diff options
Diffstat (limited to 'kernel/trace/trace_sched_wakeup.c')
| -rw-r--r-- | kernel/trace/trace_sched_wakeup.c | 70 |
1 files changed, 40 insertions, 30 deletions
diff --git a/kernel/trace/trace_sched_wakeup.c b/kernel/trace/trace_sched_wakeup.c index e14da5e97a69..19bd8928ce94 100644 --- a/kernel/trace/trace_sched_wakeup.c +++ b/kernel/trace/trace_sched_wakeup.c | |||
| @@ -130,15 +130,9 @@ wakeup_tracer_call(unsigned long ip, unsigned long parent_ip, | |||
| 130 | atomic_dec(&data->disabled); | 130 | atomic_dec(&data->disabled); |
| 131 | preempt_enable_notrace(); | 131 | preempt_enable_notrace(); |
| 132 | } | 132 | } |
| 133 | |||
| 134 | static struct ftrace_ops trace_ops __read_mostly = | ||
| 135 | { | ||
| 136 | .func = wakeup_tracer_call, | ||
| 137 | .flags = FTRACE_OPS_FL_GLOBAL | FTRACE_OPS_FL_RECURSION_SAFE, | ||
| 138 | }; | ||
| 139 | #endif /* CONFIG_FUNCTION_TRACER */ | 133 | #endif /* CONFIG_FUNCTION_TRACER */ |
| 140 | 134 | ||
| 141 | static int register_wakeup_function(int graph, int set) | 135 | static int register_wakeup_function(struct trace_array *tr, int graph, int set) |
| 142 | { | 136 | { |
| 143 | int ret; | 137 | int ret; |
| 144 | 138 | ||
| @@ -150,7 +144,7 @@ static int register_wakeup_function(int graph, int set) | |||
| 150 | ret = register_ftrace_graph(&wakeup_graph_return, | 144 | ret = register_ftrace_graph(&wakeup_graph_return, |
| 151 | &wakeup_graph_entry); | 145 | &wakeup_graph_entry); |
| 152 | else | 146 | else |
| 153 | ret = register_ftrace_function(&trace_ops); | 147 | ret = register_ftrace_function(tr->ops); |
| 154 | 148 | ||
| 155 | if (!ret) | 149 | if (!ret) |
| 156 | function_enabled = true; | 150 | function_enabled = true; |
| @@ -158,7 +152,7 @@ static int register_wakeup_function(int graph, int set) | |||
| 158 | return ret; | 152 | return ret; |
| 159 | } | 153 | } |
| 160 | 154 | ||
| 161 | static void unregister_wakeup_function(int graph) | 155 | static void unregister_wakeup_function(struct trace_array *tr, int graph) |
| 162 | { | 156 | { |
| 163 | if (!function_enabled) | 157 | if (!function_enabled) |
| 164 | return; | 158 | return; |
| @@ -166,17 +160,17 @@ static void unregister_wakeup_function(int graph) | |||
| 166 | if (graph) | 160 | if (graph) |
| 167 | unregister_ftrace_graph(); | 161 | unregister_ftrace_graph(); |
| 168 | else | 162 | else |
| 169 | unregister_ftrace_function(&trace_ops); | 163 | unregister_ftrace_function(tr->ops); |
| 170 | 164 | ||
| 171 | function_enabled = false; | 165 | function_enabled = false; |
| 172 | } | 166 | } |
| 173 | 167 | ||
| 174 | static void wakeup_function_set(int set) | 168 | static void wakeup_function_set(struct trace_array *tr, int set) |
| 175 | { | 169 | { |
| 176 | if (set) | 170 | if (set) |
| 177 | register_wakeup_function(is_graph(), 1); | 171 | register_wakeup_function(tr, is_graph(), 1); |
| 178 | else | 172 | else |
| 179 | unregister_wakeup_function(is_graph()); | 173 | unregister_wakeup_function(tr, is_graph()); |
| 180 | } | 174 | } |
| 181 | 175 | ||
| 182 | static int wakeup_flag_changed(struct trace_array *tr, u32 mask, int set) | 176 | static int wakeup_flag_changed(struct trace_array *tr, u32 mask, int set) |
| @@ -184,16 +178,16 @@ static int wakeup_flag_changed(struct trace_array *tr, u32 mask, int set) | |||
| 184 | struct tracer *tracer = tr->current_trace; | 178 | struct tracer *tracer = tr->current_trace; |
| 185 | 179 | ||
| 186 | if (mask & TRACE_ITER_FUNCTION) | 180 | if (mask & TRACE_ITER_FUNCTION) |
| 187 | wakeup_function_set(set); | 181 | wakeup_function_set(tr, set); |
| 188 | 182 | ||
| 189 | return trace_keep_overwrite(tracer, mask, set); | 183 | return trace_keep_overwrite(tracer, mask, set); |
| 190 | } | 184 | } |
| 191 | 185 | ||
| 192 | static int start_func_tracer(int graph) | 186 | static int start_func_tracer(struct trace_array *tr, int graph) |
| 193 | { | 187 | { |
| 194 | int ret; | 188 | int ret; |
| 195 | 189 | ||
| 196 | ret = register_wakeup_function(graph, 0); | 190 | ret = register_wakeup_function(tr, graph, 0); |
| 197 | 191 | ||
| 198 | if (!ret && tracing_is_enabled()) | 192 | if (!ret && tracing_is_enabled()) |
| 199 | tracer_enabled = 1; | 193 | tracer_enabled = 1; |
| @@ -203,11 +197,11 @@ static int start_func_tracer(int graph) | |||
| 203 | return ret; | 197 | return ret; |
| 204 | } | 198 | } |
| 205 | 199 | ||
| 206 | static void stop_func_tracer(int graph) | 200 | static void stop_func_tracer(struct trace_array *tr, int graph) |
| 207 | { | 201 | { |
| 208 | tracer_enabled = 0; | 202 | tracer_enabled = 0; |
| 209 | 203 | ||
| 210 | unregister_wakeup_function(graph); | 204 | unregister_wakeup_function(tr, graph); |
| 211 | } | 205 | } |
| 212 | 206 | ||
| 213 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 207 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
| @@ -221,12 +215,12 @@ wakeup_set_flag(struct trace_array *tr, u32 old_flags, u32 bit, int set) | |||
| 221 | if (!(is_graph() ^ set)) | 215 | if (!(is_graph() ^ set)) |
| 222 | return 0; | 216 | return 0; |
| 223 | 217 | ||
| 224 | stop_func_tracer(!set); | 218 | stop_func_tracer(tr, !set); |
| 225 | 219 | ||
| 226 | wakeup_reset(wakeup_trace); | 220 | wakeup_reset(wakeup_trace); |
| 227 | tracing_max_latency = 0; | 221 | tr->max_latency = 0; |
| 228 | 222 | ||
| 229 | return start_func_tracer(set); | 223 | return start_func_tracer(tr, set); |
| 230 | } | 224 | } |
| 231 | 225 | ||
| 232 | static int wakeup_graph_entry(struct ftrace_graph_ent *trace) | 226 | static int wakeup_graph_entry(struct ftrace_graph_ent *trace) |
| @@ -350,13 +344,13 @@ static void wakeup_print_header(struct seq_file *s) | |||
| 350 | /* | 344 | /* |
| 351 | * Should this new latency be reported/recorded? | 345 | * Should this new latency be reported/recorded? |
| 352 | */ | 346 | */ |
| 353 | static int report_latency(cycle_t delta) | 347 | static int report_latency(struct trace_array *tr, cycle_t delta) |
| 354 | { | 348 | { |
| 355 | if (tracing_thresh) { | 349 | if (tracing_thresh) { |
| 356 | if (delta < tracing_thresh) | 350 | if (delta < tracing_thresh) |
| 357 | return 0; | 351 | return 0; |
| 358 | } else { | 352 | } else { |
| 359 | if (delta <= tracing_max_latency) | 353 | if (delta <= tr->max_latency) |
| 360 | return 0; | 354 | return 0; |
| 361 | } | 355 | } |
| 362 | return 1; | 356 | return 1; |
| @@ -424,11 +418,11 @@ probe_wakeup_sched_switch(void *ignore, | |||
| 424 | T1 = ftrace_now(cpu); | 418 | T1 = ftrace_now(cpu); |
| 425 | delta = T1-T0; | 419 | delta = T1-T0; |
| 426 | 420 | ||
| 427 | if (!report_latency(delta)) | 421 | if (!report_latency(wakeup_trace, delta)) |
| 428 | goto out_unlock; | 422 | goto out_unlock; |
| 429 | 423 | ||
| 430 | if (likely(!is_tracing_stopped())) { | 424 | if (likely(!is_tracing_stopped())) { |
| 431 | tracing_max_latency = delta; | 425 | wakeup_trace->max_latency = delta; |
| 432 | update_max_tr(wakeup_trace, wakeup_task, wakeup_cpu); | 426 | update_max_tr(wakeup_trace, wakeup_task, wakeup_cpu); |
| 433 | } | 427 | } |
| 434 | 428 | ||
| @@ -587,7 +581,7 @@ static void start_wakeup_tracer(struct trace_array *tr) | |||
| 587 | */ | 581 | */ |
| 588 | smp_wmb(); | 582 | smp_wmb(); |
| 589 | 583 | ||
| 590 | if (start_func_tracer(is_graph())) | 584 | if (start_func_tracer(tr, is_graph())) |
| 591 | printk(KERN_ERR "failed to start wakeup tracer\n"); | 585 | printk(KERN_ERR "failed to start wakeup tracer\n"); |
| 592 | 586 | ||
| 593 | return; | 587 | return; |
| @@ -600,13 +594,15 @@ fail_deprobe: | |||
| 600 | static void stop_wakeup_tracer(struct trace_array *tr) | 594 | static void stop_wakeup_tracer(struct trace_array *tr) |
| 601 | { | 595 | { |
| 602 | tracer_enabled = 0; | 596 | tracer_enabled = 0; |
| 603 | stop_func_tracer(is_graph()); | 597 | stop_func_tracer(tr, is_graph()); |
| 604 | unregister_trace_sched_switch(probe_wakeup_sched_switch, NULL); | 598 | unregister_trace_sched_switch(probe_wakeup_sched_switch, NULL); |
| 605 | unregister_trace_sched_wakeup_new(probe_wakeup, NULL); | 599 | unregister_trace_sched_wakeup_new(probe_wakeup, NULL); |
| 606 | unregister_trace_sched_wakeup(probe_wakeup, NULL); | 600 | unregister_trace_sched_wakeup(probe_wakeup, NULL); |
| 607 | unregister_trace_sched_migrate_task(probe_wakeup_migrate_task, NULL); | 601 | unregister_trace_sched_migrate_task(probe_wakeup_migrate_task, NULL); |
| 608 | } | 602 | } |
| 609 | 603 | ||
| 604 | static bool wakeup_busy; | ||
| 605 | |||
| 610 | static int __wakeup_tracer_init(struct trace_array *tr) | 606 | static int __wakeup_tracer_init(struct trace_array *tr) |
| 611 | { | 607 | { |
| 612 | save_flags = trace_flags; | 608 | save_flags = trace_flags; |
| @@ -615,14 +611,20 @@ static int __wakeup_tracer_init(struct trace_array *tr) | |||
| 615 | set_tracer_flag(tr, TRACE_ITER_OVERWRITE, 1); | 611 | set_tracer_flag(tr, TRACE_ITER_OVERWRITE, 1); |
| 616 | set_tracer_flag(tr, TRACE_ITER_LATENCY_FMT, 1); | 612 | set_tracer_flag(tr, TRACE_ITER_LATENCY_FMT, 1); |
| 617 | 613 | ||
| 618 | tracing_max_latency = 0; | 614 | tr->max_latency = 0; |
| 619 | wakeup_trace = tr; | 615 | wakeup_trace = tr; |
| 616 | ftrace_init_array_ops(tr, wakeup_tracer_call); | ||
| 620 | start_wakeup_tracer(tr); | 617 | start_wakeup_tracer(tr); |
| 618 | |||
| 619 | wakeup_busy = true; | ||
| 621 | return 0; | 620 | return 0; |
| 622 | } | 621 | } |
| 623 | 622 | ||
| 624 | static int wakeup_tracer_init(struct trace_array *tr) | 623 | static int wakeup_tracer_init(struct trace_array *tr) |
| 625 | { | 624 | { |
| 625 | if (wakeup_busy) | ||
| 626 | return -EBUSY; | ||
| 627 | |||
| 626 | wakeup_dl = 0; | 628 | wakeup_dl = 0; |
| 627 | wakeup_rt = 0; | 629 | wakeup_rt = 0; |
| 628 | return __wakeup_tracer_init(tr); | 630 | return __wakeup_tracer_init(tr); |
| @@ -630,6 +632,9 @@ static int wakeup_tracer_init(struct trace_array *tr) | |||
| 630 | 632 | ||
| 631 | static int wakeup_rt_tracer_init(struct trace_array *tr) | 633 | static int wakeup_rt_tracer_init(struct trace_array *tr) |
| 632 | { | 634 | { |
| 635 | if (wakeup_busy) | ||
| 636 | return -EBUSY; | ||
| 637 | |||
| 633 | wakeup_dl = 0; | 638 | wakeup_dl = 0; |
| 634 | wakeup_rt = 1; | 639 | wakeup_rt = 1; |
| 635 | return __wakeup_tracer_init(tr); | 640 | return __wakeup_tracer_init(tr); |
| @@ -637,6 +642,9 @@ static int wakeup_rt_tracer_init(struct trace_array *tr) | |||
| 637 | 642 | ||
| 638 | static int wakeup_dl_tracer_init(struct trace_array *tr) | 643 | static int wakeup_dl_tracer_init(struct trace_array *tr) |
| 639 | { | 644 | { |
| 645 | if (wakeup_busy) | ||
| 646 | return -EBUSY; | ||
| 647 | |||
| 640 | wakeup_dl = 1; | 648 | wakeup_dl = 1; |
| 641 | wakeup_rt = 0; | 649 | wakeup_rt = 0; |
| 642 | return __wakeup_tracer_init(tr); | 650 | return __wakeup_tracer_init(tr); |
| @@ -653,6 +661,8 @@ static void wakeup_tracer_reset(struct trace_array *tr) | |||
| 653 | 661 | ||
| 654 | set_tracer_flag(tr, TRACE_ITER_LATENCY_FMT, lat_flag); | 662 | set_tracer_flag(tr, TRACE_ITER_LATENCY_FMT, lat_flag); |
| 655 | set_tracer_flag(tr, TRACE_ITER_OVERWRITE, overwrite_flag); | 663 | set_tracer_flag(tr, TRACE_ITER_OVERWRITE, overwrite_flag); |
| 664 | ftrace_reset_array_ops(tr); | ||
| 665 | wakeup_busy = false; | ||
| 656 | } | 666 | } |
| 657 | 667 | ||
| 658 | static void wakeup_tracer_start(struct trace_array *tr) | 668 | static void wakeup_tracer_start(struct trace_array *tr) |
| @@ -684,6 +694,7 @@ static struct tracer wakeup_tracer __read_mostly = | |||
| 684 | #endif | 694 | #endif |
| 685 | .open = wakeup_trace_open, | 695 | .open = wakeup_trace_open, |
| 686 | .close = wakeup_trace_close, | 696 | .close = wakeup_trace_close, |
| 697 | .allow_instances = true, | ||
| 687 | .use_max_tr = true, | 698 | .use_max_tr = true, |
| 688 | }; | 699 | }; |
| 689 | 700 | ||
| @@ -694,7 +705,6 @@ static struct tracer wakeup_rt_tracer __read_mostly = | |||
| 694 | .reset = wakeup_tracer_reset, | 705 | .reset = wakeup_tracer_reset, |
| 695 | .start = wakeup_tracer_start, | 706 | .start = wakeup_tracer_start, |
| 696 | .stop = wakeup_tracer_stop, | 707 | .stop = wakeup_tracer_stop, |
| 697 | .wait_pipe = poll_wait_pipe, | ||
| 698 | .print_max = true, | 708 | .print_max = true, |
| 699 | .print_header = wakeup_print_header, | 709 | .print_header = wakeup_print_header, |
| 700 | .print_line = wakeup_print_line, | 710 | .print_line = wakeup_print_line, |
| @@ -706,6 +716,7 @@ static struct tracer wakeup_rt_tracer __read_mostly = | |||
| 706 | #endif | 716 | #endif |
| 707 | .open = wakeup_trace_open, | 717 | .open = wakeup_trace_open, |
| 708 | .close = wakeup_trace_close, | 718 | .close = wakeup_trace_close, |
| 719 | .allow_instances = true, | ||
| 709 | .use_max_tr = true, | 720 | .use_max_tr = true, |
| 710 | }; | 721 | }; |
| 711 | 722 | ||
| @@ -716,7 +727,6 @@ static struct tracer wakeup_dl_tracer __read_mostly = | |||
| 716 | .reset = wakeup_tracer_reset, | 727 | .reset = wakeup_tracer_reset, |
| 717 | .start = wakeup_tracer_start, | 728 | .start = wakeup_tracer_start, |
| 718 | .stop = wakeup_tracer_stop, | 729 | .stop = wakeup_tracer_stop, |
| 719 | .wait_pipe = poll_wait_pipe, | ||
| 720 | .print_max = true, | 730 | .print_max = true, |
| 721 | .print_header = wakeup_print_header, | 731 | .print_header = wakeup_print_header, |
| 722 | .print_line = wakeup_print_line, | 732 | .print_line = wakeup_print_line, |
