diff options
author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2009-07-24 06:25:30 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-08-02 08:26:14 -0400 |
commit | 8f48894fcc89ddec62e1762f73a0825793e59e91 (patch) | |
tree | 63b071af185d7049c854cbf4d000949968236bac /kernel | |
parent | 00aec93d10a051ea64f83eff75d4065a19508ea6 (diff) |
sched: Add debug check to task_of()
A frequent mistake appears to be to call task_of() on a
scheduler entity that is not actually a task, which can result
in a wild pointer.
Add a check to catch these mistakes.
Suggested-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <new-submission>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/sched_fair.c | 20 | ||||
-rw-r--r-- | kernel/sched_rt.c | 16 |
2 files changed, 26 insertions, 10 deletions
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 493472984879..342000b31ad6 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c | |||
@@ -79,11 +79,6 @@ static const struct sched_class fair_sched_class; | |||
79 | * CFS operations on generic schedulable entities: | 79 | * CFS operations on generic schedulable entities: |
80 | */ | 80 | */ |
81 | 81 | ||
82 | static inline struct task_struct *task_of(struct sched_entity *se) | ||
83 | { | ||
84 | return container_of(se, struct task_struct, se); | ||
85 | } | ||
86 | |||
87 | #ifdef CONFIG_FAIR_GROUP_SCHED | 82 | #ifdef CONFIG_FAIR_GROUP_SCHED |
88 | 83 | ||
89 | /* cpu runqueue to which this cfs_rq is attached */ | 84 | /* cpu runqueue to which this cfs_rq is attached */ |
@@ -95,6 +90,14 @@ static inline struct rq *rq_of(struct cfs_rq *cfs_rq) | |||
95 | /* An entity is a task if it doesn't "own" a runqueue */ | 90 | /* An entity is a task if it doesn't "own" a runqueue */ |
96 | #define entity_is_task(se) (!se->my_q) | 91 | #define entity_is_task(se) (!se->my_q) |
97 | 92 | ||
93 | static inline struct task_struct *task_of(struct sched_entity *se) | ||
94 | { | ||
95 | #ifdef CONFIG_SCHED_DEBUG | ||
96 | WARN_ON_ONCE(!entity_is_task(se)); | ||
97 | #endif | ||
98 | return container_of(se, struct task_struct, se); | ||
99 | } | ||
100 | |||
98 | /* Walk up scheduling entities hierarchy */ | 101 | /* Walk up scheduling entities hierarchy */ |
99 | #define for_each_sched_entity(se) \ | 102 | #define for_each_sched_entity(se) \ |
100 | for (; se; se = se->parent) | 103 | for (; se; se = se->parent) |
@@ -186,7 +189,12 @@ find_matching_se(struct sched_entity **se, struct sched_entity **pse) | |||
186 | } | 189 | } |
187 | } | 190 | } |
188 | 191 | ||
189 | #else /* CONFIG_FAIR_GROUP_SCHED */ | 192 | #else /* !CONFIG_FAIR_GROUP_SCHED */ |
193 | |||
194 | static inline struct task_struct *task_of(struct sched_entity *se) | ||
195 | { | ||
196 | return container_of(se, struct task_struct, se); | ||
197 | } | ||
190 | 198 | ||
191 | static inline struct rq *rq_of(struct cfs_rq *cfs_rq) | 199 | static inline struct rq *rq_of(struct cfs_rq *cfs_rq) |
192 | { | 200 | { |
diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c index 13f728ef5b38..f365e66b3d49 100644 --- a/kernel/sched_rt.c +++ b/kernel/sched_rt.c | |||
@@ -3,15 +3,18 @@ | |||
3 | * policies) | 3 | * policies) |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #ifdef CONFIG_RT_GROUP_SCHED | ||
7 | |||
8 | #define rt_entity_is_task(rt_se) (!(rt_se)->my_q) | ||
9 | |||
6 | static inline struct task_struct *rt_task_of(struct sched_rt_entity *rt_se) | 10 | static inline struct task_struct *rt_task_of(struct sched_rt_entity *rt_se) |
7 | { | 11 | { |
12 | #ifdef CONFIG_SCHED_DEBUG | ||
13 | WARN_ON_ONCE(!rt_entity_is_task(rt_se)); | ||
14 | #endif | ||
8 | return container_of(rt_se, struct task_struct, rt); | 15 | return container_of(rt_se, struct task_struct, rt); |
9 | } | 16 | } |
10 | 17 | ||
11 | #ifdef CONFIG_RT_GROUP_SCHED | ||
12 | |||
13 | #define rt_entity_is_task(rt_se) (!(rt_se)->my_q) | ||
14 | |||
15 | static inline struct rq *rq_of_rt_rq(struct rt_rq *rt_rq) | 18 | static inline struct rq *rq_of_rt_rq(struct rt_rq *rt_rq) |
16 | { | 19 | { |
17 | return rt_rq->rq; | 20 | return rt_rq->rq; |
@@ -26,6 +29,11 @@ static inline struct rt_rq *rt_rq_of_se(struct sched_rt_entity *rt_se) | |||
26 | 29 | ||
27 | #define rt_entity_is_task(rt_se) (1) | 30 | #define rt_entity_is_task(rt_se) (1) |
28 | 31 | ||
32 | static inline struct task_struct *rt_task_of(struct sched_rt_entity *rt_se) | ||
33 | { | ||
34 | return container_of(rt_se, struct task_struct, rt); | ||
35 | } | ||
36 | |||
29 | static inline struct rq *rq_of_rt_rq(struct rt_rq *rt_rq) | 37 | static inline struct rq *rq_of_rt_rq(struct rt_rq *rt_rq) |
30 | { | 38 | { |
31 | return container_of(rt_rq, struct rq, rt); | 39 | return container_of(rt_rq, struct rq, rt); |