ipmr/ip6mr: Initialize the last assert time of mfc entries.
[pandora-kernel.git] / kernel / cpuset.c
index 9fe58c4..4346f9a 100644 (file)
@@ -123,6 +123,19 @@ static inline struct cpuset *task_cs(struct task_struct *task)
                            struct cpuset, css);
 }
 
+#ifdef CONFIG_NUMA
+static inline bool task_has_mempolicy(struct task_struct *task)
+{
+       return task->mempolicy;
+}
+#else
+static inline bool task_has_mempolicy(struct task_struct *task)
+{
+       return false;
+}
+#endif
+
+
 /* bits in struct cpuset flags field */
 typedef enum {
        CS_CPU_EXCLUSIVE,
@@ -949,9 +962,8 @@ static void cpuset_migrate_mm(struct mm_struct *mm, const nodemask_t *from,
 static void cpuset_change_task_nodemask(struct task_struct *tsk,
                                        nodemask_t *newmems)
 {
-       bool masks_disjoint = !nodes_intersects(*newmems, tsk->mems_allowed);
+       bool need_loop;
 
-repeat:
        /*
         * Allow tasks that have access to memory reserves because they have
         * been OOM killed to get memory anywhere.
@@ -962,47 +974,31 @@ repeat:
                return;
 
        task_lock(tsk);
-       nodes_or(tsk->mems_allowed, tsk->mems_allowed, *newmems);
-       mpol_rebind_task(tsk, newmems, MPOL_REBIND_STEP1);
-
        /*
-        * ensure checking ->mems_allowed_change_disable after setting all new
-        * allowed nodes.
-        *
-        * the read-side task can see an nodemask with new allowed nodes and
-        * old allowed nodes. and if it allocates page when cpuset clears newly
-        * disallowed ones continuous, it can see the new allowed bits.
-        *
-        * And if setting all new allowed nodes is after the checking, setting
-        * all new allowed nodes and clearing newly disallowed ones will be done
-        * continuous, and the read-side task may find no node to alloc page.
+        * Determine if a loop is necessary if another thread is doing
+        * get_mems_allowed().  If at least one node remains unchanged and
+        * tsk does not have a mempolicy, then an empty nodemask will not be
+        * possible when mems_allowed is larger than a word.
         */
-       smp_mb();
+       need_loop = task_has_mempolicy(tsk) ||
+                       !nodes_intersects(*newmems, tsk->mems_allowed);
 
-       /*
-        * Allocation of memory is very fast, we needn't sleep when waiting
-        * for the read-side.  No wait is necessary, however, if at least one
-        * node remains unchanged.
-        */
-       while (masks_disjoint &&
-                       ACCESS_ONCE(tsk->mems_allowed_change_disable)) {
-               task_unlock(tsk);
-               if (!task_curr(tsk))
-                       yield();
-               goto repeat;
+       if (need_loop) {
+               local_irq_disable();
+               write_seqcount_begin(&tsk->mems_allowed_seq);
        }
 
-       /*
-        * ensure checking ->mems_allowed_change_disable before clearing all new
-        * disallowed nodes.
-        *
-        * if clearing newly disallowed bits before the checking, the read-side
-        * task may find no node to alloc page.
-        */
-       smp_mb();
+       nodes_or(tsk->mems_allowed, tsk->mems_allowed, *newmems);
+       mpol_rebind_task(tsk, newmems, MPOL_REBIND_STEP1);
 
        mpol_rebind_task(tsk, newmems, MPOL_REBIND_STEP2);
        tsk->mems_allowed = *newmems;
+
+       if (need_loop) {
+               write_seqcount_end(&tsk->mems_allowed_seq);
+               local_irq_enable();
+       }
+
        task_unlock(tsk);
 }
 
@@ -1156,7 +1152,13 @@ done:
 
 int current_cpuset_is_being_rebound(void)
 {
-       return task_cs(current) == cpuset_being_rebound;
+       int ret;
+
+       rcu_read_lock();
+       ret = task_cs(current) == cpuset_being_rebound;
+       rcu_read_unlock();
+
+       return ret;
 }
 
 static int update_relax_domain_level(struct cpuset *cs, s64 val)
@@ -2088,6 +2090,9 @@ static void scan_for_empty_cpusets(struct cpuset *root)
  * (of no affect) on systems that are actively using CPU hotplug
  * but making no active use of cpusets.
  *
+ * The only exception to this is suspend/resume, where we don't
+ * modify cpusets at all.
+ *
  * This routine ensures that top_cpuset.cpus_allowed tracks
  * cpu_active_mask on each CPU hotplug (cpuhp) event.
  *
@@ -2367,9 +2372,9 @@ int __cpuset_node_allowed_softwall(int node, gfp_t gfp_mask)
 
        task_lock(current);
        cs = nearest_hardwall_ancestor(task_cs(current));
+       allowed = node_isset(node, cs->mems_allowed);
        task_unlock(current);
 
-       allowed = node_isset(node, cs->mems_allowed);
        mutex_unlock(&callback_mutex);
        return allowed;
 }
@@ -2512,8 +2517,16 @@ void cpuset_print_task_mems_allowed(struct task_struct *tsk)
 
        dentry = task_cs(tsk)->css.cgroup->dentry;
        spin_lock(&cpuset_buffer_lock);
-       snprintf(cpuset_name, CPUSET_NAME_LEN,
-                dentry ? (const char *)dentry->d_name.name : "/");
+
+       if (!dentry) {
+               strcpy(cpuset_name, "/");
+       } else {
+               spin_lock(&dentry->d_lock);
+               strlcpy(cpuset_name, (const char *)dentry->d_name.name,
+                       CPUSET_NAME_LEN);
+               spin_unlock(&dentry->d_lock);
+       }
+
        nodelist_scnprintf(cpuset_nodelist, CPUSET_NODELIST_LEN,
                           tsk->mems_allowed);
        printk(KERN_INFO "%s cpuset=%s mems_allowed=%s\n",