aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2008-07-25 04:47:22 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-25 13:53:38 -0400
commitf9b4fb8dabf38fb456c97f01aace07cb6e7c1723 (patch)
tree07fbf909044858d6c50b4098f94c8f084df3924c
parent0b2f630a28d53b5a2082a5275bc3334b10373508 (diff)
cpusets: update task's cpus_allowed and mems_allowed after CPU/NODE offline/online
The bug is that a task may run on the cpu/node which is not in its cpuset.cpus/ cpuset.mems. It can be reproduced by the following commands: ----------------------------------- # mkdir /dev/cpuset # mount -t cpuset xxx /dev/cpuset # mkdir /dev/cpuset/0 # echo 0-1 > /dev/cpuset/0/cpus # echo 0 > /dev/cpuset/0/mems # echo $$ > /dev/cpuset/0/tasks # echo 0 > /sys/devices/system/cpu/cpu1/online # echo 1 > /sys/devices/system/cpu/cpu1/online ----------------------------------- There is only CPU0 in cpuset.cpus, but the task in this cpuset runs on both CPU0 and CPU1. It is because the task's cpu_allowed didn't get updated after we did CPU offline/online manipulation. Similar for mem_allowed. This patch fixes this bug expect for root cpuset. Because there is a problem about root cpuset, in that whether it is necessary to update all the tasks in root cpuset or not after cpu/node offline/online. If updating, some kernel threads which is bound into a specified cpu will be unbound. If not updating, there is a bug in root cpuset. This bug is also caused by offline/online manipulation. For example, there is a dual-cpu machine. we create a sub cpuset in root cpuset and assign 1 to its cpus. And then we attach some tasks into this sub cpuset. After this, we offline CPU1. Now, the tasks in this new cpuset are moved into root cpuset automatically because there is no cpu in sub cpuset. Then we online CPU1, we find all the tasks which doesn't belong to root cpuset originally just run on CPU0. Maybe we need to add a flag in the task_struct to mark which task can't be unbound? Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Acked-by: Paul Jackson <pj@sgi.com> Cc: Li Zefan <lizf@cn.fujitsu.com> Cc: Paul Jackson <pj@sgi.com> Cc: Paul Menage <menage@google.com> Cc: David Rientjes <rientjes@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--kernel/cpuset.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 7326d51eefe1..6eae6639e851 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -1851,6 +1851,7 @@ static void scan_for_empty_cpusets(const struct cpuset *root)
1851 struct cpuset *child; /* scans child cpusets of cp */ 1851 struct cpuset *child; /* scans child cpusets of cp */
1852 struct list_head queue; 1852 struct list_head queue;
1853 struct cgroup *cont; 1853 struct cgroup *cont;
1854 nodemask_t oldmems;
1854 1855
1855 INIT_LIST_HEAD(&queue); 1856 INIT_LIST_HEAD(&queue);
1856 1857
@@ -1870,6 +1871,8 @@ static void scan_for_empty_cpusets(const struct cpuset *root)
1870 nodes_subset(cp->mems_allowed, node_states[N_HIGH_MEMORY])) 1871 nodes_subset(cp->mems_allowed, node_states[N_HIGH_MEMORY]))
1871 continue; 1872 continue;
1872 1873
1874 oldmems = cp->mems_allowed;
1875
1873 /* Remove offline cpus and mems from this cpuset. */ 1876 /* Remove offline cpus and mems from this cpuset. */
1874 mutex_lock(&callback_mutex); 1877 mutex_lock(&callback_mutex);
1875 cpus_and(cp->cpus_allowed, cp->cpus_allowed, cpu_online_map); 1878 cpus_and(cp->cpus_allowed, cp->cpus_allowed, cpu_online_map);
@@ -1881,6 +1884,10 @@ static void scan_for_empty_cpusets(const struct cpuset *root)
1881 if (cpus_empty(cp->cpus_allowed) || 1884 if (cpus_empty(cp->cpus_allowed) ||
1882 nodes_empty(cp->mems_allowed)) 1885 nodes_empty(cp->mems_allowed))
1883 remove_tasks_in_empty_cpuset(cp); 1886 remove_tasks_in_empty_cpuset(cp);
1887 else {
1888 update_tasks_cpumask(cp);
1889 update_tasks_nodemask(cp, &oldmems);
1890 }
1884 } 1891 }
1885} 1892}
1886 1893