1 /* 2 * 3 * Function graph tracer. 4 * Copyright (c) 2008-2009 Frederic Weisbecker <fweisbec@gmail.com> 5 * Mostly borrowed from function tracer which 6 * is Copyright (c) Steven Rostedt <srostedt@redhat.com> 7 * 8 */ 9 #include <linux/debugfs.h> 10 #include <linux/uaccess.h> 11 #include <linux/ftrace.h> 12 #include <linux/slab.h> 13 #include <linux/fs.h> 14 15 #include "trace.h" 16 #include "trace_output.h" 17 18 static bool kill_ftrace_graph; 19 20 /** 21 * ftrace_graph_is_dead - returns true if ftrace_graph_stop() was called 22 * 23 * ftrace_graph_stop() is called when a severe error is detected in 24 * the function graph tracing. This function is called by the critical 25 * paths of function graph to keep those paths from doing any more harm. 26 */ 27 bool ftrace_graph_is_dead(void) 28 { 29 return kill_ftrace_graph; 30 } 31 32 /** 33 * ftrace_graph_stop - set to permanently disable function graph tracincg 34 * 35 * In case of an error int function graph tracing, this is called 36 * to try to keep function graph tracing from causing any more harm. 37 * Usually this is pretty severe and this is called to try to at least 38 * get a warning out to the user. 39 */ 40 void ftrace_graph_stop(void) 41 { 42 kill_ftrace_graph = true; 43 } 44 45 /* When set, irq functions will be ignored */ 46 static int ftrace_graph_skip_irqs; 47 48 struct fgraph_cpu_data { 49 pid_t last_pid; 50 int depth; 51 int depth_irq; 52 int ignore; 53 unsigned long enter_funcs[FTRACE_RETFUNC_DEPTH]; 54 }; 55 56 struct fgraph_data { 57 struct fgraph_cpu_data __percpu *cpu_data; 58 59 /* Place to preserve last processed entry. */ 60 struct ftrace_graph_ent_entry ent; 61 struct ftrace_graph_ret_entry ret; 62 int failed; 63 int cpu; 64 }; 65 66 #define TRACE_GRAPH_INDENT 2 67 68 static unsigned int max_depth; 69 70 static struct tracer_opt trace_opts[] = { 71 /* Display overruns? (for self-debug purpose) */ 72 { TRACER_OPT(funcgraph-overrun, TRACE_GRAPH_PRINT_OVERRUN) }, 73 /* Display CPU ? */ 74 { TRACER_OPT(funcgraph-cpu, TRACE_GRAPH_PRINT_CPU) }, 75 /* Display Overhead ? */ 76 { TRACER_OPT(funcgraph-overhead, TRACE_GRAPH_PRINT_OVERHEAD) }, 77 /* Display proc name/pid */ 78 { TRACER_OPT(funcgraph-proc, TRACE_GRAPH_PRINT_PROC) }, 79 /* Display duration of execution */ 80 { TRACER_OPT(funcgraph-duration, TRACE_GRAPH_PRINT_DURATION) }, 81 /* Display absolute time of an entry */ 82 { TRACER_OPT(funcgraph-abstime, TRACE_GRAPH_PRINT_ABS_TIME) }, 83 /* Display interrupts */ 84 { TRACER_OPT(funcgraph-irqs, TRACE_GRAPH_PRINT_IRQS) }, 85 /* Display function name after trailing } */ 86 { TRACER_OPT(funcgraph-tail, TRACE_GRAPH_PRINT_TAIL) }, 87 { } /* Empty entry */ 88 }; 89 90 static struct tracer_flags tracer_flags = { 91 /* Don't display overruns, proc, or tail by default */ 92 .val = TRACE_GRAPH_PRINT_CPU | TRACE_GRAPH_PRINT_OVERHEAD | 93 TRACE_GRAPH_PRINT_DURATION | TRACE_GRAPH_PRINT_IRQS, 94 .opts = trace_opts 95 }; 96 97 static struct trace_array *graph_array; 98 99 /* 100 * DURATION column is being also used to display IRQ signs, 101 * following values are used by print_graph_irq and others 102 * to fill in space into DURATION column. 103 */ 104 enum { 105 FLAGS_FILL_FULL = 1 << TRACE_GRAPH_PRINT_FILL_SHIFT, 106 FLAGS_FILL_START = 2 << TRACE_GRAPH_PRINT_FILL_SHIFT, 107 FLAGS_FILL_END = 3 << TRACE_GRAPH_PRINT_FILL_SHIFT, 108 }; 109 110 static void 111 print_graph_duration(unsigned long long duration, struct trace_seq *s, 112 u32 flags); 113 114 /* Add a function return address to the trace stack on thread info.*/ 115 int 116 ftrace_push_return_trace(unsigned long ret, unsigned long func, int *depth, 117 unsigned long frame_pointer) 118 { 119 unsigned long long calltime; 120 int index; 121 122 if (unlikely(ftrace_graph_is_dead())) 123 return -EBUSY; 124 125 if (!current->ret_stack) 126 return -EBUSY; 127 128 /* 129 * We must make sure the ret_stack is tested before we read 130 * anything else. 131 */ 132 smp_rmb(); 133 134 /* The return trace stack is full */ 135 if (current->curr_ret_stack == FTRACE_RETFUNC_DEPTH - 1) { 136 atomic_inc(¤t->trace_overrun); 137 return -EBUSY; 138 } 139 140 /* 141 * The curr_ret_stack is an index to ftrace return stack of 142 * current task. Its value should be in [0, FTRACE_RETFUNC_ 143 * DEPTH) when the function graph tracer is used. To support 144 * filtering out specific functions, it makes the index 145 * negative by subtracting huge value (FTRACE_NOTRACE_DEPTH) 146 * so when it sees a negative index the ftrace will ignore 147 * the record. And the index gets recovered when returning 148 * from the filtered function by adding the FTRACE_NOTRACE_ 149 * DEPTH and then it'll continue to record functions normally. 150 * 151 * The curr_ret_stack is initialized to -1 and get increased 152 * in this function. So it can be less than -1 only if it was 153 * filtered out via ftrace_graph_notrace_addr() which can be 154 * set from set_graph_notrace file in debugfs by user. 155 */ 156 if (current->curr_ret_stack < -1) 157 return -EBUSY; 158 159 calltime = trace_clock_local(); 160 161 index = ++current->curr_ret_stack; 162 if (ftrace_graph_notrace_addr(func)) 163 current->curr_ret_stack -= FTRACE_NOTRACE_DEPTH; 164 barrier(); 165 current->ret_stack[index].ret = ret; 166 current->ret_stack[index].func = func; 167 current->ret_stack[index].calltime = calltime; 168 current->ret_stack[index].subtime = 0; 169 current->ret_stack[index].fp = frame_pointer; 170 *depth = current->curr_ret_stack; 171 172 return 0; 173 } 174 175 /* Retrieve a function return address to the trace stack on thread info.*/ 176 static void 177 ftrace_pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret, 178 unsigned long frame_pointer) 179 { 180 int index; 181 182 index = current->curr_ret_stack; 183 184 /* 185 * A negative index here means that it's just returned from a 186 * notrace'd function. Recover index to get an original 187 * return address. See ftrace_push_return_trace(). 188 * 189 * TODO: Need to check whether the stack gets corrupted. 190 */ 191 if (index < 0) 192 index += FTRACE_NOTRACE_DEPTH; 193 194 if (unlikely(index < 0 || index >= FTRACE_RETFUNC_DEPTH)) { 195 ftrace_graph_stop(); 196 WARN_ON(1); 197 /* Might as well panic, otherwise we have no where to go */ 198 *ret = (unsigned long)panic; 199 return; 200 } 201 202 #if defined(CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST) && !defined(CC_USING_FENTRY) 203 /* 204 * The arch may choose to record the frame pointer used 205 * and check it here to make sure that it is what we expect it 206 * to be. If gcc does not set the place holder of the return 207 * address in the frame pointer, and does a copy instead, then 208 * the function graph trace will fail. This test detects this 209 * case. 210 * 211 * Currently, x86_32 with optimize for size (-Os) makes the latest 212 * gcc do the above. 213 * 214 * Note, -mfentry does not use frame pointers, and this test 215 * is not needed if CC_USING_FENTRY is set. 216 */ 217 if (unlikely(current->ret_stack[index].fp != frame_pointer)) { 218 ftrace_graph_stop(); 219 WARN(1, "Bad frame pointer: expected %lx, received %lx\n" 220 " from func %ps return to %lx\n", 221 current->ret_stack[index].fp, 222 frame_pointer, 223 (void *)current->ret_stack[index].func, 224 current->ret_stack[index].ret); 225 *ret = (unsigned long)panic; 226 return; 227 } 228 #endif 229 230 *ret = current->ret_stack[index].ret; 231 trace->func = current->ret_stack[index].func; 232 trace->calltime = current->ret_stack[index].calltime; 233 trace->overrun = atomic_read(¤t->trace_overrun); 234 trace->depth = index; 235 } 236 237 /* 238 * Send the trace to the ring-buffer. 239 * @return the original return address. 240 */ 241 unsigned long ftrace_return_to_handler(unsigned long frame_pointer) 242 { 243 struct ftrace_graph_ret trace; 244 unsigned long ret; 245 246 ftrace_pop_return_trace(&trace, &ret, frame_pointer); 247 trace.rettime = trace_clock_local(); 248 barrier(); 249 current->curr_ret_stack--; 250 /* 251 * The curr_ret_stack can be less than -1 only if it was 252 * filtered out and it's about to return from the function. 253 * Recover the index and continue to trace normal functions. 254 */ 255 if (current->curr_ret_stack < -1) { 256 current->curr_ret_stack += FTRACE_NOTRACE_DEPTH; 257 return ret; 258 } 259 260 /* 261 * The trace should run after decrementing the ret counter 262 * in case an interrupt were to come in. We don't want to 263 * lose the interrupt if max_depth is set. 264 */ 265 ftrace_graph_return(&trace); 266 267 if (unlikely(!ret)) { 268 ftrace_graph_stop(); 269 WARN_ON(1); 270 /* Might as well panic. What else to do? */ 271 ret = (unsigned long)panic; 272 } 273 274 return ret; 275 } 276 277 int __trace_graph_entry(struct trace_array *tr, 278 struct ftrace_graph_ent *trace, 279 unsigned long flags, 280 int pc) 281 { 282 struct ftrace_event_call *call = &event_funcgraph_entry; 283 struct ring_buffer_event *event; 284 struct ring_buffer *buffer = tr->trace_buffer.buffer; 285 struct ftrace_graph_ent_entry *entry; 286 287 if (unlikely(__this_cpu_read(ftrace_cpu_disabled))) 288 return 0; 289 290 event = trace_buffer_lock_reserve(buffer, TRACE_GRAPH_ENT, 291 sizeof(*entry), flags, pc); 292 if (!event) 293 return 0; 294 entry = ring_buffer_event_data(event); 295 entry->graph_ent = *trace; 296 if (!call_filter_check_discard(call, entry, buffer, event)) 297 __buffer_unlock_commit(buffer, event); 298 299 return 1; 300 } 301 302 static inline int ftrace_graph_ignore_irqs(void) 303 { 304 if (!ftrace_graph_skip_irqs || trace_recursion_test(TRACE_IRQ_BIT)) 305 return 0; 306 307 return in_irq(); 308 } 309 310 int trace_graph_entry(struct ftrace_graph_ent *trace) 311 { 312 struct trace_array *tr = graph_array; 313 struct trace_array_cpu *data; 314 unsigned long flags; 315 long disabled; 316 int ret; 317 int cpu; 318 int pc; 319 320 if (!ftrace_trace_task(current)) 321 return 0; 322 323 /* trace it when it is-nested-in or is a function enabled. */ 324 if ((!(trace->depth || ftrace_graph_addr(trace->func)) || 325 ftrace_graph_ignore_irqs()) || (trace->depth < 0) || 326 (max_depth && trace->depth >= max_depth)) 327 return 0; 328 329 /* 330 * Do not trace a function if it's filtered by set_graph_notrace. 331 * Make the index of ret stack negative to indicate that it should 332 * ignore further functions. But it needs its own ret stack entry 333 * to recover the original index in order to continue tracing after 334 * returning from the function. 335 */ 336 if (ftrace_graph_notrace_addr(trace->func)) 337 return 1; 338 339 local_irq_save(flags); 340 cpu = raw_smp_processor_id(); 341 data = per_cpu_ptr(tr->trace_buffer.data, cpu); 342 disabled = atomic_inc_return(&data->disabled); 343 if (likely(disabled == 1)) { 344 pc = preempt_count(); 345 ret = __trace_graph_entry(tr, trace, flags, pc); 346 } else { 347 ret = 0; 348 } 349 350 atomic_dec(&data->disabled); 351 local_irq_restore(flags); 352 353 return ret; 354 } 355 356 static int trace_graph_thresh_entry(struct ftrace_graph_ent *trace) 357 { 358 if (tracing_thresh) 359 return 1; 360 else 361 return trace_graph_entry(trace); 362 } 363 364 static void 365 __trace_graph_function(struct trace_array *tr, 366 unsigned long ip, unsigned long flags, int pc) 367 { 368 u64 time = trace_clock_local(); 369 struct ftrace_graph_ent ent = { 370 .func = ip, 371 .depth = 0, 372 }; 373 struct ftrace_graph_ret ret = { 374 .func = ip, 375 .depth = 0, 376 .calltime = time, 377 .rettime = time, 378 }; 379 380 __trace_graph_entry(tr, &ent, flags, pc); 381 __trace_graph_return(tr, &ret, flags, pc); 382 } 383 384 void 385 trace_graph_function(struct trace_array *tr, 386 unsigned long ip, unsigned long parent_ip, 387 unsigned long flags, int pc) 388 { 389 __trace_graph_function(tr, ip, flags, pc); 390 } 391 392 void __trace_graph_return(struct trace_array *tr, 393 struct ftrace_graph_ret *trace, 394 unsigned long flags, 395 int pc) 396 { 397 struct ftrace_event_call *call = &event_funcgraph_exit; 398 struct ring_buffer_event *event; 399 struct ring_buffer *buffer = tr->trace_buffer.buffer; 400 struct ftrace_graph_ret_entry *entry; 401 402 if (unlikely(__this_cpu_read(ftrace_cpu_disabled))) 403 return; 404 405 event = trace_buffer_lock_reserve(buffer, TRACE_GRAPH_RET, 406 sizeof(*entry), flags, pc); 407 if (!event) 408 return; 409 entry = ring_buffer_event_data(event); 410 entry->ret = *trace; 411 if (!call_filter_check_discard(call, entry, buffer, event)) 412 __buffer_unlock_commit(buffer, event); 413 } 414 415 void trace_graph_return(struct ftrace_graph_ret *trace) 416 { 417 struct trace_array *tr = graph_array; 418 struct trace_array_cpu *data; 419 unsigned long flags; 420 long disabled; 421 int cpu; 422 int pc; 423 424 local_irq_save(flags); 425 cpu = raw_smp_processor_id(); 426 data = per_cpu_ptr(tr->trace_buffer.data, cpu); 427 disabled = atomic_inc_return(&data->disabled); 428 if (likely(disabled == 1)) { 429 pc = preempt_count(); 430 __trace_graph_return(tr, trace, flags, pc); 431 } 432 atomic_dec(&data->disabled); 433 local_irq_restore(flags); 434 } 435 436 void set_graph_array(struct trace_array *tr) 437 { 438 graph_array = tr; 439 440 /* Make graph_array visible before we start tracing */ 441 442 smp_mb(); 443 } 444 445 static void trace_graph_thresh_return(struct ftrace_graph_ret *trace) 446 { 447 if (tracing_thresh && 448 (trace->rettime - trace->calltime < tracing_thresh)) 449 return; 450 else 451 trace_graph_return(trace); 452 } 453 454 static int graph_trace_init(struct trace_array *tr) 455 { 456 int ret; 457 458 set_graph_array(tr); 459 if (tracing_thresh) 460 ret = register_ftrace_graph(&trace_graph_thresh_return, 461 &trace_graph_thresh_entry); 462 else 463 ret = register_ftrace_graph(&trace_graph_return, 464 &trace_graph_entry); 465 if (ret) 466 return ret; 467 tracing_start_cmdline_record(); 468 469 return 0; 470 } 471 472 static void graph_trace_reset(struct trace_array *tr) 473 { 474 tracing_stop_cmdline_record(); 475 unregister_ftrace_graph(); 476 } 477 478 static int graph_trace_update_thresh(struct trace_array *tr) 479 { 480 graph_trace_reset(tr); 481 return graph_trace_init(tr); 482 } 483 484 static int max_bytes_for_cpu; 485 486 static void print_graph_cpu(struct trace_seq *s, int cpu) 487 { 488 /* 489 * Start with a space character - to make it stand out 490 * to the right a bit when trace output is pasted into 491 * email: 492 */ 493 trace_seq_printf(s, " %*d) ", max_bytes_for_cpu, cpu); 494 } 495 496 #define TRACE_GRAPH_PROCINFO_LENGTH 14 497 498 static void print_graph_proc(struct trace_seq *s, pid_t pid) 499 { 500 char comm[TASK_COMM_LEN]; 501 /* sign + log10(MAX_INT) + '\0' */ 502 char pid_str[11]; 503 int spaces = 0; 504 int len; 505 int i; 506 507 trace_find_cmdline(pid, comm); 508 comm[7] = '\0'; 509 sprintf(pid_str, "%d", pid); 510 511 /* 1 stands for the "-" character */ 512 len = strlen(comm) + strlen(pid_str) + 1; 513 514 if (len < TRACE_GRAPH_PROCINFO_LENGTH) 515 spaces = TRACE_GRAPH_PROCINFO_LENGTH - len; 516 517 /* First spaces to align center */ 518 for (i = 0; i < spaces / 2; i++) 519 trace_seq_putc(s, ' '); 520 521 trace_seq_printf(s, "%s-%s", comm, pid_str); 522 523 /* Last spaces to align center */ 524 for (i = 0; i < spaces - (spaces / 2); i++) 525 trace_seq_putc(s, ' '); 526 } 527 528 529 static void print_graph_lat_fmt(struct trace_seq *s, struct trace_entry *entry) 530 { 531 trace_seq_putc(s, ' '); 532 trace_print_lat_fmt(s, entry); 533 } 534 535 /* If the pid changed since the last trace, output this event */ 536 static void 537 verif_pid(struct trace_seq *s, pid_t pid, int cpu, struct fgraph_data *data) 538 { 539 pid_t prev_pid; 540 pid_t *last_pid; 541 542 if (!data) 543 return; 544 545 last_pid = &(per_cpu_ptr(data->cpu_data, cpu)->last_pid); 546 547 if (*last_pid == pid) 548 return; 549 550 prev_pid = *last_pid; 551 *last_pid = pid; 552 553 if (prev_pid == -1) 554 return; 555 /* 556 * Context-switch trace line: 557 558 ------------------------------------------ 559 | 1) migration/0--1 => sshd-1755 560 ------------------------------------------ 561 562 */ 563 trace_seq_puts(s, " ------------------------------------------\n"); 564 print_graph_cpu(s, cpu); 565 print_graph_proc(s, prev_pid); 566 trace_seq_puts(s, " => "); 567 print_graph_proc(s, pid); 568 trace_seq_puts(s, "\n ------------------------------------------\n\n"); 569 } 570 571 static struct ftrace_graph_ret_entry * 572 get_return_for_leaf(struct trace_iterator *iter, 573 struct ftrace_graph_ent_entry *curr) 574 { 575 struct fgraph_data *data = iter->private; 576 struct ring_buffer_iter *ring_iter = NULL; 577 struct ring_buffer_event *event; 578 struct ftrace_graph_ret_entry *next; 579 580 /* 581 * If the previous output failed to write to the seq buffer, 582 * then we just reuse the data from before. 583 */ 584 if (data && data->failed) { 585 curr = &data->ent; 586 next = &data->ret; 587 } else { 588 589 ring_iter = trace_buffer_iter(iter, iter->cpu); 590 591 /* First peek to compare current entry and the next one */ 592 if (ring_iter) 593 event = ring_buffer_iter_peek(ring_iter, NULL); 594 else { 595 /* 596 * We need to consume the current entry to see 597 * the next one. 598 */ 599 ring_buffer_consume(iter->trace_buffer->buffer, iter->cpu, 600 NULL, NULL); 601 event = ring_buffer_peek(iter->trace_buffer->buffer, iter->cpu, 602 NULL, NULL); 603 } 604 605 if (!event) 606 return NULL; 607 608 next = ring_buffer_event_data(event); 609 610 if (data) { 611 /* 612 * Save current and next entries for later reference 613 * if the output fails. 614 */ 615 data->ent = *curr; 616 /* 617 * If the next event is not a return type, then 618 * we only care about what type it is. Otherwise we can 619 * safely copy the entire event. 620 */ 621 if (next->ent.type == TRACE_GRAPH_RET) 622 data->ret = *next; 623 else 624 data->ret.ent.type = next->ent.type; 625 } 626 } 627 628 if (next->ent.type != TRACE_GRAPH_RET) 629 return NULL; 630 631 if (curr->ent.pid != next->ent.pid || 632 curr->graph_ent.func != next->ret.func) 633 return NULL; 634 635 /* this is a leaf, now advance the iterator */ 636 if (ring_iter) 637 ring_buffer_read(ring_iter, NULL); 638 639 return next; 640 } 641 642 static void print_graph_abs_time(u64 t, struct trace_seq *s) 643 { 644 unsigned long usecs_rem; 645 646 usecs_rem = do_div(t, NSEC_PER_SEC); 647 usecs_rem /= 1000; 648 649 trace_seq_printf(s, "%5lu.%06lu | ", 650 (unsigned long)t, usecs_rem); 651 } 652 653 static void 654 print_graph_irq(struct trace_iterator *iter, unsigned long addr, 655 enum trace_type type, int cpu, pid_t pid, u32 flags) 656 { 657 struct trace_seq *s = &iter->seq; 658 struct trace_entry *ent = iter->ent; 659 660 if (addr < (unsigned long)__irqentry_text_start || 661 addr >= (unsigned long)__irqentry_text_end) 662 return; 663 664 if (trace_flags & TRACE_ITER_CONTEXT_INFO) { 665 /* Absolute time */ 666 if (flags & TRACE_GRAPH_PRINT_ABS_TIME) 667 print_graph_abs_time(iter->ts, s); 668 669 /* Cpu */ 670 if (flags & TRACE_GRAPH_PRINT_CPU) 671 print_graph_cpu(s, cpu); 672 673 /* Proc */ 674 if (flags & TRACE_GRAPH_PRINT_PROC) { 675 print_graph_proc(s, pid); 676 trace_seq_puts(s, " | "); 677 } 678 679 /* Latency format */ 680 if (trace_flags & TRACE_ITER_LATENCY_FMT) 681 print_graph_lat_fmt(s, ent); 682 } 683 684 /* No overhead */ 685 print_graph_duration(0, s, flags | FLAGS_FILL_START); 686 687 if (type == TRACE_GRAPH_ENT) 688 trace_seq_puts(s, "==========>"); 689 else 690 trace_seq_puts(s, "<=========="); 691 692 print_graph_duration(0, s, flags | FLAGS_FILL_END); 693 trace_seq_putc(s, '\n'); 694 } 695 696 void 697 trace_print_graph_duration(unsigned long long duration, struct trace_seq *s) 698 { 699 unsigned long nsecs_rem = do_div(duration, 1000); 700 /* log10(ULONG_MAX) + '\0' */ 701 char usecs_str[21]; 702 char nsecs_str[5]; 703 int len; 704 int i; 705 706 sprintf(usecs_str, "%lu", (unsigned long) duration); 707 708 /* Print msecs */ 709 trace_seq_printf(s, "%s", usecs_str); 710 711 len = strlen(usecs_str); 712 713 /* Print nsecs (we don't want to exceed 7 numbers) */ 714 if (len < 7) { 715 size_t slen = min_t(size_t, sizeof(nsecs_str), 8UL - len); 716 717 snprintf(nsecs_str, slen, "%03lu", nsecs_rem); 718 trace_seq_printf(s, ".%s", nsecs_str); 719 len += strlen(nsecs_str); 720 } 721 722 trace_seq_puts(s, " us "); 723 724 /* Print remaining spaces to fit the row's width */ 725 for (i = len; i < 7; i++) 726 trace_seq_putc(s, ' '); 727 } 728 729 static void 730 print_graph_duration(unsigned long long duration, struct trace_seq *s, 731 u32 flags) 732 { 733 if (!(flags & TRACE_GRAPH_PRINT_DURATION) || 734 !(trace_flags & TRACE_ITER_CONTEXT_INFO)) 735 return; 736 737 /* No real adata, just filling the column with spaces */ 738 switch (flags & TRACE_GRAPH_PRINT_FILL_MASK) { 739 case FLAGS_FILL_FULL: 740 trace_seq_puts(s, " | "); 741 return; 742 case FLAGS_FILL_START: 743 trace_seq_puts(s, " "); 744 return; 745 case FLAGS_FILL_END: 746 trace_seq_puts(s, " |"); 747 return; 748 } 749 750 /* Signal a overhead of time execution to the output */ 751 if (flags & TRACE_GRAPH_PRINT_OVERHEAD) 752 trace_seq_printf(s, "%c ", trace_find_mark(duration)); 753 else 754 trace_seq_puts(s, " "); 755 756 trace_print_graph_duration(duration, s); 757 trace_seq_puts(s, "| "); 758 } 759 760 /* Case of a leaf function on its call entry */ 761 static enum print_line_t 762 print_graph_entry_leaf(struct trace_iterator *iter, 763 struct ftrace_graph_ent_entry *entry, 764 struct ftrace_graph_ret_entry *ret_entry, 765 struct trace_seq *s, u32 flags) 766 { 767 struct fgraph_data *data = iter->private; 768 struct ftrace_graph_ret *graph_ret; 769 struct ftrace_graph_ent *call; 770 unsigned long long duration; 771 int i; 772 773 graph_ret = &ret_entry->ret; 774 call = &entry->graph_ent; 775 duration = graph_ret->rettime - graph_ret->calltime; 776 777 if (data) { 778 struct fgraph_cpu_data *cpu_data; 779 int cpu = iter->cpu; 780 781 cpu_data = per_cpu_ptr(data->cpu_data, cpu); 782 783 /* 784 * Comments display at + 1 to depth. Since 785 * this is a leaf function, keep the comments 786 * equal to this depth. 787 */ 788 cpu_data->depth = call->depth - 1; 789 790 /* No need to keep this function around for this depth */ 791 if (call->depth < FTRACE_RETFUNC_DEPTH) 792 cpu_data->enter_funcs[call->depth] = 0; 793 } 794 795 /* Overhead and duration */ 796 print_graph_duration(duration, s, flags); 797 798 /* Function */ 799 for (i = 0; i < call->depth * TRACE_GRAPH_INDENT; i++) 800 trace_seq_putc(s, ' '); 801 802 trace_seq_printf(s, "%ps();\n", (void *)call->func); 803 804 return trace_handle_return(s); 805 } 806 807 static enum print_line_t 808 print_graph_entry_nested(struct trace_iterator *iter, 809 struct ftrace_graph_ent_entry *entry, 810 struct trace_seq *s, int cpu, u32 flags) 811 { 812 struct ftrace_graph_ent *call = &entry->graph_ent; 813 struct fgraph_data *data = iter->private; 814 int i; 815 816 if (data) { 817 struct fgraph_cpu_data *cpu_data; 818 int cpu = iter->cpu; 819 820 cpu_data = per_cpu_ptr(data->cpu_data, cpu); 821 cpu_data->depth = call->depth; 822 823 /* Save this function pointer to see if the exit matches */ 824 if (call->depth < FTRACE_RETFUNC_DEPTH) 825 cpu_data->enter_funcs[call->depth] = call->func; 826 } 827 828 /* No time */ 829 print_graph_duration(0, s, flags | FLAGS_FILL_FULL); 830 831 /* Function */ 832 for (i = 0; i < call->depth * TRACE_GRAPH_INDENT; i++) 833 trace_seq_putc(s, ' '); 834 835 trace_seq_printf(s, "%ps() {\n", (void *)call->func); 836 837 if (trace_seq_has_overflowed(s)) 838 return TRACE_TYPE_PARTIAL_LINE; 839 840 /* 841 * we already consumed the current entry to check the next one 842 * and see if this is a leaf. 843 */ 844 return TRACE_TYPE_NO_CONSUME; 845 } 846 847 static void 848 print_graph_prologue(struct trace_iterator *iter, struct trace_seq *s, 849 int type, unsigned long addr, u32 flags) 850 { 851 struct fgraph_data *data = iter->private; 852 struct trace_entry *ent = iter->ent; 853 int cpu = iter->cpu; 854 855 /* Pid */ 856 verif_pid(s, ent->pid, cpu, data); 857 858 if (type) 859 /* Interrupt */ 860 print_graph_irq(iter, addr, type, cpu, ent->pid, flags); 861 862 if (!(trace_flags & TRACE_ITER_CONTEXT_INFO)) 863 return; 864 865 /* Absolute time */ 866 if (flags & TRACE_GRAPH_PRINT_ABS_TIME) 867 print_graph_abs_time(iter->ts, s); 868 869 /* Cpu */ 870 if (flags & TRACE_GRAPH_PRINT_CPU) 871 print_graph_cpu(s, cpu); 872 873 /* Proc */ 874 if (flags & TRACE_GRAPH_PRINT_PROC) { 875 print_graph_proc(s, ent->pid); 876 trace_seq_puts(s, " | "); 877 } 878 879 /* Latency format */ 880 if (trace_flags & TRACE_ITER_LATENCY_FMT) 881 print_graph_lat_fmt(s, ent); 882 883 return; 884 } 885 886 /* 887 * Entry check for irq code 888 * 889 * returns 1 if 890 * - we are inside irq code 891 * - we just entered irq code 892 * 893 * retunns 0 if 894 * - funcgraph-interrupts option is set 895 * - we are not inside irq code 896 */ 897 static int 898 check_irq_entry(struct trace_iterator *iter, u32 flags, 899 unsigned long addr, int depth) 900 { 901 int cpu = iter->cpu; 902 int *depth_irq; 903 struct fgraph_data *data = iter->private; 904 905 /* 906 * If we are either displaying irqs, or we got called as 907 * a graph event and private data does not exist, 908 * then we bypass the irq check. 909 */ 910 if ((flags & TRACE_GRAPH_PRINT_IRQS) || 911 (!data)) 912 return 0; 913 914 depth_irq = &(per_cpu_ptr(data->cpu_data, cpu)->depth_irq); 915 916 /* 917 * We are inside the irq code 918 */ 919 if (*depth_irq >= 0) 920 return 1; 921 922 if ((addr < (unsigned long)__irqentry_text_start) || 923 (addr >= (unsigned long)__irqentry_text_end)) 924 return 0; 925 926 /* 927 * We are entering irq code. 928 */ 929 *depth_irq = depth; 930 return 1; 931 } 932 933 /* 934 * Return check for irq code 935 * 936 * returns 1 if 937 * - we are inside irq code 938 * - we just left irq code 939 * 940 * returns 0 if 941 * - funcgraph-interrupts option is set 942 * - we are not inside irq code 943 */ 944 static int 945 check_irq_return(struct trace_iterator *iter, u32 flags, int depth) 946 { 947 int cpu = iter->cpu; 948 int *depth_irq; 949 struct fgraph_data *data = iter->private; 950 951 /* 952 * If we are either displaying irqs, or we got called as 953 * a graph event and private data does not exist, 954 * then we bypass the irq check. 955 */ 956 if ((flags & TRACE_GRAPH_PRINT_IRQS) || 957 (!data)) 958 return 0; 959 960 depth_irq = &(per_cpu_ptr(data->cpu_data, cpu)->depth_irq); 961 962 /* 963 * We are not inside the irq code. 964 */ 965 if (*depth_irq == -1) 966 return 0; 967 968 /* 969 * We are inside the irq code, and this is returning entry. 970 * Let's not trace it and clear the entry depth, since 971 * we are out of irq code. 972 * 973 * This condition ensures that we 'leave the irq code' once 974 * we are out of the entry depth. Thus protecting us from 975 * the RETURN entry loss. 976 */ 977 if (*depth_irq >= depth) { 978 *depth_irq = -1; 979 return 1; 980 } 981 982 /* 983 * We are inside the irq code, and this is not the entry. 984 */ 985 return 1; 986 } 987 988 static enum print_line_t 989 print_graph_entry(struct ftrace_graph_ent_entry *field, struct trace_seq *s, 990 struct trace_iterator *iter, u32 flags) 991 { 992 struct fgraph_data *data = iter->private; 993 struct ftrace_graph_ent *call = &field->graph_ent; 994 struct ftrace_graph_ret_entry *leaf_ret; 995 static enum print_line_t ret; 996 int cpu = iter->cpu; 997 998 if (check_irq_entry(iter, flags, call->func, call->depth)) 999 return TRACE_TYPE_HANDLED; 1000 1001 print_graph_prologue(iter, s, TRACE_GRAPH_ENT, call->func, flags); 1002 1003 leaf_ret = get_return_for_leaf(iter, field); 1004 if (leaf_ret) 1005 ret = print_graph_entry_leaf(iter, field, leaf_ret, s, flags); 1006 else 1007 ret = print_graph_entry_nested(iter, field, s, cpu, flags); 1008 1009 if (data) { 1010 /* 1011 * If we failed to write our output, then we need to make 1012 * note of it. Because we already consumed our entry. 1013 */ 1014 if (s->full) { 1015 data->failed = 1; 1016 data->cpu = cpu; 1017 } else 1018 data->failed = 0; 1019 } 1020 1021 return ret; 1022 } 1023 1024 static enum print_line_t 1025 print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s, 1026 struct trace_entry *ent, struct trace_iterator *iter, 1027 u32 flags) 1028 { 1029 unsigned long long duration = trace->rettime - trace->calltime; 1030 struct fgraph_data *data = iter->private; 1031 pid_t pid = ent->pid; 1032 int cpu = iter->cpu; 1033 int func_match = 1; 1034 int i; 1035 1036 if (check_irq_return(iter, flags, trace->depth)) 1037 return TRACE_TYPE_HANDLED; 1038 1039 if (data) { 1040 struct fgraph_cpu_data *cpu_data; 1041 int cpu = iter->cpu; 1042 1043 cpu_data = per_cpu_ptr(data->cpu_data, cpu); 1044 1045 /* 1046 * Comments display at + 1 to depth. This is the 1047 * return from a function, we now want the comments 1048 * to display at the same level of the bracket. 1049 */ 1050 cpu_data->depth = trace->depth - 1; 1051 1052 if (trace->depth < FTRACE_RETFUNC_DEPTH) { 1053 if (cpu_data->enter_funcs[trace->depth] != trace->func) 1054 func_match = 0; 1055 cpu_data->enter_funcs[trace->depth] = 0; 1056 } 1057 } 1058 1059 print_graph_prologue(iter, s, 0, 0, flags); 1060 1061 /* Overhead and duration */ 1062 print_graph_duration(duration, s, flags); 1063 1064 /* Closing brace */ 1065 for (i = 0; i < trace->depth * TRACE_GRAPH_INDENT; i++) 1066 trace_seq_putc(s, ' '); 1067 1068 /* 1069 * If the return function does not have a matching entry, 1070 * then the entry was lost. Instead of just printing 1071 * the '}' and letting the user guess what function this 1072 * belongs to, write out the function name. Always do 1073 * that if the funcgraph-tail option is enabled. 1074 */ 1075 if (func_match && !(flags & TRACE_GRAPH_PRINT_TAIL)) 1076 trace_seq_puts(s, "}\n"); 1077 else 1078 trace_seq_printf(s, "} /* %ps */\n", (void *)trace->func); 1079 1080 /* Overrun */ 1081 if (flags & TRACE_GRAPH_PRINT_OVERRUN) 1082 trace_seq_printf(s, " (Overruns: %lu)\n", 1083 trace->overrun); 1084 1085 print_graph_irq(iter, trace->func, TRACE_GRAPH_RET, 1086 cpu, pid, flags); 1087 1088 return trace_handle_return(s); 1089 } 1090 1091 static enum print_line_t 1092 print_graph_comment(struct trace_seq *s, struct trace_entry *ent, 1093 struct trace_iterator *iter, u32 flags) 1094 { 1095 unsigned long sym_flags = (trace_flags & TRACE_ITER_SYM_MASK); 1096 struct fgraph_data *data = iter->private; 1097 struct trace_event *event; 1098 int depth = 0; 1099 int ret; 1100 int i; 1101 1102 if (data) 1103 depth = per_cpu_ptr(data->cpu_data, iter->cpu)->depth; 1104 1105 print_graph_prologue(iter, s, 0, 0, flags); 1106 1107 /* No time */ 1108 print_graph_duration(0, s, flags | FLAGS_FILL_FULL); 1109 1110 /* Indentation */ 1111 if (depth > 0) 1112 for (i = 0; i < (depth + 1) * TRACE_GRAPH_INDENT; i++) 1113 trace_seq_putc(s, ' '); 1114 1115 /* The comment */ 1116 trace_seq_puts(s, "/* "); 1117 1118 switch (iter->ent->type) { 1119 case TRACE_BPRINT: 1120 ret = trace_print_bprintk_msg_only(iter); 1121 if (ret != TRACE_TYPE_HANDLED) 1122 return ret; 1123 break; 1124 case TRACE_PRINT: 1125 ret = trace_print_printk_msg_only(iter); 1126 if (ret != TRACE_TYPE_HANDLED) 1127 return ret; 1128 break; 1129 default: 1130 event = ftrace_find_event(ent->type); 1131 if (!event) 1132 return TRACE_TYPE_UNHANDLED; 1133 1134 ret = event->funcs->trace(iter, sym_flags, event); 1135 if (ret != TRACE_TYPE_HANDLED) 1136 return ret; 1137 } 1138 1139 if (trace_seq_has_overflowed(s)) 1140 goto out; 1141 1142 /* Strip ending newline */ 1143 if (s->buffer[s->seq.len - 1] == '\n') { 1144 s->buffer[s->seq.len - 1] = '\0'; 1145 s->seq.len--; 1146 } 1147 1148 trace_seq_puts(s, " */\n"); 1149 out: 1150 return trace_handle_return(s); 1151 } 1152 1153 1154 enum print_line_t 1155 print_graph_function_flags(struct trace_iterator *iter, u32 flags) 1156 { 1157 struct ftrace_graph_ent_entry *field; 1158 struct fgraph_data *data = iter->private; 1159 struct trace_entry *entry = iter->ent; 1160 struct trace_seq *s = &iter->seq; 1161 int cpu = iter->cpu; 1162 int ret; 1163 1164 if (data && per_cpu_ptr(data->cpu_data, cpu)->ignore) { 1165 per_cpu_ptr(data->cpu_data, cpu)->ignore = 0; 1166 return TRACE_TYPE_HANDLED; 1167 } 1168 1169 /* 1170 * If the last output failed, there's a possibility we need 1171 * to print out the missing entry which would never go out. 1172 */ 1173 if (data && data->failed) { 1174 field = &data->ent; 1175 iter->cpu = data->cpu; 1176 ret = print_graph_entry(field, s, iter, flags); 1177 if (ret == TRACE_TYPE_HANDLED && iter->cpu != cpu) { 1178 per_cpu_ptr(data->cpu_data, iter->cpu)->ignore = 1; 1179 ret = TRACE_TYPE_NO_CONSUME; 1180 } 1181 iter->cpu = cpu; 1182 return ret; 1183 } 1184 1185 switch (entry->type) { 1186 case TRACE_GRAPH_ENT: { 1187 /* 1188 * print_graph_entry() may consume the current event, 1189 * thus @field may become invalid, so we need to save it. 1190 * sizeof(struct ftrace_graph_ent_entry) is very small, 1191 * it can be safely saved at the stack. 1192 */ 1193 struct ftrace_graph_ent_entry saved; 1194 trace_assign_type(field, entry); 1195 saved = *field; 1196 return print_graph_entry(&saved, s, iter, flags); 1197 } 1198 case TRACE_GRAPH_RET: { 1199 struct ftrace_graph_ret_entry *field; 1200 trace_assign_type(field, entry); 1201 return print_graph_return(&field->ret, s, entry, iter, flags); 1202 } 1203 case TRACE_STACK: 1204 case TRACE_FN: 1205 /* dont trace stack and functions as comments */ 1206 return TRACE_TYPE_UNHANDLED; 1207 1208 default: 1209 return print_graph_comment(s, entry, iter, flags); 1210 } 1211 1212 return TRACE_TYPE_HANDLED; 1213 } 1214 1215 static enum print_line_t 1216 print_graph_function(struct trace_iterator *iter) 1217 { 1218 return print_graph_function_flags(iter, tracer_flags.val); 1219 } 1220 1221 static enum print_line_t 1222 print_graph_function_event(struct trace_iterator *iter, int flags, 1223 struct trace_event *event) 1224 { 1225 return print_graph_function(iter); 1226 } 1227 1228 static void print_lat_header(struct seq_file *s, u32 flags) 1229 { 1230 static const char spaces[] = " " /* 16 spaces */ 1231 " " /* 4 spaces */ 1232 " "; /* 17 spaces */ 1233 int size = 0; 1234 1235 if (flags & TRACE_GRAPH_PRINT_ABS_TIME) 1236 size += 16; 1237 if (flags & TRACE_GRAPH_PRINT_CPU) 1238 size += 4; 1239 if (flags & TRACE_GRAPH_PRINT_PROC) 1240 size += 17; 1241 1242 seq_printf(s, "#%.*s _-----=> irqs-off \n", size, spaces); 1243 seq_printf(s, "#%.*s / _----=> need-resched \n", size, spaces); 1244 seq_printf(s, "#%.*s| / _---=> hardirq/softirq \n", size, spaces); 1245 seq_printf(s, "#%.*s|| / _--=> preempt-depth \n", size, spaces); 1246 seq_printf(s, "#%.*s||| / \n", size, spaces); 1247 } 1248 1249 static void __print_graph_headers_flags(struct seq_file *s, u32 flags) 1250 { 1251 int lat = trace_flags & TRACE_ITER_LATENCY_FMT; 1252 1253 if (lat) 1254 print_lat_header(s, flags); 1255 1256 /* 1st line */ 1257 seq_putc(s, '#'); 1258 if (flags & TRACE_GRAPH_PRINT_ABS_TIME) 1259 seq_puts(s, " TIME "); 1260 if (flags & TRACE_GRAPH_PRINT_CPU) 1261 seq_puts(s, " CPU"); 1262 if (flags & TRACE_GRAPH_PRINT_PROC) 1263 seq_puts(s, " TASK/PID "); 1264 if (lat) 1265 seq_puts(s, "||||"); 1266 if (flags & TRACE_GRAPH_PRINT_DURATION) 1267 seq_puts(s, " DURATION "); 1268 seq_puts(s, " FUNCTION CALLS\n"); 1269 1270 /* 2nd line */ 1271 seq_putc(s, '#'); 1272 if (flags & TRACE_GRAPH_PRINT_ABS_TIME) 1273 seq_puts(s, " | "); 1274 if (flags & TRACE_GRAPH_PRINT_CPU) 1275 seq_puts(s, " | "); 1276 if (flags & TRACE_GRAPH_PRINT_PROC) 1277 seq_puts(s, " | | "); 1278 if (lat) 1279 seq_puts(s, "||||"); 1280 if (flags & TRACE_GRAPH_PRINT_DURATION) 1281 seq_puts(s, " | | "); 1282 seq_puts(s, " | | | |\n"); 1283 } 1284 1285 static void print_graph_headers(struct seq_file *s) 1286 { 1287 print_graph_headers_flags(s, tracer_flags.val); 1288 } 1289 1290 void print_graph_headers_flags(struct seq_file *s, u32 flags) 1291 { 1292 struct trace_iterator *iter = s->private; 1293 1294 if (!(trace_flags & TRACE_ITER_CONTEXT_INFO)) 1295 return; 1296 1297 if (trace_flags & TRACE_ITER_LATENCY_FMT) { 1298 /* print nothing if the buffers are empty */ 1299 if (trace_empty(iter)) 1300 return; 1301 1302 print_trace_header(s, iter); 1303 } 1304 1305 __print_graph_headers_flags(s, flags); 1306 } 1307 1308 void graph_trace_open(struct trace_iterator *iter) 1309 { 1310 /* pid and depth on the last trace processed */ 1311 struct fgraph_data *data; 1312 int cpu; 1313 1314 iter->private = NULL; 1315 1316 data = kzalloc(sizeof(*data), GFP_KERNEL); 1317 if (!data) 1318 goto out_err; 1319 1320 data->cpu_data = alloc_percpu(struct fgraph_cpu_data); 1321 if (!data->cpu_data) 1322 goto out_err_free; 1323 1324 for_each_possible_cpu(cpu) { 1325 pid_t *pid = &(per_cpu_ptr(data->cpu_data, cpu)->last_pid); 1326 int *depth = &(per_cpu_ptr(data->cpu_data, cpu)->depth); 1327 int *ignore = &(per_cpu_ptr(data->cpu_data, cpu)->ignore); 1328 int *depth_irq = &(per_cpu_ptr(data->cpu_data, cpu)->depth_irq); 1329 1330 *pid = -1; 1331 *depth = 0; 1332 *ignore = 0; 1333 *depth_irq = -1; 1334 } 1335 1336 iter->private = data; 1337 1338 return; 1339 1340 out_err_free: 1341 kfree(data); 1342 out_err: 1343 pr_warning("function graph tracer: not enough memory\n"); 1344 } 1345 1346 void graph_trace_close(struct trace_iterator *iter) 1347 { 1348 struct fgraph_data *data = iter->private; 1349 1350 if (data) { 1351 free_percpu(data->cpu_data); 1352 kfree(data); 1353 } 1354 } 1355 1356 static int 1357 func_graph_set_flag(struct trace_array *tr, u32 old_flags, u32 bit, int set) 1358 { 1359 if (bit == TRACE_GRAPH_PRINT_IRQS) 1360 ftrace_graph_skip_irqs = !set; 1361 1362 return 0; 1363 } 1364 1365 static struct trace_event_functions graph_functions = { 1366 .trace = print_graph_function_event, 1367 }; 1368 1369 static struct trace_event graph_trace_entry_event = { 1370 .type = TRACE_GRAPH_ENT, 1371 .funcs = &graph_functions, 1372 }; 1373 1374 static struct trace_event graph_trace_ret_event = { 1375 .type = TRACE_GRAPH_RET, 1376 .funcs = &graph_functions 1377 }; 1378 1379 static struct tracer graph_trace __tracer_data = { 1380 .name = "function_graph", 1381 .update_thresh = graph_trace_update_thresh, 1382 .open = graph_trace_open, 1383 .pipe_open = graph_trace_open, 1384 .close = graph_trace_close, 1385 .pipe_close = graph_trace_close, 1386 .init = graph_trace_init, 1387 .reset = graph_trace_reset, 1388 .print_line = print_graph_function, 1389 .print_header = print_graph_headers, 1390 .flags = &tracer_flags, 1391 .set_flag = func_graph_set_flag, 1392 #ifdef CONFIG_FTRACE_SELFTEST 1393 .selftest = trace_selftest_startup_function_graph, 1394 #endif 1395 }; 1396 1397 1398 static ssize_t 1399 graph_depth_write(struct file *filp, const char __user *ubuf, size_t cnt, 1400 loff_t *ppos) 1401 { 1402 unsigned long val; 1403 int ret; 1404 1405 ret = kstrtoul_from_user(ubuf, cnt, 10, &val); 1406 if (ret) 1407 return ret; 1408 1409 max_depth = val; 1410 1411 *ppos += cnt; 1412 1413 return cnt; 1414 } 1415 1416 static ssize_t 1417 graph_depth_read(struct file *filp, char __user *ubuf, size_t cnt, 1418 loff_t *ppos) 1419 { 1420 char buf[15]; /* More than enough to hold UINT_MAX + "\n"*/ 1421 int n; 1422 1423 n = sprintf(buf, "%d\n", max_depth); 1424 1425 return simple_read_from_buffer(ubuf, cnt, ppos, buf, n); 1426 } 1427 1428 static const struct file_operations graph_depth_fops = { 1429 .open = tracing_open_generic, 1430 .write = graph_depth_write, 1431 .read = graph_depth_read, 1432 .llseek = generic_file_llseek, 1433 }; 1434 1435 static __init int init_graph_debugfs(void) 1436 { 1437 struct dentry *d_tracer; 1438 1439 d_tracer = tracing_init_dentry(); 1440 if (IS_ERR(d_tracer)) 1441 return 0; 1442 1443 trace_create_file("max_graph_depth", 0644, d_tracer, 1444 NULL, &graph_depth_fops); 1445 1446 return 0; 1447 } 1448 fs_initcall(init_graph_debugfs); 1449 1450 static __init int init_graph_trace(void) 1451 { 1452 max_bytes_for_cpu = snprintf(NULL, 0, "%d", nr_cpu_ids - 1); 1453 1454 if (!register_ftrace_event(&graph_trace_entry_event)) { 1455 pr_warning("Warning: could not register graph trace events\n"); 1456 return 1; 1457 } 1458 1459 if (!register_ftrace_event(&graph_trace_ret_event)) { 1460 pr_warning("Warning: could not register graph trace events\n"); 1461 return 1; 1462 } 1463 1464 return register_tracer(&graph_trace); 1465 } 1466 1467 core_initcall(init_graph_trace); 1468