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
40 40
41static inline void cpuset_inc(void)41static inline void cpuset_inc(void)
42{42{
43 static_branch_inc(&cpusets_pre_enable_key);43 static_branch_inc_cpuslocked(&cpusets_pre_enable_key);
44 static_branch_inc(&cpusets_enabled_key);44 static_branch_inc_cpuslocked(&cpusets_enabled_key);
45}45}
46 46
47static inline void cpuset_dec(void)47static inline void cpuset_dec(void)
48{48{
49 static_branch_dec(&cpusets_enabled_key);49 static_branch_dec_cpuslocked(&cpusets_enabled_key);
50 static_branch_dec(&cpusets_pre_enable_key);50 static_branch_dec_cpuslocked(&cpusets_pre_enable_key);
51}51}
52 52
53extern int cpuset_init(void);53extern int cpuset_init(void);
kernel/cgroup/cpuset.c+17−5
@@ -973,8 +973,8 @@ static void rebuild_sched_domains_locked(void) · 972 unmodified lines
973 cpumask_var_t *doms;973 cpumask_var_t *doms;
974 int ndoms;974 int ndoms;
975 975
976 lockdep_assert_cpus_held();
976 percpu_rwsem_assert_held(&cpuset_rwsem);977 percpu_rwsem_assert_held(&cpuset_rwsem);
977 get_online_cpus();
978 978
979 /*979 /*
980 * We have raced with CPU hotplug. Don't do anything to avoid980 * 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
983 */983 */
984 if (!top_cpuset.nr_subparts_cpus &&984 if (!top_cpuset.nr_subparts_cpus &&
985 !cpumask_equal(top_cpuset.effective_cpus, cpu_active_mask))985 !cpumask_equal(top_cpuset.effective_cpus, cpu_active_mask))
986 goto out;986 return;
987 987
988 if (top_cpuset.nr_subparts_cpus &&988 if (top_cpuset.nr_subparts_cpus &&
989 !cpumask_subset(top_cpuset.effective_cpus, cpu_active_mask))989 !cpumask_subset(top_cpuset.effective_cpus, cpu_active_mask))
990 goto out;990 return;
991 991
992 /* Generate domain masks and attrs */992 /* Generate domain masks and attrs */
993 ndoms = generate_sched_domains(&doms, &attr);993 ndoms = generate_sched_domains(&doms, &attr);
994 994
995 /* Have scheduler rebuild the domains */995 /* Have scheduler rebuild the domains */
996 partition_and_rebuild_sched_domains(ndoms, doms, attr);996 partition_and_rebuild_sched_domains(ndoms, doms, attr);
997out:
998 put_online_cpus();
999}997}
1000#else /* !CONFIG_SMP */998#else /* !CONFIG_SMP */
1001static void rebuild_sched_domains_locked(void)999static void rebuild_sched_domains_locked(void)
@@ -1005,9 +1003,11 @@ static void rebuild_sched_domains_locked(void) · 3 unmodified lines
1005 1003
1006void rebuild_sched_domains(void)1004void rebuild_sched_domains(void)
1007{1005{
1006 get_online_cpus();
1008 percpu_down_write(&cpuset_rwsem);1007 percpu_down_write(&cpuset_rwsem);
1009 rebuild_sched_domains_locked();1008 rebuild_sched_domains_locked();
1010 percpu_up_write(&cpuset_rwsem);1009 percpu_up_write(&cpuset_rwsem);
1010 put_online_cpus();
1011}1011}
1012 1012
1013/**1013/**
@@ -2245,6 +2245,7 @@ static int cpuset_write_u64(struct cgroup_subsys_state *css, struct cftype *cft, · 1231 unmodified lines
2245 cpuset_filetype_t type = cft->private;2245 cpuset_filetype_t type = cft->private;
2246 int retval = 0;2246 int retval = 0;
2247 2247
2248 get_online_cpus();
2248 percpu_down_write(&cpuset_rwsem);2249 percpu_down_write(&cpuset_rwsem);
2249 if (!is_cpuset_online(cs)) {2250 if (!is_cpuset_online(cs)) {
2250 retval = -ENODEV;2251 retval = -ENODEV;
@@ -2282,6 +2283,7 @@ static int cpuset_write_u64(struct cgroup_subsys_state *css, struct cftype *cft, · 31 unmodified lines
2282 }2283 }
2283out_unlock:2284out_unlock:
2284 percpu_up_write(&cpuset_rwsem);2285 percpu_up_write(&cpuset_rwsem);
2286 put_online_cpus();
2285 return retval;2287 return retval;
2286}2288}
2287 2289
@@ -2292,6 +2294,7 @@ static int cpuset_write_s64(struct cgroup_subsys_state *css, struct cftype *cft, · 4 unmodified lines
2292 cpuset_filetype_t type = cft->private;2294 cpuset_filetype_t type = cft->private;
2293 int retval = -ENODEV;2295 int retval = -ENODEV;
2294 2296
2297 get_online_cpus();
2295 percpu_down_write(&cpuset_rwsem);2298 percpu_down_write(&cpuset_rwsem);
2296 if (!is_cpuset_online(cs))2299 if (!is_cpuset_online(cs))
2297 goto out_unlock;2300 goto out_unlock;
@@ -2306,6 +2309,7 @@ static int cpuset_write_s64(struct cgroup_subsys_state *css, struct cftype *cft, · 8 unmodified lines
2306 }2309 }
2307out_unlock:2310out_unlock:
2308 percpu_up_write(&cpuset_rwsem);2311 percpu_up_write(&cpuset_rwsem);
2312 put_online_cpus();
2309 return retval;2313 return retval;
2310}2314}
2311 2315
@@ -2344,6 +2348,7 @@ static ssize_t cpuset_write_resmask(struct kernfs_open_file *of, · 32 unmodified lines
2344 kernfs_break_active_protection(of->kn);2348 kernfs_break_active_protection(of->kn);
2345 flush_work(&cpuset_hotplug_work);2349 flush_work(&cpuset_hotplug_work);
2346 2350
2351 get_online_cpus();
2347 percpu_down_write(&cpuset_rwsem);2352 percpu_down_write(&cpuset_rwsem);
2348 if (!is_cpuset_online(cs))2353 if (!is_cpuset_online(cs))
2349 goto out_unlock;2354 goto out_unlock;
@@ -2369,6 +2374,7 @@ static ssize_t cpuset_write_resmask(struct kernfs_open_file *of, · 19 unmodified lines
2369 free_cpuset(trialcs);2374 free_cpuset(trialcs);
2370out_unlock:2375out_unlock:
2371 percpu_up_write(&cpuset_rwsem);2376 percpu_up_write(&cpuset_rwsem);
2377 put_online_cpus();
2372 kernfs_unbreak_active_protection(of->kn);2378 kernfs_unbreak_active_protection(of->kn);
2373 css_put(&cs->css);2379 css_put(&cs->css);
2374 flush_workqueue(cpuset_migrate_mm_wq);2380 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
2499 return -EINVAL;2505 return -EINVAL;
2500 2506
2501 css_get(&cs->css);2507 css_get(&cs->css);
2508 get_online_cpus();
2502 percpu_down_write(&cpuset_rwsem);2509 percpu_down_write(&cpuset_rwsem);
2503 if (!is_cpuset_online(cs))2510 if (!is_cpuset_online(cs))
2504 goto out_unlock;2511 goto out_unlock;
@@ -2506,6 +2513,7 @@ static ssize_t sched_partition_write(struct kernfs_open_file *of, char *buf, · 1 unmodified line
2506 retval = update_prstate(cs, val);2513 retval = update_prstate(cs, val);
2507out_unlock:2514out_unlock:
2508 percpu_up_write(&cpuset_rwsem);2515 percpu_up_write(&cpuset_rwsem);
2516 put_online_cpus();
2509 css_put(&cs->css);2517 css_put(&cs->css);
2510 return retval ?: nbytes;2518 return retval ?: nbytes;
2511}2519}
@@ -2711,6 +2719,7 @@ static int cpuset_css_online(struct cgroup_subsys_state *css) · 199 unmodified lines
2711 if (!parent)2719 if (!parent)
2712 return 0;2720 return 0;
2713 2721
2722 get_online_cpus();
2714 percpu_down_write(&cpuset_rwsem);2723 percpu_down_write(&cpuset_rwsem);
2715 2724
2716 set_bit(CS_ONLINE, &cs->flags);2725 set_bit(CS_ONLINE, &cs->flags);
@@ -2763,6 +2772,7 @@ static int cpuset_css_online(struct cgroup_subsys_state *css) · 46 unmodified lines
2763 spin_unlock_irq(&callback_lock);2772 spin_unlock_irq(&callback_lock);
2764out_unlock:2773out_unlock:
2765 percpu_up_write(&cpuset_rwsem);2774 percpu_up_write(&cpuset_rwsem);
2775 put_online_cpus();
2766 return 0;2776 return 0;
2767}2777}
2768 2778
@@ -2781,6 +2791,7 @@ static void cpuset_css_offline(struct cgroup_subsys_state *css) · 12 unmodified lines
2781{2791{
2782 struct cpuset *cs = css_cs(css);2792 struct cpuset *cs = css_cs(css);
2783 2793
2794 get_online_cpus();
2784 percpu_down_write(&cpuset_rwsem);2795 percpu_down_write(&cpuset_rwsem);
2785 2796
2786 if (is_partition_root(cs))2797 if (is_partition_root(cs))
@@ -2801,6 +2812,7 @@ static void cpuset_css_offline(struct cgroup_subsys_state *css) · 14 unmodified lines
2801 clear_bit(CS_ONLINE, &cs->flags);2812 clear_bit(CS_ONLINE, &cs->flags);
2802 2813
2803 percpu_up_write(&cpuset_rwsem);2814 percpu_up_write(&cpuset_rwsem);
2815 put_online_cpus();
2804}2816}
2805 2817
2806static void cpuset_css_free(struct cgroup_subsys_state *css)2818static 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