Loading kernel/cpuset.c +16 −53 Original line number Diff line number Diff line Loading @@ -101,8 +101,6 @@ struct cpuset { /* for custom sched domain */ int relax_domain_level; struct work_struct hotplug_work; }; /* Retrieve the cpuset for a cgroup */ Loading Loading @@ -268,12 +266,7 @@ static DEFINE_MUTEX(callback_mutex); /* * CPU / memory hotplug is handled asynchronously. */ static struct workqueue_struct *cpuset_propagate_hotplug_wq; static void cpuset_hotplug_workfn(struct work_struct *work); static void cpuset_propagate_hotplug_workfn(struct work_struct *work); static void schedule_cpuset_propagate_hotplug(struct cpuset *cs); static DECLARE_WORK(cpuset_hotplug_work, cpuset_hotplug_workfn); static DECLARE_WAIT_QUEUE_HEAD(cpuset_attach_wq); Loading Loading @@ -1554,7 +1547,6 @@ static int cpuset_write_resmask(struct cgroup *cgrp, struct cftype *cft, * after execution capability is restored. */ flush_work(&cpuset_hotplug_work); flush_workqueue(cpuset_propagate_hotplug_wq); mutex_lock(&cpuset_mutex); if (!is_cpuset_online(cs)) Loading Loading @@ -1821,7 +1813,6 @@ static struct cgroup_subsys_state *cpuset_css_alloc(struct cgroup *cont) cpumask_clear(cs->cpus_allowed); nodes_clear(cs->mems_allowed); fmeter_init(&cs->fmeter); INIT_WORK(&cs->hotplug_work, cpuset_propagate_hotplug_workfn); cs->relax_domain_level = -1; return &cs->css; Loading Loading @@ -1984,18 +1975,17 @@ static void remove_tasks_in_empty_cpuset(struct cpuset *cs) } /** * cpuset_propagate_hotplug_workfn - propagate CPU/memory hotplug to a cpuset * cpuset_hotplug_update_tasks - update tasks in a cpuset for hotunplug * @cs: cpuset in interest * * Compare @cs's cpu and mem masks against top_cpuset and if some have gone * offline, update @cs accordingly. If @cs ends up with no CPU or memory, * all its tasks are moved to the nearest ancestor with both resources. */ static void cpuset_propagate_hotplug_workfn(struct work_struct *work) static void cpuset_hotplug_update_tasks(struct cpuset *cs) { static cpumask_t off_cpus; static nodemask_t off_mems, tmp_mems; struct cpuset *cs = container_of(work, struct cpuset, hotplug_work); bool is_empty; retry: Loading Loading @@ -2044,34 +2034,6 @@ static void cpuset_propagate_hotplug_workfn(struct work_struct *work) */ if (is_empty) remove_tasks_in_empty_cpuset(cs); /* the following may free @cs, should be the last operation */ css_put(&cs->css); } /** * schedule_cpuset_propagate_hotplug - schedule hotplug propagation to a cpuset * @cs: cpuset of interest * * Schedule cpuset_propagate_hotplug_workfn() which will update CPU and * memory masks according to top_cpuset. */ static void schedule_cpuset_propagate_hotplug(struct cpuset *cs) { /* * Pin @cs. The refcnt will be released when the work item * finishes executing. */ if (!css_tryget(&cs->css)) return; /* * Queue @cs->hotplug_work. If already pending, lose the css ref. * cpuset_propagate_hotplug_wq is ordered and propagation will * happen in the order this function is called. */ if (!queue_work(cpuset_propagate_hotplug_wq, &cs->hotplug_work)) css_put(&cs->css); } /** Loading @@ -2084,8 +2046,8 @@ static void schedule_cpuset_propagate_hotplug(struct cpuset *cs) * actively using CPU hotplug but making no active use of cpusets. * * Non-root cpusets are only affected by offlining. If any CPUs or memory * nodes have been taken down, cpuset_propagate_hotplug() is invoked on all * descendants. * nodes have been taken down, cpuset_hotplug_update_tasks() is invoked on * all descendants. * * Note that CPU offlining during suspend is ignored. We don't modify * cpusets across suspend/resume cycles at all. Loading Loading @@ -2128,21 +2090,26 @@ static void cpuset_hotplug_workfn(struct work_struct *work) update_tasks_nodemask(&top_cpuset, &tmp_mems, NULL); } mutex_unlock(&cpuset_mutex); /* if cpus or mems went down, we need to propagate to descendants */ if (cpus_offlined || mems_offlined) { struct cpuset *cs; struct cgroup *pos_cgrp; rcu_read_lock(); cpuset_for_each_descendant_pre(cs, pos_cgrp, &top_cpuset) schedule_cpuset_propagate_hotplug(cs); cpuset_for_each_descendant_pre(cs, pos_cgrp, &top_cpuset) { if (!css_tryget(&cs->css)) continue; rcu_read_unlock(); } mutex_unlock(&cpuset_mutex); cpuset_hotplug_update_tasks(cs); /* wait for propagations to finish */ flush_workqueue(cpuset_propagate_hotplug_wq); rcu_read_lock(); css_put(&cs->css); } rcu_read_unlock(); } /* rebuild sched domains if cpus_allowed has changed */ if (cpus_updated) Loading Loading @@ -2193,10 +2160,6 @@ void __init cpuset_init_smp(void) top_cpuset.mems_allowed = node_states[N_MEMORY]; register_hotmemory_notifier(&cpuset_track_online_nodes_nb); cpuset_propagate_hotplug_wq = alloc_ordered_workqueue("cpuset_hotplug", 0); BUG_ON(!cpuset_propagate_hotplug_wq); } /** Loading Loading
kernel/cpuset.c +16 −53 Original line number Diff line number Diff line Loading @@ -101,8 +101,6 @@ struct cpuset { /* for custom sched domain */ int relax_domain_level; struct work_struct hotplug_work; }; /* Retrieve the cpuset for a cgroup */ Loading Loading @@ -268,12 +266,7 @@ static DEFINE_MUTEX(callback_mutex); /* * CPU / memory hotplug is handled asynchronously. */ static struct workqueue_struct *cpuset_propagate_hotplug_wq; static void cpuset_hotplug_workfn(struct work_struct *work); static void cpuset_propagate_hotplug_workfn(struct work_struct *work); static void schedule_cpuset_propagate_hotplug(struct cpuset *cs); static DECLARE_WORK(cpuset_hotplug_work, cpuset_hotplug_workfn); static DECLARE_WAIT_QUEUE_HEAD(cpuset_attach_wq); Loading Loading @@ -1554,7 +1547,6 @@ static int cpuset_write_resmask(struct cgroup *cgrp, struct cftype *cft, * after execution capability is restored. */ flush_work(&cpuset_hotplug_work); flush_workqueue(cpuset_propagate_hotplug_wq); mutex_lock(&cpuset_mutex); if (!is_cpuset_online(cs)) Loading Loading @@ -1821,7 +1813,6 @@ static struct cgroup_subsys_state *cpuset_css_alloc(struct cgroup *cont) cpumask_clear(cs->cpus_allowed); nodes_clear(cs->mems_allowed); fmeter_init(&cs->fmeter); INIT_WORK(&cs->hotplug_work, cpuset_propagate_hotplug_workfn); cs->relax_domain_level = -1; return &cs->css; Loading Loading @@ -1984,18 +1975,17 @@ static void remove_tasks_in_empty_cpuset(struct cpuset *cs) } /** * cpuset_propagate_hotplug_workfn - propagate CPU/memory hotplug to a cpuset * cpuset_hotplug_update_tasks - update tasks in a cpuset for hotunplug * @cs: cpuset in interest * * Compare @cs's cpu and mem masks against top_cpuset and if some have gone * offline, update @cs accordingly. If @cs ends up with no CPU or memory, * all its tasks are moved to the nearest ancestor with both resources. */ static void cpuset_propagate_hotplug_workfn(struct work_struct *work) static void cpuset_hotplug_update_tasks(struct cpuset *cs) { static cpumask_t off_cpus; static nodemask_t off_mems, tmp_mems; struct cpuset *cs = container_of(work, struct cpuset, hotplug_work); bool is_empty; retry: Loading Loading @@ -2044,34 +2034,6 @@ static void cpuset_propagate_hotplug_workfn(struct work_struct *work) */ if (is_empty) remove_tasks_in_empty_cpuset(cs); /* the following may free @cs, should be the last operation */ css_put(&cs->css); } /** * schedule_cpuset_propagate_hotplug - schedule hotplug propagation to a cpuset * @cs: cpuset of interest * * Schedule cpuset_propagate_hotplug_workfn() which will update CPU and * memory masks according to top_cpuset. */ static void schedule_cpuset_propagate_hotplug(struct cpuset *cs) { /* * Pin @cs. The refcnt will be released when the work item * finishes executing. */ if (!css_tryget(&cs->css)) return; /* * Queue @cs->hotplug_work. If already pending, lose the css ref. * cpuset_propagate_hotplug_wq is ordered and propagation will * happen in the order this function is called. */ if (!queue_work(cpuset_propagate_hotplug_wq, &cs->hotplug_work)) css_put(&cs->css); } /** Loading @@ -2084,8 +2046,8 @@ static void schedule_cpuset_propagate_hotplug(struct cpuset *cs) * actively using CPU hotplug but making no active use of cpusets. * * Non-root cpusets are only affected by offlining. If any CPUs or memory * nodes have been taken down, cpuset_propagate_hotplug() is invoked on all * descendants. * nodes have been taken down, cpuset_hotplug_update_tasks() is invoked on * all descendants. * * Note that CPU offlining during suspend is ignored. We don't modify * cpusets across suspend/resume cycles at all. Loading Loading @@ -2128,21 +2090,26 @@ static void cpuset_hotplug_workfn(struct work_struct *work) update_tasks_nodemask(&top_cpuset, &tmp_mems, NULL); } mutex_unlock(&cpuset_mutex); /* if cpus or mems went down, we need to propagate to descendants */ if (cpus_offlined || mems_offlined) { struct cpuset *cs; struct cgroup *pos_cgrp; rcu_read_lock(); cpuset_for_each_descendant_pre(cs, pos_cgrp, &top_cpuset) schedule_cpuset_propagate_hotplug(cs); cpuset_for_each_descendant_pre(cs, pos_cgrp, &top_cpuset) { if (!css_tryget(&cs->css)) continue; rcu_read_unlock(); } mutex_unlock(&cpuset_mutex); cpuset_hotplug_update_tasks(cs); /* wait for propagations to finish */ flush_workqueue(cpuset_propagate_hotplug_wq); rcu_read_lock(); css_put(&cs->css); } rcu_read_unlock(); } /* rebuild sched domains if cpus_allowed has changed */ if (cpus_updated) Loading Loading @@ -2193,10 +2160,6 @@ void __init cpuset_init_smp(void) top_cpuset.mems_allowed = node_states[N_MEMORY]; register_hotmemory_notifier(&cpuset_track_online_nodes_nb); cpuset_propagate_hotplug_wq = alloc_ordered_workqueue("cpuset_hotplug", 0); BUG_ON(!cpuset_propagate_hotplug_wq); } /** Loading