diff options
| author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2010-05-31 12:13:25 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2010-06-01 03:27:17 -0400 |
| commit | 02f726949f2be0967aa4871dd4e47d3967779b26 (patch) | |
| tree | cca72d10f5db4d5d2b37c0d3fb9c424fbef051ca | |
| parent | e51fd5e22e12b39f49b1bb60b37b300b17378a43 (diff) | |
sched, trace: Fix sched_switch() prev_state argument
For CONFIG_PREEMPT=y kernels the sched_switch(.prev_state) argument isn't
useful because we can get preempted with current->state != TASK_RUNNING
without actually getting removed from the runqueue.
Cure this by treating all preempted tasks as runnable from the tracer's
point of view.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cautiously-acked-by: Steven Rostedt <rostedt@goodmis.org>
LKML-Reference: <1275322715.27810.23323.camel@twins>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
| -rw-r--r-- | include/trace/events/sched.h | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h index 4f733ecea46e..b9e1dd6c6208 100644 --- a/include/trace/events/sched.h +++ b/include/trace/events/sched.h | |||
| @@ -115,6 +115,23 @@ DEFINE_EVENT(sched_wakeup_template, sched_wakeup_new, | |||
| 115 | TP_PROTO(struct task_struct *p, int success), | 115 | TP_PROTO(struct task_struct *p, int success), |
| 116 | TP_ARGS(p, success)); | 116 | TP_ARGS(p, success)); |
| 117 | 117 | ||
| 118 | #ifdef CREATE_TRACE_POINTS | ||
| 119 | static inline long __trace_sched_switch_state(struct task_struct *p) | ||
| 120 | { | ||
| 121 | long state = p->state; | ||
| 122 | |||
| 123 | #ifdef CONFIG_PREEMPT | ||
| 124 | /* | ||
| 125 | * For all intents and purposes a preempted task is a running task. | ||
| 126 | */ | ||
| 127 | if (task_thread_info(p)->preempt_count & PREEMPT_ACTIVE) | ||
| 128 | state = TASK_RUNNING; | ||
| 129 | #endif | ||
| 130 | |||
| 131 | return state; | ||
| 132 | } | ||
| 133 | #endif | ||
| 134 | |||
| 118 | /* | 135 | /* |
| 119 | * Tracepoint for task switches, performed by the scheduler: | 136 | * Tracepoint for task switches, performed by the scheduler: |
| 120 | */ | 137 | */ |
| @@ -139,7 +156,7 @@ TRACE_EVENT(sched_switch, | |||
| 139 | memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN); | 156 | memcpy(__entry->next_comm, next->comm, TASK_COMM_LEN); |
| 140 | __entry->prev_pid = prev->pid; | 157 | __entry->prev_pid = prev->pid; |
| 141 | __entry->prev_prio = prev->prio; | 158 | __entry->prev_prio = prev->prio; |
| 142 | __entry->prev_state = prev->state; | 159 | __entry->prev_state = __trace_sched_switch_state(prev); |
| 143 | memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN); | 160 | memcpy(__entry->prev_comm, prev->comm, TASK_COMM_LEN); |
| 144 | __entry->next_pid = next->pid; | 161 | __entry->next_pid = next->pid; |
| 145 | __entry->next_prio = next->prio; | 162 | __entry->next_prio = next->prio; |
