.. | .. |
---|
143 | 143 | struct trace_array *tr = irqsoff_trace; |
---|
144 | 144 | struct trace_array_cpu *data; |
---|
145 | 145 | unsigned long flags; |
---|
146 | | - unsigned int trace_ctx; |
---|
147 | 146 | |
---|
148 | 147 | if (!func_prolog_dec(tr, &data, &flags)) |
---|
149 | 148 | return; |
---|
150 | 149 | |
---|
151 | | - trace_ctx = tracing_gen_ctx_flags(flags); |
---|
152 | | - |
---|
153 | | - trace_function(tr, ip, parent_ip, trace_ctx); |
---|
| 150 | + trace_function(tr, ip, parent_ip, flags, preempt_count()); |
---|
154 | 151 | |
---|
155 | 152 | atomic_dec(&data->disabled); |
---|
156 | 153 | } |
---|
.. | .. |
---|
180 | 177 | struct trace_array *tr = irqsoff_trace; |
---|
181 | 178 | struct trace_array_cpu *data; |
---|
182 | 179 | unsigned long flags; |
---|
183 | | - unsigned int trace_ctx; |
---|
184 | 180 | int ret; |
---|
| 181 | + int pc; |
---|
185 | 182 | |
---|
186 | 183 | if (ftrace_graph_ignore_func(trace)) |
---|
187 | 184 | return 0; |
---|
.. | .. |
---|
198 | 195 | if (!func_prolog_dec(tr, &data, &flags)) |
---|
199 | 196 | return 0; |
---|
200 | 197 | |
---|
201 | | - trace_ctx = tracing_gen_ctx_flags(flags); |
---|
202 | | - ret = __trace_graph_entry(tr, trace, trace_ctx); |
---|
| 198 | + pc = preempt_count(); |
---|
| 199 | + ret = __trace_graph_entry(tr, trace, flags, pc); |
---|
203 | 200 | atomic_dec(&data->disabled); |
---|
204 | 201 | |
---|
205 | 202 | return ret; |
---|
.. | .. |
---|
210 | 207 | struct trace_array *tr = irqsoff_trace; |
---|
211 | 208 | struct trace_array_cpu *data; |
---|
212 | 209 | unsigned long flags; |
---|
213 | | - unsigned int trace_ctx; |
---|
| 210 | + int pc; |
---|
214 | 211 | |
---|
215 | 212 | ftrace_graph_addr_finish(trace); |
---|
216 | 213 | |
---|
217 | 214 | if (!func_prolog_dec(tr, &data, &flags)) |
---|
218 | 215 | return; |
---|
219 | 216 | |
---|
220 | | - trace_ctx = tracing_gen_ctx_flags(flags); |
---|
221 | | - __trace_graph_return(tr, trace, trace_ctx); |
---|
| 217 | + pc = preempt_count(); |
---|
| 218 | + __trace_graph_return(tr, trace, flags, pc); |
---|
222 | 219 | atomic_dec(&data->disabled); |
---|
223 | 220 | } |
---|
224 | 221 | |
---|
.. | .. |
---|
270 | 267 | static void |
---|
271 | 268 | __trace_function(struct trace_array *tr, |
---|
272 | 269 | unsigned long ip, unsigned long parent_ip, |
---|
273 | | - unsigned int trace_ctx) |
---|
| 270 | + unsigned long flags, int pc) |
---|
274 | 271 | { |
---|
275 | 272 | if (is_graph(tr)) |
---|
276 | | - trace_graph_function(tr, ip, parent_ip, trace_ctx); |
---|
| 273 | + trace_graph_function(tr, ip, parent_ip, flags, pc); |
---|
277 | 274 | else |
---|
278 | | - trace_function(tr, ip, parent_ip, trace_ctx); |
---|
| 275 | + trace_function(tr, ip, parent_ip, flags, pc); |
---|
279 | 276 | } |
---|
280 | 277 | |
---|
281 | 278 | #else |
---|
.. | .. |
---|
325 | 322 | { |
---|
326 | 323 | u64 T0, T1, delta; |
---|
327 | 324 | unsigned long flags; |
---|
328 | | - unsigned int trace_ctx; |
---|
| 325 | + int pc; |
---|
329 | 326 | |
---|
330 | 327 | T0 = data->preempt_timestamp; |
---|
331 | 328 | T1 = ftrace_now(cpu); |
---|
332 | 329 | delta = T1-T0; |
---|
333 | 330 | |
---|
334 | | - trace_ctx = tracing_gen_ctx(); |
---|
| 331 | + local_save_flags(flags); |
---|
| 332 | + |
---|
| 333 | + pc = preempt_count(); |
---|
335 | 334 | |
---|
336 | 335 | if (!report_latency(tr, delta)) |
---|
337 | 336 | goto out; |
---|
.. | .. |
---|
342 | 341 | if (!report_latency(tr, delta)) |
---|
343 | 342 | goto out_unlock; |
---|
344 | 343 | |
---|
345 | | - __trace_function(tr, CALLER_ADDR0, parent_ip, trace_ctx); |
---|
| 344 | + __trace_function(tr, CALLER_ADDR0, parent_ip, flags, pc); |
---|
346 | 345 | /* Skip 5 functions to get to the irq/preempt enable function */ |
---|
347 | | - __trace_stack(tr, trace_ctx, 5); |
---|
| 346 | + __trace_stack(tr, flags, 5, pc); |
---|
348 | 347 | |
---|
349 | 348 | if (data->critical_sequence != max_sequence) |
---|
350 | 349 | goto out_unlock; |
---|
.. | .. |
---|
364 | 363 | out: |
---|
365 | 364 | data->critical_sequence = max_sequence; |
---|
366 | 365 | data->preempt_timestamp = ftrace_now(cpu); |
---|
367 | | - __trace_function(tr, CALLER_ADDR0, parent_ip, trace_ctx); |
---|
| 366 | + __trace_function(tr, CALLER_ADDR0, parent_ip, flags, pc); |
---|
368 | 367 | } |
---|
369 | 368 | |
---|
370 | 369 | static nokprobe_inline void |
---|
371 | | -start_critical_timing(unsigned long ip, unsigned long parent_ip) |
---|
| 370 | +start_critical_timing(unsigned long ip, unsigned long parent_ip, int pc) |
---|
372 | 371 | { |
---|
373 | 372 | int cpu; |
---|
374 | 373 | struct trace_array *tr = irqsoff_trace; |
---|
375 | 374 | struct trace_array_cpu *data; |
---|
| 375 | + unsigned long flags; |
---|
376 | 376 | |
---|
377 | 377 | if (!tracer_enabled || !tracing_is_enabled()) |
---|
378 | 378 | return; |
---|
.. | .. |
---|
393 | 393 | data->preempt_timestamp = ftrace_now(cpu); |
---|
394 | 394 | data->critical_start = parent_ip ? : ip; |
---|
395 | 395 | |
---|
396 | | - __trace_function(tr, ip, parent_ip, tracing_gen_ctx()); |
---|
| 396 | + local_save_flags(flags); |
---|
| 397 | + |
---|
| 398 | + __trace_function(tr, ip, parent_ip, flags, pc); |
---|
397 | 399 | |
---|
398 | 400 | per_cpu(tracing_cpu, cpu) = 1; |
---|
399 | 401 | |
---|
.. | .. |
---|
401 | 403 | } |
---|
402 | 404 | |
---|
403 | 405 | static nokprobe_inline void |
---|
404 | | -stop_critical_timing(unsigned long ip, unsigned long parent_ip) |
---|
| 406 | +stop_critical_timing(unsigned long ip, unsigned long parent_ip, int pc) |
---|
405 | 407 | { |
---|
406 | 408 | int cpu; |
---|
407 | 409 | struct trace_array *tr = irqsoff_trace; |
---|
408 | 410 | struct trace_array_cpu *data; |
---|
409 | | - unsigned int trace_ctx; |
---|
| 411 | + unsigned long flags; |
---|
410 | 412 | |
---|
411 | 413 | cpu = raw_smp_processor_id(); |
---|
412 | 414 | /* Always clear the tracing cpu on stopping the trace */ |
---|
.. | .. |
---|
426 | 428 | |
---|
427 | 429 | atomic_inc(&data->disabled); |
---|
428 | 430 | |
---|
429 | | - trace_ctx = tracing_gen_ctx(); |
---|
430 | | - __trace_function(tr, ip, parent_ip, trace_ctx); |
---|
| 431 | + local_save_flags(flags); |
---|
| 432 | + __trace_function(tr, ip, parent_ip, flags, pc); |
---|
431 | 433 | check_critical_timing(tr, data, parent_ip ? : ip, cpu); |
---|
432 | 434 | data->critical_start = 0; |
---|
433 | 435 | atomic_dec(&data->disabled); |
---|
.. | .. |
---|
436 | 438 | /* start and stop critical timings used to for stoppage (in idle) */ |
---|
437 | 439 | void start_critical_timings(void) |
---|
438 | 440 | { |
---|
439 | | - if (preempt_trace(preempt_count()) || irq_trace()) |
---|
440 | | - start_critical_timing(CALLER_ADDR0, CALLER_ADDR1); |
---|
| 441 | + int pc = preempt_count(); |
---|
| 442 | + |
---|
| 443 | + if (preempt_trace(pc) || irq_trace()) |
---|
| 444 | + start_critical_timing(CALLER_ADDR0, CALLER_ADDR1, pc); |
---|
441 | 445 | } |
---|
442 | 446 | EXPORT_SYMBOL_GPL(start_critical_timings); |
---|
443 | 447 | NOKPROBE_SYMBOL(start_critical_timings); |
---|
444 | 448 | |
---|
445 | 449 | void stop_critical_timings(void) |
---|
446 | 450 | { |
---|
447 | | - if (preempt_trace(preempt_count()) || irq_trace()) |
---|
448 | | - stop_critical_timing(CALLER_ADDR0, CALLER_ADDR1); |
---|
| 451 | + int pc = preempt_count(); |
---|
| 452 | + |
---|
| 453 | + if (preempt_trace(pc) || irq_trace()) |
---|
| 454 | + stop_critical_timing(CALLER_ADDR0, CALLER_ADDR1, pc); |
---|
449 | 455 | } |
---|
450 | 456 | EXPORT_SYMBOL_GPL(stop_critical_timings); |
---|
451 | 457 | NOKPROBE_SYMBOL(stop_critical_timings); |
---|
.. | .. |
---|
607 | 613 | */ |
---|
608 | 614 | void tracer_hardirqs_on(unsigned long a0, unsigned long a1) |
---|
609 | 615 | { |
---|
610 | | - if (!preempt_trace(preempt_count()) && irq_trace()) |
---|
611 | | - stop_critical_timing(a0, a1); |
---|
| 616 | + unsigned int pc = preempt_count(); |
---|
| 617 | + |
---|
| 618 | + if (!preempt_trace(pc) && irq_trace()) |
---|
| 619 | + stop_critical_timing(a0, a1, pc); |
---|
612 | 620 | } |
---|
613 | 621 | NOKPROBE_SYMBOL(tracer_hardirqs_on); |
---|
614 | 622 | |
---|
615 | 623 | void tracer_hardirqs_off(unsigned long a0, unsigned long a1) |
---|
616 | 624 | { |
---|
617 | | - if (!preempt_trace(preempt_count()) && irq_trace()) |
---|
618 | | - start_critical_timing(a0, a1); |
---|
| 625 | + unsigned int pc = preempt_count(); |
---|
| 626 | + |
---|
| 627 | + if (!preempt_trace(pc) && irq_trace()) |
---|
| 628 | + start_critical_timing(a0, a1, pc); |
---|
619 | 629 | } |
---|
620 | 630 | NOKPROBE_SYMBOL(tracer_hardirqs_off); |
---|
621 | 631 | |
---|
.. | .. |
---|
655 | 665 | #ifdef CONFIG_PREEMPT_TRACER |
---|
656 | 666 | void tracer_preempt_on(unsigned long a0, unsigned long a1) |
---|
657 | 667 | { |
---|
658 | | - if (preempt_trace(preempt_count()) && !irq_trace()) |
---|
659 | | - stop_critical_timing(a0, a1); |
---|
| 668 | + int pc = preempt_count(); |
---|
| 669 | + |
---|
| 670 | + if (preempt_trace(pc) && !irq_trace()) |
---|
| 671 | + stop_critical_timing(a0, a1, pc); |
---|
660 | 672 | } |
---|
661 | 673 | |
---|
662 | 674 | void tracer_preempt_off(unsigned long a0, unsigned long a1) |
---|
663 | 675 | { |
---|
664 | | - if (preempt_trace(preempt_count()) && !irq_trace()) |
---|
665 | | - start_critical_timing(a0, a1); |
---|
| 676 | + int pc = preempt_count(); |
---|
| 677 | + |
---|
| 678 | + if (preempt_trace(pc) && !irq_trace()) |
---|
| 679 | + start_critical_timing(a0, a1, pc); |
---|
666 | 680 | } |
---|
667 | 681 | |
---|
668 | 682 | static int preemptoff_tracer_init(struct trace_array *tr) |
---|