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