Loading kernel/cpuset.c +16 −53 Original line number Original line Diff line number Diff line Loading @@ -101,8 +101,6 @@ struct cpuset { /* for custom sched domain */ /* for custom sched domain */ int relax_domain_level; int relax_domain_level; struct work_struct hotplug_work; }; }; /* Retrieve the cpuset for a cgroup */ /* Retrieve the cpuset for a cgroup */ Loading Loading @@ -268,12 +266,7 @@ static DEFINE_MUTEX(callback_mutex); /* /* * CPU / memory hotplug is handled asynchronously. * 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_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_WORK(cpuset_hotplug_work, cpuset_hotplug_workfn); static DECLARE_WAIT_QUEUE_HEAD(cpuset_attach_wq); 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. * after execution capability is restored. */ */ flush_work(&cpuset_hotplug_work); flush_work(&cpuset_hotplug_work); flush_workqueue(cpuset_propagate_hotplug_wq); mutex_lock(&cpuset_mutex); mutex_lock(&cpuset_mutex); if (!is_cpuset_online(cs)) 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); cpumask_clear(cs->cpus_allowed); nodes_clear(cs->mems_allowed); nodes_clear(cs->mems_allowed); fmeter_init(&cs->fmeter); fmeter_init(&cs->fmeter); INIT_WORK(&cs->hotplug_work, cpuset_propagate_hotplug_workfn); cs->relax_domain_level = -1; cs->relax_domain_level = -1; return &cs->css; 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 * @cs: cpuset in interest * * * Compare @cs's cpu and mem masks against top_cpuset and if some have gone * 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, * 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. * 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 cpumask_t off_cpus; static nodemask_t off_mems, tmp_mems; static nodemask_t off_mems, tmp_mems; struct cpuset *cs = container_of(work, struct cpuset, hotplug_work); bool is_empty; bool is_empty; retry: retry: Loading Loading @@ -2044,34 +2034,6 @@ static void cpuset_propagate_hotplug_workfn(struct work_struct *work) */ */ if (is_empty) if (is_empty) remove_tasks_in_empty_cpuset(cs); 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. * actively using CPU hotplug but making no active use of cpusets. * * * Non-root cpusets are only affected by offlining. If any CPUs or memory * 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 * nodes have been taken down, cpuset_hotplug_update_tasks() is invoked on * descendants. * all descendants. * * * Note that CPU offlining during suspend is ignored. We don't modify * Note that CPU offlining during suspend is ignored. We don't modify * cpusets across suspend/resume cycles at all. * 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); 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 or mems went down, we need to propagate to descendants */ if (cpus_offlined || mems_offlined) { if (cpus_offlined || mems_offlined) { struct cpuset *cs; struct cpuset *cs; struct cgroup *pos_cgrp; struct cgroup *pos_cgrp; rcu_read_lock(); rcu_read_lock(); cpuset_for_each_descendant_pre(cs, pos_cgrp, &top_cpuset) cpuset_for_each_descendant_pre(cs, pos_cgrp, &top_cpuset) { schedule_cpuset_propagate_hotplug(cs); if (!css_tryget(&cs->css)) continue; rcu_read_unlock(); rcu_read_unlock(); } mutex_unlock(&cpuset_mutex); cpuset_hotplug_update_tasks(cs); /* wait for propagations to finish */ rcu_read_lock(); flush_workqueue(cpuset_propagate_hotplug_wq); css_put(&cs->css); } rcu_read_unlock(); } /* rebuild sched domains if cpus_allowed has changed */ /* rebuild sched domains if cpus_allowed has changed */ if (cpus_updated) if (cpus_updated) Loading Loading @@ -2193,10 +2160,6 @@ void __init cpuset_init_smp(void) top_cpuset.mems_allowed = node_states[N_MEMORY]; top_cpuset.mems_allowed = node_states[N_MEMORY]; register_hotmemory_notifier(&cpuset_track_online_nodes_nb); 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 Original line Diff line number Diff line Loading @@ -101,8 +101,6 @@ struct cpuset { /* for custom sched domain */ /* for custom sched domain */ int relax_domain_level; int relax_domain_level; struct work_struct hotplug_work; }; }; /* Retrieve the cpuset for a cgroup */ /* Retrieve the cpuset for a cgroup */ Loading Loading @@ -268,12 +266,7 @@ static DEFINE_MUTEX(callback_mutex); /* /* * CPU / memory hotplug is handled asynchronously. * 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_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_WORK(cpuset_hotplug_work, cpuset_hotplug_workfn); static DECLARE_WAIT_QUEUE_HEAD(cpuset_attach_wq); 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. * after execution capability is restored. */ */ flush_work(&cpuset_hotplug_work); flush_work(&cpuset_hotplug_work); flush_workqueue(cpuset_propagate_hotplug_wq); mutex_lock(&cpuset_mutex); mutex_lock(&cpuset_mutex); if (!is_cpuset_online(cs)) 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); cpumask_clear(cs->cpus_allowed); nodes_clear(cs->mems_allowed); nodes_clear(cs->mems_allowed); fmeter_init(&cs->fmeter); fmeter_init(&cs->fmeter); INIT_WORK(&cs->hotplug_work, cpuset_propagate_hotplug_workfn); cs->relax_domain_level = -1; cs->relax_domain_level = -1; return &cs->css; 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 * @cs: cpuset in interest * * * Compare @cs's cpu and mem masks against top_cpuset and if some have gone * 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, * 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. * 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 cpumask_t off_cpus; static nodemask_t off_mems, tmp_mems; static nodemask_t off_mems, tmp_mems; struct cpuset *cs = container_of(work, struct cpuset, hotplug_work); bool is_empty; bool is_empty; retry: retry: Loading Loading @@ -2044,34 +2034,6 @@ static void cpuset_propagate_hotplug_workfn(struct work_struct *work) */ */ if (is_empty) if (is_empty) remove_tasks_in_empty_cpuset(cs); 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. * actively using CPU hotplug but making no active use of cpusets. * * * Non-root cpusets are only affected by offlining. If any CPUs or memory * 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 * nodes have been taken down, cpuset_hotplug_update_tasks() is invoked on * descendants. * all descendants. * * * Note that CPU offlining during suspend is ignored. We don't modify * Note that CPU offlining during suspend is ignored. We don't modify * cpusets across suspend/resume cycles at all. * 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); 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 or mems went down, we need to propagate to descendants */ if (cpus_offlined || mems_offlined) { if (cpus_offlined || mems_offlined) { struct cpuset *cs; struct cpuset *cs; struct cgroup *pos_cgrp; struct cgroup *pos_cgrp; rcu_read_lock(); rcu_read_lock(); cpuset_for_each_descendant_pre(cs, pos_cgrp, &top_cpuset) cpuset_for_each_descendant_pre(cs, pos_cgrp, &top_cpuset) { schedule_cpuset_propagate_hotplug(cs); if (!css_tryget(&cs->css)) continue; rcu_read_unlock(); rcu_read_unlock(); } mutex_unlock(&cpuset_mutex); cpuset_hotplug_update_tasks(cs); /* wait for propagations to finish */ rcu_read_lock(); flush_workqueue(cpuset_propagate_hotplug_wq); css_put(&cs->css); } rcu_read_unlock(); } /* rebuild sched domains if cpus_allowed has changed */ /* rebuild sched domains if cpus_allowed has changed */ if (cpus_updated) if (cpus_updated) Loading Loading @@ -2193,10 +2160,6 @@ void __init cpuset_init_smp(void) top_cpuset.mems_allowed = node_states[N_MEMORY]; top_cpuset.mems_allowed = node_states[N_MEMORY]; register_hotmemory_notifier(&cpuset_track_online_nodes_nb); 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