1. 21 Apr, 2017 15 commits
  2. 18 Apr, 2017 5 commits
    • Steven Rostedt (VMware)'s avatar
      ftrace: Move the probe function into the tracing directory · ec19b859
      Steven Rostedt (VMware) authored
      As nothing outside the tracing directory uses the function probes mechanism,
      I'm moving the prototypes out of the include/linux/ftrace.h and into the
      local kernel/trace/trace.h header. I plan on making them hook to the
      trace_array structure which is local to kernel/trace, and I do not want to
      expose it to the rest of the kernel. This requires that the probe functions
      must also be local to tracing. But luckily nothing else uses them.
      Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
      ec19b859
    • Steven Rostedt (VMware)'s avatar
      selftests: ftrace: Add test to test reading of set_ftrace_file · a9064f67
      Steven Rostedt (VMware) authored
      The set_ftrace_file lists both functions that are filtered, as well as
      function probes (triggers) that are attached to a function, like traceon or
      stacktrace, etc. The reading of this file is not as trivial as most pseudo
      files are, and there's been various bugs that have appeared in the past
      when there's a mix of probes and functions listed. There's also a difference
      when reading the file using dd with a block size of 1.
      
      This test performs the following:
      
       o Resets set_ftrace_filter
      
       o Makes sure only "#### all functions enabled ####" is listed
      
          (All checks uses cat, and dd with bs=1 and bs=100)
      
       o Adds a traceon trigger to schedule
      
       o Checks if only "#### all function enabled ####" and the trigger is there.
      
       o Adds tracing of schedule
      
       o Checks if only schedule and the trigger is there
      
       o Adds tracing of do_IRQ as well
      
       o Checks if only schedule, do_IRQ and the trigger is there
      
       o Adds a traceon trigger to do_IRQ
      
       o Checks if only schedule, do_IRQ and both triggers are there
      
       o Removes tracing of do_IRQ
      
       o Checks if only schedule and both triggers are there
      
       o Removes tracing of schedule
      
       o Checks if only  "#### all functions enabled ####" and both triggers are there
      
       o Removes the triggers
      
       o Checks if only "#### all functions enabled ####" is there
      
       o Adds tracing of schedule
      
       o Checks if only schedule is there
      
       o Adds tracing of do_IRQ
      
       o Checks if only schedule and do_IRQ are there
      Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
      a9064f67
    • Steven Rostedt (VMware)'s avatar
      selftests: ftrace: Add a test to test function triggers to start and stop tracing · d8b39e1d
      Steven Rostedt (VMware) authored
      This adds a test to test the function tiggers traceon and traceoff to make
      sure that it starts and stops tracing when a function is hit.
      
      The test performs the following:
      
       o Enables all events
      
       o Writes schedule:traceoff into set_ftrace_filter
      
       o Makes sure the tigger exists in the file
      
       o Makes sure the trace file no longer grows
      
       o Makes sure that tracing_on is now zero
      
       o Clears the trace file
      
       o Makes sure it's still empty
      
       o Removes the trigger
      
       o Makes sure tracing is still off (tracing_on is zero)
      
       o Writes schedule:traceon into set_ftrace_filter
      
       o Makes sure the trace file is no longer empty
      
       o Makes sure that tracing_on file is set to one
      
       o Removes the trigger
      
       o Makes sure the trigger is no longer there
      
       o Writes schedule:traceoff:3 into set_ftrace_filter
      
       o Makes sure that tracing_on turns off
      
         . Writes 1 into tracing_on
      
         . Makes sure that it turns off 2 more times
      
       o Writes 1 into tracing_on
      
       o Makes sure that tracing_on is still a one
      Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
      d8b39e1d
    • Steven Rostedt (VMware)'s avatar
      selftests: ftrace: Add a selftest to test event enable/disable func trigger · 43bb45da
      Steven Rostedt (VMware) authored
      This adds a test to enable and disable trace events via the function
      triggers. It tests enabling and disabling the sched:sched_switch event via
      the the event_enable and event_disable function triggers attached to the
      schedule() kernel function.
      
      The test does the following:
      
       o disable all events
      
       o disables or enables the sched_switch event
      
       o writes schedule:event_enable/disable:sched:sched_switch into set_ftrace_filter
      
       o 5 times it checks to make sure:
      
          . Writes 0/1 into the sched_switch/enable
      
          . Checks that the sched_switch/enable goes back to 1/0
      
       o Resets the events
      
       o writes schedule:event_enable/disable:sched:sched_switch:3 into set_ftrace_filter
      
       o Does a loop of 3 to see that sched_switch/enable file gets updated
      
       o Makes sure the sched_switch/enable stops getting updated
      Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
      43bb45da
    • Steven Rostedt (VMware)'s avatar
      selftests: ftrace: Add a way to reset triggers in the set_ftrace_filter file · 8e5e19c1
      Steven Rostedt (VMware) authored
      Just writing into the set_ftrace_filter file does not reset triggers, even
      though it can reset the function list. Triggers require writing the trigger
      name with a "!" prepended. It's worse that it requires the number if the
      trigger has a count associated to it.
      
      Add a reset_ftrace_filter function to the ftrace self tests to allow for the
      tests to have a generic way to clear them. It also resets any functions that
      are listed in that file as well.
      Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
      8e5e19c1
  3. 17 Apr, 2017 4 commits
  4. 15 Apr, 2017 1 commit
    • Steven Rostedt (VMware)'s avatar
      ftrace: Fix removing of second function probe · acceb72e
      Steven Rostedt (VMware) authored
      When two function probes are added to set_ftrace_filter, and then one of
      them is removed, the update to the function locations is not performed, and
      the record keeping of the function states are corrupted, and causes an
      ftrace_bug() to occur.
      
      This is easily reproducable by adding two probes, removing one, and then
      adding it back again.
      
       # cd /sys/kernel/debug/tracing
       # echo schedule:traceoff > set_ftrace_filter
       # echo do_IRQ:traceoff > set_ftrace_filter
       # echo \!do_IRQ:traceoff > /debug/tracing/set_ftrace_filter
       # echo do_IRQ:traceoff > set_ftrace_filter
      
      Causes:
       ------------[ cut here ]------------
       WARNING: CPU: 2 PID: 1098 at kernel/trace/ftrace.c:2369 ftrace_get_addr_curr+0x143/0x220
       Modules linked in: [...]
       CPU: 2 PID: 1098 Comm: bash Not tainted 4.10.0-test+ #405
       Hardware name: Hewlett-Packard HP Compaq Pro 6300 SFF/339A, BIOS K01 v02.05 05/07/2012
       Call Trace:
        dump_stack+0x68/0x9f
        __warn+0x111/0x130
        ? trace_irq_work_interrupt+0xa0/0xa0
        warn_slowpath_null+0x1d/0x20
        ftrace_get_addr_curr+0x143/0x220
        ? __fentry__+0x10/0x10
        ftrace_replace_code+0xe3/0x4f0
        ? ftrace_int3_handler+0x90/0x90
        ? printk+0x99/0xb5
        ? 0xffffffff81000000
        ftrace_modify_all_code+0x97/0x110
        arch_ftrace_update_code+0x10/0x20
        ftrace_run_update_code+0x1c/0x60
        ftrace_run_modify_code.isra.48.constprop.62+0x8e/0xd0
        register_ftrace_function_probe+0x4b6/0x590
        ? ftrace_startup+0x310/0x310
        ? debug_lockdep_rcu_enabled.part.4+0x1a/0x30
        ? update_stack_state+0x88/0x110
        ? ftrace_regex_write.isra.43.part.44+0x1d3/0x320
        ? preempt_count_sub+0x18/0xd0
        ? mutex_lock_nested+0x104/0x800
        ? ftrace_regex_write.isra.43.part.44+0x1d3/0x320
        ? __unwind_start+0x1c0/0x1c0
        ? _mutex_lock_nest_lock+0x800/0x800
        ftrace_trace_probe_callback.isra.3+0xc0/0x130
        ? func_set_flag+0xe0/0xe0
        ? __lock_acquire+0x642/0x1790
        ? __might_fault+0x1e/0x20
        ? trace_get_user+0x398/0x470
        ? strcmp+0x35/0x60
        ftrace_trace_onoff_callback+0x48/0x70
        ftrace_regex_write.isra.43.part.44+0x251/0x320
        ? match_records+0x420/0x420
        ftrace_filter_write+0x2b/0x30
        __vfs_write+0xd7/0x330
        ? do_loop_readv_writev+0x120/0x120
        ? locks_remove_posix+0x90/0x2f0
        ? do_lock_file_wait+0x160/0x160
        ? __lock_is_held+0x93/0x100
        ? rcu_read_lock_sched_held+0x5c/0xb0
        ? preempt_count_sub+0x18/0xd0
        ? __sb_start_write+0x10a/0x230
        ? vfs_write+0x222/0x240
        vfs_write+0xef/0x240
        SyS_write+0xab/0x130
        ? SyS_read+0x130/0x130
        ? trace_hardirqs_on_caller+0x182/0x280
        ? trace_hardirqs_on_thunk+0x1a/0x1c
        entry_SYSCALL_64_fastpath+0x18/0xad
       RIP: 0033:0x7fe61c157c30
       RSP: 002b:00007ffe87890258 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
       RAX: ffffffffffffffda RBX: ffffffff8114a410 RCX: 00007fe61c157c30
       RDX: 0000000000000010 RSI: 000055814798f5e0 RDI: 0000000000000001
       RBP: ffff8800c9027f98 R08: 00007fe61c422740 R09: 00007fe61ca53700
       R10: 0000000000000073 R11: 0000000000000246 R12: 0000558147a36400
       R13: 00007ffe8788f160 R14: 0000000000000024 R15: 00007ffe8788f15c
        ? trace_hardirqs_off_caller+0xc0/0x110
       ---[ end trace 99fa09b3d9869c2c ]---
       Bad trampoline accounting at: ffffffff81cc3b00 (do_IRQ+0x0/0x150)
      
      Cc: stable@vger.kernel.org
      Fixes: 59df055f ("ftrace: trace different functions with a different tracer")
      Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
      acceb72e
  5. 10 Apr, 2017 6 commits
  6. 07 Apr, 2017 1 commit
    • Steven Rostedt (VMware)'s avatar
      ftrace: Add use of synchronize_rcu_tasks() with dynamic trampolines · 0598e4f0
      Steven Rostedt (VMware) authored
      The function tracer needs to be more careful than other subsystems when it
      comes to freeing data. Especially if that data is actually executable code.
      When a single function is traced, a trampoline can be dynamically allocated
      which is called to jump to the function trace callback. When the callback is
      no longer needed, the dynamic allocated trampoline needs to be freed. This
      is where the issues arise. The dynamically allocated trampoline must not be
      used again. As function tracing can trace all subsystems, including
      subsystems that are used to serialize aspects of freeing (namely RCU), it
      must take extra care when doing the freeing.
      
      Before synchronize_rcu_tasks() was around, there was no way for the function
      tracer to know that nothing was using the dynamically allocated trampoline
      when CONFIG_PREEMPT was enabled. That's because a task could be indefinitely
      preempted while sitting on the trampoline. Now with synchronize_rcu_tasks(),
      it will wait till all tasks have either voluntarily scheduled (not on the
      trampoline) or goes into userspace (not on the trampoline). Then it is safe
      to free the trampoline even with CONFIG_PREEMPT set.
      Acked-by: default avatar"Paul E. McKenney" <paulmck@linux.vnet.ibm.com>
      Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
      0598e4f0
  7. 04 Apr, 2017 1 commit
    • Alban Crequy's avatar
      tracing/kprobes: expose maxactive for kretprobe in kprobe_events · 696ced4f
      Alban Crequy authored
      When a kretprobe is installed on a kernel function, there is a maximum
      limit of how many calls in parallel it can catch (aka "maxactive"). A
      kernel module could call register_kretprobe() and initialize maxactive
      (see example in samples/kprobes/kretprobe_example.c).
      
      But that is not exposed to userspace and it is currently not possible to
      choose maxactive when writing to /sys/kernel/debug/tracing/kprobe_events
      
      The default maxactive can be as low as 1 on single-core with a
      non-preemptive kernel. This is too low and we need to increase it not
      only for recursive functions, but for functions that sleep or resched.
      
      This patch updates the format of the command that can be written to
      kprobe_events so that maxactive can be optionally specified.
      
      I need this for a bpf program attached to the kretprobe of
      inet_csk_accept, which can sleep for a long time.
      
      This patch includes a basic selftest:
      
      > # ./ftracetest -v  test.d/kprobe/
      > === Ftrace unit tests ===
      > [1] Kprobe dynamic event - adding and removing	[PASS]
      > [2] Kprobe dynamic event - busy event check	[PASS]
      > [3] Kprobe dynamic event with arguments	[PASS]
      > [4] Kprobes event arguments with types	[PASS]
      > [5] Kprobe dynamic event with function tracer	[PASS]
      > [6] Kretprobe dynamic event with arguments	[PASS]
      > [7] Kretprobe dynamic event with maxactive	[PASS]
      >
      > # of passed:  7
      > # of failed:  0
      > # of unresolved:  0
      > # of untested:  0
      > # of unsupported:  0
      > # of xfailed:  0
      > # of undefined(test bug):  0
      
      BugLink: https://github.com/iovisor/bcc/issues/1072
      Link: http://lkml.kernel.org/r/1491215782-15490-1-git-send-email-alban@kinvolk.ioAcked-by: default avatarMasami Hiramatsu <mhiramat@kernel.org>
      Signed-off-by: default avatarAlban Crequy <alban@kinvolk.io>
      Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
      696ced4f
  8. 03 Apr, 2017 1 commit
    • Steven Rostedt (VMware)'s avatar
      ftrace: Have init/main.c call ftrace directly to free init memory · b80f0f6c
      Steven Rostedt (VMware) authored
      Relying on free_reserved_area() to call ftrace to free init memory proved to
      not be sufficient. The issue is that on x86, when debug_pagealloc is
      enabled, the init memory is not freed, but simply set as not present. Since
      ftrace was uninformed of this, starting function tracing still tries to
      update pages that are not present according to the page tables, causing
      ftrace to bug, as well as killing the kernel itself.
      
      Instead of relying on free_reserved_area(), have init/main.c call ftrace
      directly just before it frees the init memory. Then it needs to use
      __init_begin and __init_end to know where the init memory location is.
      Looking at all archs (and testing what I can), it appears that this should
      work for each of them.
      Reported-by: default avatarkernel test robot <xiaolong.ye@intel.com>
      Reported-by: default avatarFengguang Wu <fengguang.wu@intel.com>
      Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
      b80f0f6c
  9. 31 Mar, 2017 5 commits
    • Steven Rostedt (VMware)'s avatar
      ftrace: Create separate t_func_next() to simplify the function / hash logic · 5bd84629
      Steven Rostedt (VMware) authored
      I noticed that if I use dd to read the set_ftrace_filter file that the first
      hash command is repeated.
      
       # cd /sys/kernel/debug/tracing
       # echo schedule > set_ftrace_filter
       # echo do_IRQ >> set_ftrace_filter
       # echo schedule:traceoff >> set_ftrace_filter
       # echo do_IRQ:traceoff >> set_ftrace_filter
      
       # cat set_ftrace_filter
       schedule
       do_IRQ
       schedule:traceoff:unlimited
       do_IRQ:traceoff:unlimited
      
       # dd if=set_ftrace_filter bs=1
       schedule
       do_IRQ
       schedule:traceoff:unlimited
       schedule:traceoff:unlimited
       do_IRQ:traceoff:unlimited
       98+0 records in
       98+0 records out
       98 bytes copied, 0.00265011 s, 37.0 kB/s
      
      This is due to the way t_start() calls t_next() as well as the seq_file
      calls t_next() and the state is slightly different between the two. Namely,
      t_start() will call t_next() with a local "pos" variable.
      
      By separating out the function listing from t_next() into its own function,
      we can have better control of outputting the functions and the hash of
      triggers. This simplifies the code.
      Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
      5bd84629
    • Steven Rostedt (VMware)'s avatar
      ftrace: Update func_pos in t_start() when all functions are enabled · 43ff926a
      Steven Rostedt (VMware) authored
      If all functions are enabled, there's a comment displayed in the file to
      denote that:
      
        # cd /sys/kernel/debug/tracing
        # cat set_ftrace_filter
       #### all functions enabled ####
      
      If a function trigger is set, those are displayed as well:
      
        # echo schedule:traceoff >> /debug/tracing/set_ftrace_filter
        # cat set_ftrace_filter
       #### all functions enabled ####
       schedule:traceoff:unlimited
      
      But if you read that file with dd, the output can change:
      
        # dd if=/debug/tracing/set_ftrace_filter bs=1
       #### all functions enabled ####
       32+0 records in
       32+0 records out
       32 bytes copied, 7.0237e-05 s, 456 kB/s
      
      This is because the "pos" variable is updated for the comment, but func_pos
      is not. "func_pos" is used by the triggers (or hashes) to know how many
      functions were printed and it bases its index from the pos - func_pos.
      func_pos should be 1 to count for the comment printed. But since it is not,
      t_hash_start() thinks that one trigger was already printed.
      
      The cat gets to t_hash_start() via t_next() and not t_start() which updates
      both pos and func_pos.
      Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
      43ff926a
    • Steven Rostedt (VMware)'s avatar
      ftrace: Return NULL at end of t_start() instead of calling t_hash_start() · 2d71d989
      Steven Rostedt (VMware) authored
      The loop in t_start() of calling t_next() will call t_hash_start() if the
      pos is beyond the functions and enters the hash items. There's no reason to
      check if p is NULL and call t_hash_start(), as that would be redundant.
      Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
      2d71d989
    • Steven Rostedt (VMware)'s avatar
      ftrace: Assign iter->hash to filter or notrace hashes on seq read · c20489da
      Steven Rostedt (VMware) authored
      Instead of testing if the hash to use is the filter_hash or the notrace_hash
      at each iteration, do the test at open, and set the iter->hash to point to
      the corresponding filter or notrace hash. Then use that directly instead of
      testing which hash needs to be used each iteration.
      Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
      c20489da
    • Steven Rostedt (VMware)'s avatar
      ftrace: Clean up __seq_open_private() return check · c1bc5919
      Steven Rostedt (VMware) authored
      The return status check of __seq_open_private() is rather strange:
      
      	iter = __seq_open_private();
      	if (iter) {
      		/* do stuff */
      	}
      
      	return iter ? 0 : -ENOMEM;
      
      It makes much more sense to do the return of failure right away:
      
      	iter = __seq_open_private();
      	if (!iter)
      		return -ENOMEM;
      
      	/* do stuff */
      
      	return 0;
      
      This clean up will make updates to this code a bit nicer.
      Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
      c1bc5919
  10. 28 Mar, 2017 1 commit
    • Steven Rostedt (VMware)'s avatar
      ftrace/x86: Do no run CPU sync when there is only one CPU online · 2b87965a
      Steven Rostedt (VMware) authored
      Moving enabling of function tracing to early boot, even before scheduling is
      enabled, means that it is not safe to enable interrupts. When function
      tracing was enabled at boot up, it use to happen after scheduling and the
      other CPUs were brought up. That required running a sync across all CPUs
      when modifying the function hook locations in the code. To do the
      synchronization, interrupts had to be enabled. Now function tracing can be
      started before the other CPUs are brought up, and enabling interrupts in
      that case is dangerous. As only tho boot CPU is active, there is no reason
      to run the synchronization. If the online CPU count is one, do not bother
      doing the synchronization. This removes the need to enable interrupts.
      
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: Ingo Molnar <mingo@kernel.org>
      Cc: "H. Peter Anvin" <hpa@zytor.com>
      Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
      2b87965a