diff options
| -rw-r--r-- | kernel/trace/trace_sched_wakeup.c | 102 |
1 files changed, 50 insertions, 52 deletions
diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c index 033510dbb322..31689d2df7f3 100644 --- a/kernel/trace/trace_sched_wakeup.c +++ b/kernel/trace/trace_sched_wakeup.c | |||
| @@ -56,43 +56,73 @@ static struct tracer_flags tracer_flags = { | |||
| 56 | #define is_graph() (tracer_flags.val & TRACE_DISPLAY_GRAPH) | 56 | #define is_graph() (tracer_flags.val & TRACE_DISPLAY_GRAPH) |
| 57 | 57 | ||
| 58 | #ifdef CONFIG_FUNCTION_TRACER | 58 | #ifdef CONFIG_FUNCTION_TRACER |
| 59 | |||
| 59 | /* | 60 | /* |
| 60 | * wakeup uses its own tracer function to keep the overhead down: | 61 | * Prologue for the wakeup function tracers. |
| 62 | * | ||
| 63 | * Returns 1 if it is OK to continue, and preemption | ||
| 64 | * is disabled and data->disabled is incremented. | ||
| 65 | * 0 if the trace is to be ignored, and preemption | ||
| 66 | * is not disabled and data->disabled is | ||
| 67 | * kept the same. | ||
| 68 | * | ||
| 69 | * Note, this function is also used outside this ifdef but | ||
| 70 | * inside the #ifdef of the function graph tracer below. | ||
| 71 | * This is OK, since the function graph tracer is | ||
| 72 | * dependent on the function tracer. | ||
| 61 | */ | 73 | */ |
| 62 | static void | 74 | static int |
| 63 | wakeup_tracer_call(unsigned long ip, unsigned long parent_ip) | 75 | func_prolog_preempt_disable(struct trace_array *tr, |
| 76 | struct trace_array_cpu **data, | ||
| 77 | int *pc) | ||
| 64 | { | 78 | { |
| 65 | struct trace_array *tr = wakeup_trace; | ||
| 66 | struct trace_array_cpu *data; | ||
| 67 | unsigned long flags; | ||
| 68 | long disabled; | 79 | long disabled; |
| 69 | int cpu; | 80 | int cpu; |
| 70 | int pc; | ||
| 71 | 81 | ||
| 72 | if (likely(!wakeup_task)) | 82 | if (likely(!wakeup_task)) |
| 73 | return; | 83 | return 0; |
| 74 | 84 | ||
| 75 | pc = preempt_count(); | 85 | *pc = preempt_count(); |
| 76 | preempt_disable_notrace(); | 86 | preempt_disable_notrace(); |
| 77 | 87 | ||
| 78 | cpu = raw_smp_processor_id(); | 88 | cpu = raw_smp_processor_id(); |
| 79 | if (cpu != wakeup_current_cpu) | 89 | if (cpu != wakeup_current_cpu) |
| 80 | goto out_enable; | 90 | goto out_enable; |
| 81 | 91 | ||
| 82 | data = tr->data[cpu]; | 92 | *data = tr->data[cpu]; |
| 83 | disabled = atomic_inc_return(&data->disabled); | 93 | disabled = atomic_inc_return(&(*data)->disabled); |
| 84 | if (unlikely(disabled != 1)) | 94 | if (unlikely(disabled != 1)) |
| 85 | goto out; | 95 | goto out; |
| 86 | 96 | ||
| 87 | local_irq_save(flags); | 97 | return 1; |
| 88 | 98 | ||
| 89 | trace_function(tr, ip, parent_ip, flags, pc); | 99 | out: |
| 100 | atomic_dec(&(*data)->disabled); | ||
| 101 | |||
| 102 | out_enable: | ||
| 103 | preempt_enable_notrace(); | ||
| 104 | return 0; | ||
| 105 | } | ||
| 106 | |||
| 107 | /* | ||
| 108 | * wakeup uses its own tracer function to keep the overhead down: | ||
| 109 | */ | ||
| 110 | static void | ||
| 111 | wakeup_tracer_call(unsigned long ip, unsigned long parent_ip) | ||
| 112 | { | ||
| 113 | struct trace_array *tr = wakeup_trace; | ||
| 114 | struct trace_array_cpu *data; | ||
| 115 | unsigned long flags; | ||
| 116 | int pc; | ||
| 117 | |||
| 118 | if (!func_prolog_preempt_disable(tr, &data, &pc)) | ||
| 119 | return; | ||
| 90 | 120 | ||
| 121 | local_irq_save(flags); | ||
| 122 | trace_function(tr, ip, parent_ip, flags, pc); | ||
| 91 | local_irq_restore(flags); | 123 | local_irq_restore(flags); |
| 92 | 124 | ||
| 93 | out: | ||
| 94 | atomic_dec(&data->disabled); | 125 | atomic_dec(&data->disabled); |
| 95 | out_enable: | ||
| 96 | preempt_enable_notrace(); | 126 | preempt_enable_notrace(); |
| 97 | } | 127 | } |
| 98 | 128 | ||
| @@ -154,32 +184,16 @@ static int wakeup_graph_entry(struct ftrace_graph_ent *trace) | |||
| 154 | struct trace_array *tr = wakeup_trace; | 184 | struct trace_array *tr = wakeup_trace; |
| 155 | struct trace_array_cpu *data; | 185 | struct trace_array_cpu *data; |
| 156 | unsigned long flags; | 186 | unsigned long flags; |
| 157 | long disabled; | 187 | int pc, ret = 0; |
| 158 | int cpu, pc, ret = 0; | ||
| 159 | 188 | ||
| 160 | if (likely(!wakeup_task)) | 189 | if (!func_prolog_preempt_disable(tr, &data, &pc)) |
| 161 | return 0; | 190 | return 0; |
| 162 | 191 | ||
| 163 | pc = preempt_count(); | ||
| 164 | preempt_disable_notrace(); | ||
| 165 | |||
| 166 | cpu = raw_smp_processor_id(); | ||
| 167 | if (cpu != wakeup_current_cpu) | ||
| 168 | goto out_enable; | ||
| 169 | |||
| 170 | data = tr->data[cpu]; | ||
| 171 | disabled = atomic_inc_return(&data->disabled); | ||
| 172 | if (unlikely(disabled != 1)) | ||
| 173 | goto out; | ||
| 174 | |||
| 175 | local_save_flags(flags); | 192 | local_save_flags(flags); |
| 176 | ret = __trace_graph_entry(tr, trace, flags, pc); | 193 | ret = __trace_graph_entry(tr, trace, flags, pc); |
| 177 | |||
| 178 | out: | ||
| 179 | atomic_dec(&data->disabled); | 194 | atomic_dec(&data->disabled); |
| 180 | |||
| 181 | out_enable: | ||
| 182 | preempt_enable_notrace(); | 195 | preempt_enable_notrace(); |
| 196 | |||
| 183 | return ret; | 197 | return ret; |
| 184 | } | 198 | } |
| 185 | 199 | ||
| @@ -188,31 +202,15 @@ static void wakeup_graph_return(struct ftrace_graph_ret *trace) | |||
| 188 | struct trace_array *tr = wakeup_trace; | 202 | struct trace_array *tr = wakeup_trace; |
| 189 | struct trace_array_cpu *data; | 203 | struct trace_array_cpu *data; |
| 190 | unsigned long flags; | 204 | unsigned long flags; |
| 191 | long disabled; | 205 | int pc; |
| 192 | int cpu, pc; | ||
| 193 | 206 | ||
| 194 | if (likely(!wakeup_task)) | 207 | if (!func_prolog_preempt_disable(tr, &data, &pc)) |
| 195 | return; | 208 | return; |
| 196 | 209 | ||
| 197 | pc = preempt_count(); | ||
| 198 | preempt_disable_notrace(); | ||
| 199 | |||
| 200 | cpu = raw_smp_processor_id(); | ||
| 201 | if (cpu != wakeup_current_cpu) | ||
| 202 | goto out_enable; | ||
| 203 | |||
| 204 | data = tr->data[cpu]; | ||
| 205 | disabled = atomic_inc_return(&data->disabled); | ||
| 206 | if (unlikely(disabled != 1)) | ||
| 207 | goto out; | ||
| 208 | |||
| 209 | local_save_flags(flags); | 210 | local_save_flags(flags); |
| 210 | __trace_graph_return(tr, trace, flags, pc); | 211 | __trace_graph_return(tr, trace, flags, pc); |
| 211 | |||
| 212 | out: | ||
| 213 | atomic_dec(&data->disabled); | 212 | atomic_dec(&data->disabled); |
| 214 | 213 | ||
| 215 | out_enable: | ||
| 216 | preempt_enable_notrace(); | 214 | preempt_enable_notrace(); |
| 217 | return; | 215 | return; |
| 218 | } | 216 | } |
