aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cpuset.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/cpuset.c')
-rw-r--r--kernel/cpuset.c93
1 files changed, 62 insertions, 31 deletions
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 7e75a41bd508..3cf2183b472d 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -537,8 +537,7 @@ update_domain_attr_tree(struct sched_domain_attr *dattr, struct cpuset *c)
537 * element of the partition (one sched domain) to be passed to 537 * element of the partition (one sched domain) to be passed to
538 * partition_sched_domains(). 538 * partition_sched_domains().
539 */ 539 */
540/* FIXME: see the FIXME in partition_sched_domains() */ 540static int generate_sched_domains(cpumask_var_t **domains,
541static int generate_sched_domains(struct cpumask **domains,
542 struct sched_domain_attr **attributes) 541 struct sched_domain_attr **attributes)
543{ 542{
544 LIST_HEAD(q); /* queue of cpusets to be scanned */ 543 LIST_HEAD(q); /* queue of cpusets to be scanned */
@@ -546,7 +545,7 @@ static int generate_sched_domains(struct cpumask **domains,
546 struct cpuset **csa; /* array of all cpuset ptrs */ 545 struct cpuset **csa; /* array of all cpuset ptrs */
547 int csn; /* how many cpuset ptrs in csa so far */ 546 int csn; /* how many cpuset ptrs in csa so far */
548 int i, j, k; /* indices for partition finding loops */ 547 int i, j, k; /* indices for partition finding loops */
549 struct cpumask *doms; /* resulting partition; i.e. sched domains */ 548 cpumask_var_t *doms; /* resulting partition; i.e. sched domains */
550 struct sched_domain_attr *dattr; /* attributes for custom domains */ 549 struct sched_domain_attr *dattr; /* attributes for custom domains */
551 int ndoms = 0; /* number of sched domains in result */ 550 int ndoms = 0; /* number of sched domains in result */
552 int nslot; /* next empty doms[] struct cpumask slot */ 551 int nslot; /* next empty doms[] struct cpumask slot */
@@ -557,7 +556,8 @@ static int generate_sched_domains(struct cpumask **domains,
557 556
558 /* Special case for the 99% of systems with one, full, sched domain */ 557 /* Special case for the 99% of systems with one, full, sched domain */
559 if (is_sched_load_balance(&top_cpuset)) { 558 if (is_sched_load_balance(&top_cpuset)) {
560 doms = kmalloc(cpumask_size(), GFP_KERNEL); 559 ndoms = 1;
560 doms = alloc_sched_domains(ndoms);
561 if (!doms) 561 if (!doms)
562 goto done; 562 goto done;
563 563
@@ -566,9 +566,8 @@ static int generate_sched_domains(struct cpumask **domains,
566 *dattr = SD_ATTR_INIT; 566 *dattr = SD_ATTR_INIT;
567 update_domain_attr_tree(dattr, &top_cpuset); 567 update_domain_attr_tree(dattr, &top_cpuset);
568 } 568 }
569 cpumask_copy(doms, top_cpuset.cpus_allowed); 569 cpumask_copy(doms[0], top_cpuset.cpus_allowed);
570 570
571 ndoms = 1;
572 goto done; 571 goto done;
573 } 572 }
574 573
@@ -636,7 +635,7 @@ restart:
636 * Now we know how many domains to create. 635 * Now we know how many domains to create.
637 * Convert <csn, csa> to <ndoms, doms> and populate cpu masks. 636 * Convert <csn, csa> to <ndoms, doms> and populate cpu masks.
638 */ 637 */
639 doms = kmalloc(ndoms * cpumask_size(), GFP_KERNEL); 638 doms = alloc_sched_domains(ndoms);
640 if (!doms) 639 if (!doms)
641 goto done; 640 goto done;
642 641
@@ -656,7 +655,7 @@ restart:
656 continue; 655 continue;
657 } 656 }
658 657
659 dp = doms + nslot; 658 dp = doms[nslot];
660 659
661 if (nslot == ndoms) { 660 if (nslot == ndoms) {
662 static int warnings = 10; 661 static int warnings = 10;
@@ -718,7 +717,7 @@ done:
718static void do_rebuild_sched_domains(struct work_struct *unused) 717static void do_rebuild_sched_domains(struct work_struct *unused)
719{ 718{
720 struct sched_domain_attr *attr; 719 struct sched_domain_attr *attr;
721 struct cpumask *doms; 720 cpumask_var_t *doms;
722 int ndoms; 721 int ndoms;
723 722
724 get_online_cpus(); 723 get_online_cpus();
@@ -1324,9 +1323,10 @@ static int fmeter_getrate(struct fmeter *fmp)
1324static cpumask_var_t cpus_attach; 1323static cpumask_var_t cpus_attach;
1325 1324
1326/* Called by cgroups to determine if a cpuset is usable; cgroup_mutex held */ 1325/* Called by cgroups to determine if a cpuset is usable; cgroup_mutex held */
1327static int cpuset_can_attach(struct cgroup_subsys *ss, 1326static int cpuset_can_attach(struct cgroup_subsys *ss, struct cgroup *cont,
1328 struct cgroup *cont, struct task_struct *tsk) 1327 struct task_struct *tsk, bool threadgroup)
1329{ 1328{
1329 int ret;
1330 struct cpuset *cs = cgroup_cs(cont); 1330 struct cpuset *cs = cgroup_cs(cont);
1331 1331
1332 if (cpumask_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed)) 1332 if (cpumask_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed))
@@ -1343,18 +1343,51 @@ static int cpuset_can_attach(struct cgroup_subsys *ss,
1343 if (tsk->flags & PF_THREAD_BOUND) 1343 if (tsk->flags & PF_THREAD_BOUND)
1344 return -EINVAL; 1344 return -EINVAL;
1345 1345
1346 return security_task_setscheduler(tsk, 0, NULL); 1346 ret = security_task_setscheduler(tsk, 0, NULL);
1347 if (ret)
1348 return ret;
1349 if (threadgroup) {
1350 struct task_struct *c;
1351
1352 rcu_read_lock();
1353 list_for_each_entry_rcu(c, &tsk->thread_group, thread_group) {
1354 ret = security_task_setscheduler(c, 0, NULL);
1355 if (ret) {
1356 rcu_read_unlock();
1357 return ret;
1358 }
1359 }
1360 rcu_read_unlock();
1361 }
1362 return 0;
1347} 1363}
1348 1364
1349static void cpuset_attach(struct cgroup_subsys *ss, 1365static void cpuset_attach_task(struct task_struct *tsk, nodemask_t *to,
1350 struct cgroup *cont, struct cgroup *oldcont, 1366 struct cpuset *cs)
1351 struct task_struct *tsk) 1367{
1368 int err;
1369 /*
1370 * can_attach beforehand should guarantee that this doesn't fail.
1371 * TODO: have a better way to handle failure here
1372 */
1373 err = set_cpus_allowed_ptr(tsk, cpus_attach);
1374 WARN_ON_ONCE(err);
1375
1376 task_lock(tsk);
1377 cpuset_change_task_nodemask(tsk, to);
1378 task_unlock(tsk);
1379 cpuset_update_task_spread_flag(cs, tsk);
1380
1381}
1382
1383static void cpuset_attach(struct cgroup_subsys *ss, struct cgroup *cont,
1384 struct cgroup *oldcont, struct task_struct *tsk,
1385 bool threadgroup)
1352{ 1386{
1353 nodemask_t from, to; 1387 nodemask_t from, to;
1354 struct mm_struct *mm; 1388 struct mm_struct *mm;
1355 struct cpuset *cs = cgroup_cs(cont); 1389 struct cpuset *cs = cgroup_cs(cont);
1356 struct cpuset *oldcs = cgroup_cs(oldcont); 1390 struct cpuset *oldcs = cgroup_cs(oldcont);
1357 int err;
1358 1391
1359 if (cs == &top_cpuset) { 1392 if (cs == &top_cpuset) {
1360 cpumask_copy(cpus_attach, cpu_possible_mask); 1393 cpumask_copy(cpus_attach, cpu_possible_mask);
@@ -1363,15 +1396,19 @@ static void cpuset_attach(struct cgroup_subsys *ss,
1363 guarantee_online_cpus(cs, cpus_attach); 1396 guarantee_online_cpus(cs, cpus_attach);
1364 guarantee_online_mems(cs, &to); 1397 guarantee_online_mems(cs, &to);
1365 } 1398 }
1366 err = set_cpus_allowed_ptr(tsk, cpus_attach);
1367 if (err)
1368 return;
1369 1399
1370 task_lock(tsk); 1400 /* do per-task migration stuff possibly for each in the threadgroup */
1371 cpuset_change_task_nodemask(tsk, &to); 1401 cpuset_attach_task(tsk, &to, cs);
1372 task_unlock(tsk); 1402 if (threadgroup) {
1373 cpuset_update_task_spread_flag(cs, tsk); 1403 struct task_struct *c;
1404 rcu_read_lock();
1405 list_for_each_entry_rcu(c, &tsk->thread_group, thread_group) {
1406 cpuset_attach_task(c, &to, cs);
1407 }
1408 rcu_read_unlock();
1409 }
1374 1410
1411 /* change mm; only needs to be done once even if threadgroup */
1375 from = oldcs->mems_allowed; 1412 from = oldcs->mems_allowed;
1376 to = cs->mems_allowed; 1413 to = cs->mems_allowed;
1377 mm = get_task_mm(tsk); 1414 mm = get_task_mm(tsk);
@@ -2014,7 +2051,7 @@ static int cpuset_track_online_cpus(struct notifier_block *unused_nb,
2014 unsigned long phase, void *unused_cpu) 2051 unsigned long phase, void *unused_cpu)
2015{ 2052{
2016 struct sched_domain_attr *attr; 2053 struct sched_domain_attr *attr;
2017 struct cpumask *doms; 2054 cpumask_var_t *doms;
2018 int ndoms; 2055 int ndoms;
2019 2056
2020 switch (phase) { 2057 switch (phase) {
@@ -2499,15 +2536,9 @@ const struct file_operations proc_cpuset_operations = {
2499}; 2536};
2500#endif /* CONFIG_PROC_PID_CPUSET */ 2537#endif /* CONFIG_PROC_PID_CPUSET */
2501 2538
2502/* Display task cpus_allowed, mems_allowed in /proc/<pid>/status file. */ 2539/* Display task mems_allowed in /proc/<pid>/status file. */
2503void cpuset_task_status_allowed(struct seq_file *m, struct task_struct *task) 2540void cpuset_task_status_allowed(struct seq_file *m, struct task_struct *task)
2504{ 2541{
2505 seq_printf(m, "Cpus_allowed:\t");
2506 seq_cpumask(m, &task->cpus_allowed);
2507 seq_printf(m, "\n");
2508 seq_printf(m, "Cpus_allowed_list:\t");
2509 seq_cpumask_list(m, &task->cpus_allowed);
2510 seq_printf(m, "\n");
2511 seq_printf(m, "Mems_allowed:\t"); 2542 seq_printf(m, "Mems_allowed:\t");
2512 seq_nodemask(m, &task->mems_allowed); 2543 seq_nodemask(m, &task->mems_allowed);
2513 seq_printf(m, "\n"); 2544 seq_printf(m, "\n");