History

tracing: Use one prologue for the wakeup tracer function tracers

The wakeup tracer has three types of function tracers. Normal function tracer, function graph entry, and function graph return. Each of these use a complex dance to prevent recursion and whether to trace the data or not (depending on the wake_task variable). This patch moves the duplicate code into a single routine, to prevent future mistakes with modifying duplicate complex code.

Steven Rostedt committed 16 years ago

Commit 542181d1 parent 7495a5b1 file · +50 −52Browse files

Showing the changes to kernel (1 of 1 file). Show all

Unified · Split

kernel/trace/trace_sched_wakeup.c+50−52
@@ -56,43 +56,73 @@ static struct tracer_flags tracer_flags = { · 55 unmodified lines
5656 #define is_graph() (tracer_flags.val & TRACE_DISPLAY_GRAPH)
5757
5858 #ifdef CONFIG_FUNCTION_TRACER
59+
5960 /*
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.
6173 */
62−static void
63−wakeup_tracer_call(unsigned long ip, unsigned long parent_ip)
74+static int
75+func_prolog_preempt_disable(struct trace_array *tr,
76+ struct trace_array_cpu **data,
77+ int *pc)
6478 {
65− struct trace_array *tr = wakeup_trace;
66− struct trace_array_cpu *data;
67− unsigned long flags;
6879 long disabled;
6980 int cpu;
70− int pc;
7181
7282 if (likely(!wakeup_task))
73− return;
83+ return 0;
7484
75− pc = preempt_count();
85+ *pc = preempt_count();
7686 preempt_disable_notrace();
7787
7888 cpu = raw_smp_processor_id();
7989 if (cpu != wakeup_current_cpu)
8090 goto out_enable;
8191
82− data = tr->data[cpu];
83− disabled = atomic_inc_return(&data->disabled);
92+ *data = tr->data[cpu];
93+ disabled = atomic_inc_return(&(*data)->disabled);
8494 if (unlikely(disabled != 1))
8595 goto out;
8696
87− local_irq_save(flags);
97+ return 1;
8898
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;
90120
121+ local_irq_save(flags);
122+ trace_function(tr, ip, parent_ip, flags, pc);
91123 local_irq_restore(flags);
92124
93− out:
94125 atomic_dec(&data->disabled);
95− out_enable:
96126 preempt_enable_notrace();
97127 }
98128
@@ -154,32 +184,16 @@ static int wakeup_graph_entry(struct ftrace_graph_ent *trace) · 55 unmodified lines
154184 struct trace_array *tr = wakeup_trace;
155185 struct trace_array_cpu *data;
156186 unsigned long flags;
157− long disabled;
158− int cpu, pc, ret = 0;
187+ int pc, ret = 0;
159188
160− if (likely(!wakeup_task))
189+ if (!func_prolog_preempt_disable(tr, &data, &pc))
161190 return 0;
162191
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−
175192 local_save_flags(flags);
176193 ret = __trace_graph_entry(tr, trace, flags, pc);
177−
178−out:
179194 atomic_dec(&data->disabled);
180−
181−out_enable:
182195 preempt_enable_notrace();
196+
183197 return ret;
184198 }
185199
@@ -188,31 +202,15 @@ static void wakeup_graph_return(struct ftrace_graph_ret *trace) · 2 unmodified lines
188202 struct trace_array *tr = wakeup_trace;
189203 struct trace_array_cpu *data;
190204 unsigned long flags;
191− long disabled;
192− int cpu, pc;
205+ int pc;
193206
194− if (likely(!wakeup_task))
207+ if (!func_prolog_preempt_disable(tr, &data, &pc))
195208 return;
196209
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−
209210 local_save_flags(flags);
210211 __trace_graph_return(tr, trace, flags, pc);
211−
212−out:
213212 atomic_dec(&data->disabled);
214213
215−out_enable:
216214 preempt_enable_notrace();
217215 return;
218216 }