Commit bdfbbda9 authored by Tejun Heo's avatar Tejun Heo

Revert "cgroup/cpuset: remove circular dependency deadlock"

This reverts commit aa24163b.

This and the following commit led to another circular locking scenario
and the scenario which is fixed by this commit no longer exists after
e8b3f8db ("workqueue/hotplug: simplify workqueue_offline_cpu()")
which removes work item flushing from hotplug path.

Revert it for now.
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
parent 11db855c
...@@ -812,18 +812,6 @@ static int generate_sched_domains(cpumask_var_t **domains, ...@@ -812,18 +812,6 @@ static int generate_sched_domains(cpumask_var_t **domains,
return ndoms; return ndoms;
} }
static void cpuset_sched_change_begin(void)
{
cpus_read_lock();
mutex_lock(&cpuset_mutex);
}
static void cpuset_sched_change_end(void)
{
mutex_unlock(&cpuset_mutex);
cpus_read_unlock();
}
/* /*
* Rebuild scheduler domains. * Rebuild scheduler domains.
* *
...@@ -833,14 +821,16 @@ static void cpuset_sched_change_end(void) ...@@ -833,14 +821,16 @@ static void cpuset_sched_change_end(void)
* 'cpus' is removed, then call this routine to rebuild the * 'cpus' is removed, then call this routine to rebuild the
* scheduler's dynamic sched domains. * scheduler's dynamic sched domains.
* *
* Call with cpuset_mutex held. Takes get_online_cpus().
*/ */
static void rebuild_sched_domains_cpuslocked(void) static void rebuild_sched_domains_locked(void)
{ {
struct sched_domain_attr *attr; struct sched_domain_attr *attr;
cpumask_var_t *doms; cpumask_var_t *doms;
int ndoms; int ndoms;
lockdep_assert_held(&cpuset_mutex); lockdep_assert_held(&cpuset_mutex);
get_online_cpus();
/* /*
* We have raced with CPU hotplug. Don't do anything to avoid * We have raced with CPU hotplug. Don't do anything to avoid
...@@ -848,25 +838,27 @@ static void rebuild_sched_domains_cpuslocked(void) ...@@ -848,25 +838,27 @@ static void rebuild_sched_domains_cpuslocked(void)
* Anyways, hotplug work item will rebuild sched domains. * Anyways, hotplug work item will rebuild sched domains.
*/ */
if (!cpumask_equal(top_cpuset.effective_cpus, cpu_active_mask)) if (!cpumask_equal(top_cpuset.effective_cpus, cpu_active_mask))
return; goto out;
/* Generate domain masks and attrs */ /* Generate domain masks and attrs */
ndoms = generate_sched_domains(&doms, &attr); ndoms = generate_sched_domains(&doms, &attr);
/* Have scheduler rebuild the domains */ /* Have scheduler rebuild the domains */
partition_sched_domains(ndoms, doms, attr); partition_sched_domains(ndoms, doms, attr);
out:
put_online_cpus();
} }
#else /* !CONFIG_SMP */ #else /* !CONFIG_SMP */
static void rebuild_sched_domains_cpuslocked(void) static void rebuild_sched_domains_locked(void)
{ {
} }
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
void rebuild_sched_domains(void) void rebuild_sched_domains(void)
{ {
cpuset_sched_change_begin(); mutex_lock(&cpuset_mutex);
rebuild_sched_domains_cpuslocked(); rebuild_sched_domains_locked();
cpuset_sched_change_end(); mutex_unlock(&cpuset_mutex);
} }
/** /**
...@@ -952,7 +944,7 @@ static void update_cpumasks_hier(struct cpuset *cs, struct cpumask *new_cpus) ...@@ -952,7 +944,7 @@ static void update_cpumasks_hier(struct cpuset *cs, struct cpumask *new_cpus)
rcu_read_unlock(); rcu_read_unlock();
if (need_rebuild_sched_domains) if (need_rebuild_sched_domains)
rebuild_sched_domains_cpuslocked(); rebuild_sched_domains_locked();
} }
/** /**
...@@ -1284,7 +1276,7 @@ static int update_relax_domain_level(struct cpuset *cs, s64 val) ...@@ -1284,7 +1276,7 @@ static int update_relax_domain_level(struct cpuset *cs, s64 val)
cs->relax_domain_level = val; cs->relax_domain_level = val;
if (!cpumask_empty(cs->cpus_allowed) && if (!cpumask_empty(cs->cpus_allowed) &&
is_sched_load_balance(cs)) is_sched_load_balance(cs))
rebuild_sched_domains_cpuslocked(); rebuild_sched_domains_locked();
} }
return 0; return 0;
...@@ -1317,6 +1309,7 @@ static void update_tasks_flags(struct cpuset *cs) ...@@ -1317,6 +1309,7 @@ static void update_tasks_flags(struct cpuset *cs)
* *
* Call with cpuset_mutex held. * Call with cpuset_mutex held.
*/ */
static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs,
int turning_on) int turning_on)
{ {
...@@ -1349,7 +1342,7 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, ...@@ -1349,7 +1342,7 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs,
spin_unlock_irq(&callback_lock); spin_unlock_irq(&callback_lock);
if (!cpumask_empty(trialcs->cpus_allowed) && balance_flag_changed) if (!cpumask_empty(trialcs->cpus_allowed) && balance_flag_changed)
rebuild_sched_domains_cpuslocked(); rebuild_sched_domains_locked();
if (spread_flag_changed) if (spread_flag_changed)
update_tasks_flags(cs); update_tasks_flags(cs);
...@@ -1617,7 +1610,7 @@ static int cpuset_write_u64(struct cgroup_subsys_state *css, struct cftype *cft, ...@@ -1617,7 +1610,7 @@ static int cpuset_write_u64(struct cgroup_subsys_state *css, struct cftype *cft,
cpuset_filetype_t type = cft->private; cpuset_filetype_t type = cft->private;
int retval = 0; int retval = 0;
cpuset_sched_change_begin(); mutex_lock(&cpuset_mutex);
if (!is_cpuset_online(cs)) { if (!is_cpuset_online(cs)) {
retval = -ENODEV; retval = -ENODEV;
goto out_unlock; goto out_unlock;
...@@ -1653,7 +1646,7 @@ static int cpuset_write_u64(struct cgroup_subsys_state *css, struct cftype *cft, ...@@ -1653,7 +1646,7 @@ static int cpuset_write_u64(struct cgroup_subsys_state *css, struct cftype *cft,
break; break;
} }
out_unlock: out_unlock:
cpuset_sched_change_end(); mutex_unlock(&cpuset_mutex);
return retval; return retval;
} }
...@@ -1664,7 +1657,7 @@ static int cpuset_write_s64(struct cgroup_subsys_state *css, struct cftype *cft, ...@@ -1664,7 +1657,7 @@ static int cpuset_write_s64(struct cgroup_subsys_state *css, struct cftype *cft,
cpuset_filetype_t type = cft->private; cpuset_filetype_t type = cft->private;
int retval = -ENODEV; int retval = -ENODEV;
cpuset_sched_change_begin(); mutex_lock(&cpuset_mutex);
if (!is_cpuset_online(cs)) if (!is_cpuset_online(cs))
goto out_unlock; goto out_unlock;
...@@ -1677,7 +1670,7 @@ static int cpuset_write_s64(struct cgroup_subsys_state *css, struct cftype *cft, ...@@ -1677,7 +1670,7 @@ static int cpuset_write_s64(struct cgroup_subsys_state *css, struct cftype *cft,
break; break;
} }
out_unlock: out_unlock:
cpuset_sched_change_end(); mutex_unlock(&cpuset_mutex);
return retval; return retval;
} }
...@@ -1716,7 +1709,7 @@ static ssize_t cpuset_write_resmask(struct kernfs_open_file *of, ...@@ -1716,7 +1709,7 @@ static ssize_t cpuset_write_resmask(struct kernfs_open_file *of,
kernfs_break_active_protection(of->kn); kernfs_break_active_protection(of->kn);
flush_work(&cpuset_hotplug_work); flush_work(&cpuset_hotplug_work);
cpuset_sched_change_begin(); mutex_lock(&cpuset_mutex);
if (!is_cpuset_online(cs)) if (!is_cpuset_online(cs))
goto out_unlock; goto out_unlock;
...@@ -1740,7 +1733,7 @@ static ssize_t cpuset_write_resmask(struct kernfs_open_file *of, ...@@ -1740,7 +1733,7 @@ static ssize_t cpuset_write_resmask(struct kernfs_open_file *of,
free_trial_cpuset(trialcs); free_trial_cpuset(trialcs);
out_unlock: out_unlock:
cpuset_sched_change_end(); mutex_unlock(&cpuset_mutex);
kernfs_unbreak_active_protection(of->kn); kernfs_unbreak_active_protection(of->kn);
css_put(&cs->css); css_put(&cs->css);
flush_workqueue(cpuset_migrate_mm_wq); flush_workqueue(cpuset_migrate_mm_wq);
...@@ -2041,14 +2034,14 @@ static int cpuset_css_online(struct cgroup_subsys_state *css) ...@@ -2041,14 +2034,14 @@ static int cpuset_css_online(struct cgroup_subsys_state *css)
/* /*
* If the cpuset being removed has its flag 'sched_load_balance' * If the cpuset being removed has its flag 'sched_load_balance'
* enabled, then simulate turning sched_load_balance off, which * enabled, then simulate turning sched_load_balance off, which
* will call rebuild_sched_domains_cpuslocked(). * will call rebuild_sched_domains_locked().
*/ */
static void cpuset_css_offline(struct cgroup_subsys_state *css) static void cpuset_css_offline(struct cgroup_subsys_state *css)
{ {
struct cpuset *cs = css_cs(css); struct cpuset *cs = css_cs(css);
cpuset_sched_change_begin(); mutex_lock(&cpuset_mutex);
if (is_sched_load_balance(cs)) if (is_sched_load_balance(cs))
update_flag(CS_SCHED_LOAD_BALANCE, cs, 0); update_flag(CS_SCHED_LOAD_BALANCE, cs, 0);
...@@ -2056,7 +2049,7 @@ static void cpuset_css_offline(struct cgroup_subsys_state *css) ...@@ -2056,7 +2049,7 @@ static void cpuset_css_offline(struct cgroup_subsys_state *css)
cpuset_dec(); cpuset_dec();
clear_bit(CS_ONLINE, &cs->flags); clear_bit(CS_ONLINE, &cs->flags);
cpuset_sched_change_end(); mutex_unlock(&cpuset_mutex);
} }
static void cpuset_css_free(struct cgroup_subsys_state *css) static void cpuset_css_free(struct cgroup_subsys_state *css)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment