diff options
author | Oleg Nesterov <oleg@redhat.com> | 2010-03-15 05:10:27 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2010-04-02 14:12:03 -0400 |
commit | 9084bb8246ea935b98320554229e2f371f7f52fa (patch) | |
tree | 8478d18125e3b4a7e0a31d702647dee1830d23ef /include/linux/cpuset.h | |
parent | 6a1bdc1b577ebcb65f6603c57f8347309bc4ab13 (diff) |
sched: Make select_fallback_rq() cpuset friendly
Introduce cpuset_cpus_allowed_fallback() helper to fix the cpuset problems
with select_fallback_rq(). It can be called from any context and can't use
any cpuset locks including task_lock(). It is called when the task doesn't
have online cpus in ->cpus_allowed but ttwu/etc must be able to find a
suitable cpu.
I am not proud of this patch. Everything which needs such a fat comment
can't be good even if correct. But I'd prefer to not change the locking
rules in the code I hardly understand, and in any case I believe this
simple change make the code much more correct compared to deadlocks we
currently have.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <20100315091027.GA9155@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'include/linux/cpuset.h')
-rw-r--r-- | include/linux/cpuset.h | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h index eeaaee746bee..a73454aec333 100644 --- a/include/linux/cpuset.h +++ b/include/linux/cpuset.h | |||
@@ -21,6 +21,7 @@ extern int number_of_cpusets; /* How many cpusets are defined in system? */ | |||
21 | extern int cpuset_init(void); | 21 | extern int cpuset_init(void); |
22 | extern void cpuset_init_smp(void); | 22 | extern void cpuset_init_smp(void); |
23 | extern void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask); | 23 | extern void cpuset_cpus_allowed(struct task_struct *p, struct cpumask *mask); |
24 | extern int cpuset_cpus_allowed_fallback(struct task_struct *p); | ||
24 | extern nodemask_t cpuset_mems_allowed(struct task_struct *p); | 25 | extern nodemask_t cpuset_mems_allowed(struct task_struct *p); |
25 | #define cpuset_current_mems_allowed (current->mems_allowed) | 26 | #define cpuset_current_mems_allowed (current->mems_allowed) |
26 | void cpuset_init_current_mems_allowed(void); | 27 | void cpuset_init_current_mems_allowed(void); |
@@ -101,6 +102,12 @@ static inline void cpuset_cpus_allowed(struct task_struct *p, | |||
101 | cpumask_copy(mask, cpu_possible_mask); | 102 | cpumask_copy(mask, cpu_possible_mask); |
102 | } | 103 | } |
103 | 104 | ||
105 | static inline int cpuset_cpus_allowed_fallback(struct task_struct *p) | ||
106 | { | ||
107 | cpumask_copy(&p->cpus_allowed, cpu_possible_mask); | ||
108 | return cpumask_any(cpu_active_mask); | ||
109 | } | ||
110 | |||
104 | static inline nodemask_t cpuset_mems_allowed(struct task_struct *p) | 111 | static inline nodemask_t cpuset_mems_allowed(struct task_struct *p) |
105 | { | 112 | { |
106 | return node_possible_map; | 113 | return node_possible_map; |