diff --git a/include/linux/sched.h b/include/linux/sched.h index 0e92ee6464e5..eb32de4fdda7 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -860,6 +860,9 @@ struct task_struct { int nr_cpus_allowed; const cpumask_t *cpus_ptr; cpumask_t cpus_mask; +#ifdef CONFIG_SCHED_WALT + cpumask_t cpus_requested; +#endif #ifdef CONFIG_PREEMPT_RCU int rcu_read_lock_nesting; diff --git a/init/init_task.c b/init/init_task.c index af4dc7dcf246..2ad8a7c21c77 100644 --- a/init/init_task.c +++ b/init/init_task.c @@ -73,6 +73,9 @@ struct task_struct init_task .cpus_ptr = &init_task.cpus_mask, .cpus_mask = CPU_MASK_ALL, .nr_cpus_allowed= NR_CPUS, +#ifdef CONFIG_SCHED_WALT + .cpus_requested = CPU_MASK_ALL, +#endif .mm = NULL, .active_mm = &init_mm, .restart_block = { diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c index c87ee6412b36..9ea6269fff29 100644 --- a/kernel/cgroup/cpuset.c +++ b/kernel/cgroup/cpuset.c @@ -1022,6 +1022,22 @@ void rebuild_sched_domains(void) put_online_cpus(); } +static int update_cpus_allowed(struct cpuset *cs, struct task_struct *p, + const struct cpumask *new_mask) +{ +#ifdef CONFIG_SCHED_WALT + int ret; + + if (cpumask_subset(&p->cpus_requested, cs->cpus_allowed)) { + ret = set_cpus_allowed_ptr(p, &p->cpus_requested); + if (!ret) + return ret; + } +#endif + + return set_cpus_allowed_ptr(p, new_mask); +} + /** * update_tasks_cpumask - Update the cpumasks of tasks in the cpuset. * @cs: the cpuset in which each task's cpus_allowed mask needs to be changed @@ -1037,7 +1053,7 @@ static void update_tasks_cpumask(struct cpuset *cs) css_task_iter_start(&cs->css, 0, &it); while ((task = css_task_iter_next(&it))) - set_cpus_allowed_ptr(task, cs->effective_cpus); + update_cpus_allowed(cs, task, cs->effective_cpus); css_task_iter_end(&it); } @@ -2187,7 +2203,7 @@ static void cpuset_attach(struct cgroup_taskset *tset) * can_attach beforehand should guarantee that this doesn't * fail. TODO: have a better way to handle failure here */ - WARN_ON_ONCE(set_cpus_allowed_ptr(task, cpus_attach)); + WARN_ON_ONCE(update_cpus_allowed(cs, task, cpus_attach)); cpuset_change_task_nodemask(task, &cpuset_attach_nodemask_to); cpuset_update_task_spread_flag(cs, task); diff --git a/kernel/sched/core.c b/kernel/sched/core.c index ba94863d96aa..b10f9c2300ae 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -5634,6 +5634,11 @@ again: retval = -EINVAL; } +#ifdef CONFIG_SCHED_WALT + if (!retval && !(p->flags & PF_KTHREAD)) + cpumask_and(&p->cpus_requested, in_mask, cpu_possible_mask); +#endif + out_free_new_mask: free_cpumask_var(new_mask); out_free_cpus_allowed: @@ -6780,6 +6785,9 @@ void __init sched_init_smp(void) /* Move init over to a non-isolated CPU */ if (set_cpus_allowed_ptr(current, housekeeping_cpumask(HK_FLAG_DOMAIN)) < 0) BUG(); +#ifdef CONFIG_SCHED_WALT + cpumask_copy(¤t->cpus_requested, cpu_possible_mask); +#endif sched_init_granularity(); init_sched_rt_class();