No synchronisation mechanism exists between the cpuset subsystem and calls to function __sched_setscheduler(). As such, it is possible that new root domains are created on the cpuset side while a deadline acceptance test is carried out in __sched_setscheduler(), leading to a potential oversell of CPU bandwidth. Grab cpuset_rwsem read lock from core scheduler, so to prevent situations such as the one described above from happening. The only exception is normalize_rt_tasks() which needs to work under tasklist_lock and can't therefore grab cpuset_rwsem. We are fine with this, as this function is only called by sysrq and, if that gets triggered, DEADLINE guarantees are already gone out of the window anyway.
Showing the changes to include/linux (1 of 3 files). Show all
Unified · Split
| @@ -55,6 +55,8 @@ extern void cpuset_init_smp(void); · 54 unmodified lines | |||
| 55 | extern void cpuset_force_rebuild(void); | 55 | extern void cpuset_force_rebuild(void); |
| 56 | extern void cpuset_update_active_cpus(void); | 56 | extern void cpuset_update_active_cpus(void); |
| 57 | extern void cpuset_wait_for_hotplug(void); | 57 | extern void cpuset_wait_for_hotplug(void); |
| 58 | extern void cpuset_read_lock(void); | ||
| 59 | extern void cpuset_read_unlock(void); | ||
| 58 | extern void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask); | 60 | extern void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask); |
| 59 | extern void cpuset_cpus_allowed_fallback(struct task_struct *p); | 61 | extern void cpuset_cpus_allowed_fallback(struct task_struct *p); |
| 60 | extern nodemask_t cpuset_mems_allowed(struct task_struct *p); | 62 | extern nodemask_t cpuset_mems_allowed(struct task_struct *p); |
| @@ -176,6 +178,9 @@ static inline void cpuset_update_active_cpus(void) · 115 unmodified lines | |||
| 176 | 178 | ||
| 177 | static inline void cpuset_wait_for_hotplug(void) { } | 179 | static inline void cpuset_wait_for_hotplug(void) { } |
| 178 | 180 | ||
| 181 | static inline void cpuset_read_lock(void) { } | ||
| 182 | static inline void cpuset_read_unlock(void) { } | ||
| 183 | |||
| 179 | static inline void cpuset_cpus_allowed(struct task_struct *p, | 184 | static inline void cpuset_cpus_allowed(struct task_struct *p, |
| 180 | struct cpumask *mask) | 185 | struct cpumask *mask) |
| 181 | { | 186 | { |