From: Paul Jackson Apply a couple of simplications to the cpuset_mems_generation mechanism used to trigger a task into updating its mems_allowed when its cpuset memory placement changes: 1) Didn't need tasklock, since only dealing with current task, and no one else is going to nuke current->cpuset out from under us. 2) Instead of dropping the cpuset semaphore cpuset_sem, and then jumping through flaming write-memory-barrier hoops to ensure that we didn't get an out of order generation number, rather pick off the current cpusets generation number while we have the cpuset locked anyway getting its nodemask. The combination of the above allowed several fussy lines of code to go poof into thin air. Signed-off-by: Paul Jackson Signed-off-by: Andrew Morton --- 25-akpm/include/linux/cpuset.h | 6 ----- 25-akpm/kernel/cpuset.c | 48 ++++++++--------------------------------- 2 files changed, 10 insertions(+), 44 deletions(-) diff -puN include/linux/cpuset.h~cpusets-simplify-memory-generation include/linux/cpuset.h --- 25/include/linux/cpuset.h~cpusets-simplify-memory-generation Fri Sep 17 16:45:41 2004 +++ 25-akpm/include/linux/cpuset.h Fri Sep 17 16:45:41 2004 @@ -19,7 +19,6 @@ extern void cpuset_init_smp(void); extern void cpuset_fork(struct task_struct *p); extern void cpuset_exit(struct task_struct *p); extern const cpumask_t cpuset_cpus_allowed(const struct task_struct *p); -extern const nodemask_t cpuset_mems_allowed(const struct task_struct *p); void cpuset_init_current_mems_allowed(void); void cpuset_update_current_mems_allowed(void); void cpuset_restrict_to_mems_allowed(unsigned long *nodes); @@ -40,11 +39,6 @@ static inline const cpumask_t cpuset_cpu return cpu_possible_map; } -static inline const nodemask_t cpuset_mems_allowed(struct task_struct *p) -{ - return node_possible_map; -} - static inline void cpuset_init_current_mems_allowed(void) {} static inline void cpuset_update_current_mems_allowed(void) {} static inline void cpuset_restrict_to_mems_allowed(unsigned long *nodes) {} diff -puN kernel/cpuset.c~cpusets-simplify-memory-generation kernel/cpuset.c --- 25/kernel/cpuset.c~cpusets-simplify-memory-generation Fri Sep 17 16:45:41 2004 +++ 25-akpm/kernel/cpuset.c Fri Sep 17 16:45:41 2004 @@ -555,7 +555,6 @@ static int update_nodemask(struct cpuset if (retval == 0) { cs->mems_allowed = trialcs.mems_allowed; atomic_inc(&cpuset_mems_generation); - wmb(); /* insure above mems_allowed seen before next line */ cs->mems_generation = atomic_read(&cpuset_mems_generation); } return retval; @@ -1199,7 +1198,6 @@ static long cpuset_create(struct cpuset INIT_LIST_HEAD(&cs->sibling); INIT_LIST_HEAD(&cs->children); atomic_inc(&cpuset_mems_generation); - wmb(); /* insure above mems_allowed seen before next line */ cs->mems_generation = atomic_read(&cpuset_mems_generation); cs->parent = parent; @@ -1379,53 +1377,27 @@ const cpumask_t cpuset_cpus_allowed(cons return mask; } -/** - * cpuset_mems_allowed - return mems_allowed mask from a tasks cpuset. - * @tsk: pointer to task_struct from which to obtain cpuset->mems_allowed. - * - * Description: Returns the nodemask_t mems_allowed of the cpuset - * attached to the specified @tsk. - **/ - -const nodemask_t cpuset_mems_allowed(const struct task_struct *tsk) -{ - nodemask_t mask; - - down(&cpuset_sem); - task_lock((struct task_struct *)tsk); - if (tsk->cpuset) - mask = tsk->cpuset->mems_allowed; - else - mask = NODE_MASK_ALL; - task_unlock((struct task_struct *)tsk); - up(&cpuset_sem); - - return mask; -} - void cpuset_init_current_mems_allowed(void) { current->mems_allowed = NODE_MASK_ALL; } /* - * If the current tasks cpusets mems_allowed changes behind our backs, - * update current->mems_allowed to the new value. While loop for rare - * race with concurrent cpuset changes. Must insure that we never see - * the next generation number with an old mems_allowed, in order to - * avoid having stale mems_allowed w/o knowing it. See also the wmb() - * calls above. Do not call this routine if in_interrupt(). + * If the current tasks cpusets mems_allowed changed behind our backs, + * update current->mems_allowed and mems_generation to the new value. + * Do not call this routine if in_interrupt(). */ void cpuset_update_current_mems_allowed() { - int g; + struct cpuset *cs = current->cpuset; - if (!current->cpuset) + if (!cs) return; /* task is exiting */ - while ((g = current->cpuset->mems_generation) != - current->cpuset_mems_generation) { - current->mems_allowed = cpuset_mems_allowed(current); - current->cpuset_mems_generation = g; + if (current->cpuset_mems_generation != cs->mems_generation) { + down(&cpuset_sem); + current->mems_allowed = cs->mems_allowed; + current->cpuset_mems_generation = cs->mems_generation; + up(&cpuset_sem); } } _