History

cgroup/cpuset: Change cpuset_rwsem and hotplug lock order

cpuset_rwsem is going to be acquired from sched_setscheduler() with a following patch. There are however paths (e.g., spawn_ksoftirqd) in which sched_scheduler() is eventually called while holding hotplug lock; this creates a dependecy between hotplug lock (to be always acquired first) and cpuset_rwsem (to be always acquired after hotplug lock). Fix paths which currently take the two locks in the wrong order (after a following patch is applied).

Juri Lelli committed 7 years ago

Commit d74b27d1 parent 1243dc52 files · +21 −9Browse files

Unified · Split

2 files
  1. include/linux/cpuset.h +4 −4
  2. kernel/cgroup/cpuset.c +17 −5
include/linux/cpuset.h+4−4
@@ -40,14 +40,14 @@ static inline bool cpusets_enabled(void) · 39 unmodified lines
4040
4141 static inline void cpuset_inc(void)
4242 {
43− static_branch_inc(&cpusets_pre_enable_key);
44− static_branch_inc(&cpusets_enabled_key);
43+ static_branch_inc_cpuslocked(&cpusets_pre_enable_key);
44+ static_branch_inc_cpuslocked(&cpusets_enabled_key);
4545 }
4646
4747 static inline void cpuset_dec(void)
4848 {
49− static_branch_dec(&cpusets_enabled_key);
50− static_branch_dec(&cpusets_pre_enable_key);
49+ static_branch_dec_cpuslocked(&cpusets_enabled_key);
50+ static_branch_dec_cpuslocked(&cpusets_pre_enable_key);
5151 }
5252
5353 extern int cpuset_init(void);
kernel/cgroup/cpuset.c+17−5
@@ -973,8 +973,8 @@ static void rebuild_sched_domains_locked(void) · 972 unmodified lines
973973 cpumask_var_t *doms;
974974 int ndoms;
975975
976+ lockdep_assert_cpus_held();
976977 percpu_rwsem_assert_held(&cpuset_rwsem);
977− get_online_cpus();
978978
979979 /*
980980 * We have raced with CPU hotplug. Don't do anything to avoid
@@ -983,19 +983,17 @@ static void rebuild_sched_domains_locked(void) · 2 unmodified lines
983983 */
984984 if (!top_cpuset.nr_subparts_cpus &&
985985 !cpumask_equal(top_cpuset.effective_cpus, cpu_active_mask))
986− goto out;
986+ return;
987987
988988 if (top_cpuset.nr_subparts_cpus &&
989989 !cpumask_subset(top_cpuset.effective_cpus, cpu_active_mask))
990− goto out;
990+ return;
991991
992992 /* Generate domain masks and attrs */
993993 ndoms = generate_sched_domains(&doms, &attr);
994994
995995 /* Have scheduler rebuild the domains */
996996 partition_and_rebuild_sched_domains(ndoms, doms, attr);
997−out:
998− put_online_cpus();
999997 }
1000998 #else /* !CONFIG_SMP */
1001999 static void rebuild_sched_domains_locked(void)
@@ -1005,9 +1003,11 @@ static void rebuild_sched_domains_locked(void) · 3 unmodified lines
10051003
10061004 void rebuild_sched_domains(void)
10071005 {
1006+ get_online_cpus();
10081007 percpu_down_write(&cpuset_rwsem);
10091008 rebuild_sched_domains_locked();
10101009 percpu_up_write(&cpuset_rwsem);
1010+ put_online_cpus();
10111011 }
10121012
10131013 /**
@@ -2245,6 +2245,7 @@ static int cpuset_write_u64(struct cgroup_subsys_state *css, struct cftype *cft, · 1231 unmodified lines
22452245 cpuset_filetype_t type = cft->private;
22462246 int retval = 0;
22472247
2248+ get_online_cpus();
22482249 percpu_down_write(&cpuset_rwsem);
22492250 if (!is_cpuset_online(cs)) {
22502251 retval = -ENODEV;
@@ -2282,6 +2283,7 @@ static int cpuset_write_u64(struct cgroup_subsys_state *css, struct cftype *cft, · 31 unmodified lines
22822283 }
22832284 out_unlock:
22842285 percpu_up_write(&cpuset_rwsem);
2286+ put_online_cpus();
22852287 return retval;
22862288 }
22872289
@@ -2292,6 +2294,7 @@ static int cpuset_write_s64(struct cgroup_subsys_state *css, struct cftype *cft, · 4 unmodified lines
22922294 cpuset_filetype_t type = cft->private;
22932295 int retval = -ENODEV;
22942296
2297+ get_online_cpus();
22952298 percpu_down_write(&cpuset_rwsem);
22962299 if (!is_cpuset_online(cs))
22972300 goto out_unlock;
@@ -2306,6 +2309,7 @@ static int cpuset_write_s64(struct cgroup_subsys_state *css, struct cftype *cft, · 8 unmodified lines
23062309 }
23072310 out_unlock:
23082311 percpu_up_write(&cpuset_rwsem);
2312+ put_online_cpus();
23092313 return retval;
23102314 }
23112315
@@ -2344,6 +2348,7 @@ static ssize_t cpuset_write_resmask(struct kernfs_open_file *of, · 32 unmodified lines
23442348 kernfs_break_active_protection(of->kn);
23452349 flush_work(&cpuset_hotplug_work);
23462350
2351+ get_online_cpus();
23472352 percpu_down_write(&cpuset_rwsem);
23482353 if (!is_cpuset_online(cs))
23492354 goto out_unlock;
@@ -2369,6 +2374,7 @@ static ssize_t cpuset_write_resmask(struct kernfs_open_file *of, · 19 unmodified lines
23692374 free_cpuset(trialcs);
23702375 out_unlock:
23712376 percpu_up_write(&cpuset_rwsem);
2377+ put_online_cpus();
23722378 kernfs_unbreak_active_protection(of->kn);
23732379 css_put(&cs->css);
23742380 flush_workqueue(cpuset_migrate_mm_wq);
@@ -2499,6 +2505,7 @@ static ssize_t sched_partition_write(struct kernfs_open_file *of, char *buf, · 124 unmodified lines
24992505 return -EINVAL;
25002506
25012507 css_get(&cs->css);
2508+ get_online_cpus();
25022509 percpu_down_write(&cpuset_rwsem);
25032510 if (!is_cpuset_online(cs))
25042511 goto out_unlock;
@@ -2506,6 +2513,7 @@ static ssize_t sched_partition_write(struct kernfs_open_file *of, char *buf, · 1 unmodified line
25062513 retval = update_prstate(cs, val);
25072514 out_unlock:
25082515 percpu_up_write(&cpuset_rwsem);
2516+ put_online_cpus();
25092517 css_put(&cs->css);
25102518 return retval ?: nbytes;
25112519 }
@@ -2711,6 +2719,7 @@ static int cpuset_css_online(struct cgroup_subsys_state *css) · 199 unmodified lines
27112719 if (!parent)
27122720 return 0;
27132721
2722+ get_online_cpus();
27142723 percpu_down_write(&cpuset_rwsem);
27152724
27162725 set_bit(CS_ONLINE, &cs->flags);
@@ -2763,6 +2772,7 @@ static int cpuset_css_online(struct cgroup_subsys_state *css) · 46 unmodified lines
27632772 spin_unlock_irq(&callback_lock);
27642773 out_unlock:
27652774 percpu_up_write(&cpuset_rwsem);
2775+ put_online_cpus();
27662776 return 0;
27672777 }
27682778
@@ -2781,6 +2791,7 @@ static void cpuset_css_offline(struct cgroup_subsys_state *css) · 12 unmodified lines
27812791 {
27822792 struct cpuset *cs = css_cs(css);
27832793
2794+ get_online_cpus();
27842795 percpu_down_write(&cpuset_rwsem);
27852796
27862797 if (is_partition_root(cs))
@@ -2801,6 +2812,7 @@ static void cpuset_css_offline(struct cgroup_subsys_state *css) · 14 unmodified lines
28012812 clear_bit(CS_ONLINE, &cs->flags);
28022813
28032814 percpu_up_write(&cpuset_rwsem);
2815+ put_online_cpus();
28042816 }
28052817
28062818 static void cpuset_css_free(struct cgroup_subsys_state *css)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t