diff options
Diffstat (limited to 'kernel/cpuset.c')
-rw-r--r-- | kernel/cpuset.c | 46 |
1 files changed, 38 insertions, 8 deletions
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 039baa4cd90c..459d601947a8 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
@@ -1037,8 +1037,8 @@ int current_cpuset_is_being_rebound(void) | |||
1037 | 1037 | ||
1038 | static int update_relax_domain_level(struct cpuset *cs, s64 val) | 1038 | static int update_relax_domain_level(struct cpuset *cs, s64 val) |
1039 | { | 1039 | { |
1040 | if ((int)val < 0) | 1040 | if (val < -1 || val >= SD_LV_MAX) |
1041 | val = -1; | 1041 | return -EINVAL; |
1042 | 1042 | ||
1043 | if (val != cs->relax_domain_level) { | 1043 | if (val != cs->relax_domain_level) { |
1044 | cs->relax_domain_level = val; | 1044 | cs->relax_domain_level = val; |
@@ -1194,6 +1194,15 @@ static int cpuset_can_attach(struct cgroup_subsys *ss, | |||
1194 | 1194 | ||
1195 | if (cpus_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed)) | 1195 | if (cpus_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed)) |
1196 | return -ENOSPC; | 1196 | return -ENOSPC; |
1197 | if (tsk->flags & PF_THREAD_BOUND) { | ||
1198 | cpumask_t mask; | ||
1199 | |||
1200 | mutex_lock(&callback_mutex); | ||
1201 | mask = cs->cpus_allowed; | ||
1202 | mutex_unlock(&callback_mutex); | ||
1203 | if (!cpus_equal(tsk->cpus_allowed, mask)) | ||
1204 | return -EINVAL; | ||
1205 | } | ||
1197 | 1206 | ||
1198 | return security_task_setscheduler(tsk, 0, NULL); | 1207 | return security_task_setscheduler(tsk, 0, NULL); |
1199 | } | 1208 | } |
@@ -1207,11 +1216,14 @@ static void cpuset_attach(struct cgroup_subsys *ss, | |||
1207 | struct mm_struct *mm; | 1216 | struct mm_struct *mm; |
1208 | struct cpuset *cs = cgroup_cs(cont); | 1217 | struct cpuset *cs = cgroup_cs(cont); |
1209 | struct cpuset *oldcs = cgroup_cs(oldcont); | 1218 | struct cpuset *oldcs = cgroup_cs(oldcont); |
1219 | int err; | ||
1210 | 1220 | ||
1211 | mutex_lock(&callback_mutex); | 1221 | mutex_lock(&callback_mutex); |
1212 | guarantee_online_cpus(cs, &cpus); | 1222 | guarantee_online_cpus(cs, &cpus); |
1213 | set_cpus_allowed_ptr(tsk, &cpus); | 1223 | err = set_cpus_allowed_ptr(tsk, &cpus); |
1214 | mutex_unlock(&callback_mutex); | 1224 | mutex_unlock(&callback_mutex); |
1225 | if (err) | ||
1226 | return; | ||
1215 | 1227 | ||
1216 | from = oldcs->mems_allowed; | 1228 | from = oldcs->mems_allowed; |
1217 | to = cs->mems_allowed; | 1229 | to = cs->mems_allowed; |
@@ -1882,7 +1894,7 @@ static void scan_for_empty_cpusets(const struct cpuset *root) | |||
1882 | * in order to minimize text size. | 1894 | * in order to minimize text size. |
1883 | */ | 1895 | */ |
1884 | 1896 | ||
1885 | static void common_cpu_mem_hotplug_unplug(void) | 1897 | static void common_cpu_mem_hotplug_unplug(int rebuild_sd) |
1886 | { | 1898 | { |
1887 | cgroup_lock(); | 1899 | cgroup_lock(); |
1888 | 1900 | ||
@@ -1890,6 +1902,13 @@ static void common_cpu_mem_hotplug_unplug(void) | |||
1890 | top_cpuset.mems_allowed = node_states[N_HIGH_MEMORY]; | 1902 | top_cpuset.mems_allowed = node_states[N_HIGH_MEMORY]; |
1891 | scan_for_empty_cpusets(&top_cpuset); | 1903 | scan_for_empty_cpusets(&top_cpuset); |
1892 | 1904 | ||
1905 | /* | ||
1906 | * Scheduler destroys domains on hotplug events. | ||
1907 | * Rebuild them based on the current settings. | ||
1908 | */ | ||
1909 | if (rebuild_sd) | ||
1910 | rebuild_sched_domains(); | ||
1911 | |||
1893 | cgroup_unlock(); | 1912 | cgroup_unlock(); |
1894 | } | 1913 | } |
1895 | 1914 | ||
@@ -1906,11 +1925,22 @@ static void common_cpu_mem_hotplug_unplug(void) | |||
1906 | static int cpuset_handle_cpuhp(struct notifier_block *unused_nb, | 1925 | static int cpuset_handle_cpuhp(struct notifier_block *unused_nb, |
1907 | unsigned long phase, void *unused_cpu) | 1926 | unsigned long phase, void *unused_cpu) |
1908 | { | 1927 | { |
1909 | if (phase == CPU_DYING || phase == CPU_DYING_FROZEN) | 1928 | switch (phase) { |
1929 | case CPU_UP_CANCELED: | ||
1930 | case CPU_UP_CANCELED_FROZEN: | ||
1931 | case CPU_DOWN_FAILED: | ||
1932 | case CPU_DOWN_FAILED_FROZEN: | ||
1933 | case CPU_ONLINE: | ||
1934 | case CPU_ONLINE_FROZEN: | ||
1935 | case CPU_DEAD: | ||
1936 | case CPU_DEAD_FROZEN: | ||
1937 | common_cpu_mem_hotplug_unplug(1); | ||
1938 | break; | ||
1939 | default: | ||
1910 | return NOTIFY_DONE; | 1940 | return NOTIFY_DONE; |
1941 | } | ||
1911 | 1942 | ||
1912 | common_cpu_mem_hotplug_unplug(); | 1943 | return NOTIFY_OK; |
1913 | return 0; | ||
1914 | } | 1944 | } |
1915 | 1945 | ||
1916 | #ifdef CONFIG_MEMORY_HOTPLUG | 1946 | #ifdef CONFIG_MEMORY_HOTPLUG |
@@ -1923,7 +1953,7 @@ static int cpuset_handle_cpuhp(struct notifier_block *unused_nb, | |||
1923 | 1953 | ||
1924 | void cpuset_track_online_nodes(void) | 1954 | void cpuset_track_online_nodes(void) |
1925 | { | 1955 | { |
1926 | common_cpu_mem_hotplug_unplug(); | 1956 | common_cpu_mem_hotplug_unplug(0); |
1927 | } | 1957 | } |
1928 | #endif | 1958 | #endif |
1929 | 1959 | ||