Commit b8c0aa46 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'trace-3.17' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace

Pull tracing updates from Steven Rostedt:
 "This pull request has a lot of work done.  The main thing is the
  changes to the ftrace function callback infrastructure.  It's
  introducing a way to allow different functions to call directly
  different trampolines instead of all calling the same "mcount" one.

  The only user of this for now is the function graph tracer, which
  always had a different trampoline, but the function tracer trampoline
  was called and did basically nothing, and then the function graph
  tracer trampoline was called.  The difference now, is that the
  function graph tracer trampoline can be called directly if a function
  is only being traced by the function graph trampoline.  If function
  tracing is also happening on the same function, the old way is still
  done.

  The accounting for this takes up more memory when function graph
  tracing is activated, as it needs to keep track of which functions it
  uses.  I have a new way that wont take as much memory, but it's not
  ready yet for this merge window, and will have to wait for the next
  one.

  Another big change was the removal of the ftrace_start/stop() calls
  that were used by the suspend/resume code that stopped function
  tracing when entering into suspend and resume paths.  The stop of
  ftrace was done because there was some function that would crash the
  system if one called smp_processor_id()! The stop/start was a big
  hammer to solve the issue at the time, which was when ftrace was first
  introduced into Linux.  Now ftrace has better infrastructure to debug
  such issues, and I found the problem function and labeled it with
  "notrace" and function tracing can now safely be activated all the way
  down into the guts of suspend and resume

  Other changes include clean ups of uprobe code, clean up of the
  trace_seq() code, and other various small fixes and clean ups to
  ftrace and tracing"

* tag 'trace-3.17' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: (57 commits)
  ftrace: Add warning if tramp hash does not match nr_trampolines
  ftrace: Fix trampoline hash update check on rec->flags
  ring-buffer: Use rb_page_size() instead of open coded head_page size
  ftrace: Rename ftrace_ops field from trampolines to nr_trampolines
  tracing: Convert local function_graph functions to static
  ftrace: Do not copy old hash when resetting
  tracing: let user specify tracing_thresh after selecting function_graph
  ring-buffer: Always run per-cpu ring buffer resize with schedule_work_on()
  tracing: Remove function_trace_stop and HAVE_FUNCTION_TRACE_MCOUNT_TEST
  s390/ftrace: remove check of obsolete variable function_trace_stop
  arm64, ftrace: Remove check of obsolete variable function_trace_stop
  Blackfin: ftrace: Remove check of obsolete variable function_trace_stop
  metag: ftrace: Remove check of obsolete variable function_trace_stop
  microblaze: ftrace: Remove check of obsolete variable function_trace_stop
  MIPS: ftrace: Remove check of obsolete variable function_trace_stop
  parisc: ftrace: Remove check of obsolete variable function_trace_stop
  sh: ftrace: Remove check of obsolete variable function_trace_stop
  sparc64,ftrace: Remove check of obsolete variable function_trace_stop
  tile: ftrace: Remove check of obsolete variable function_trace_stop
  ftrace: x86: Remove check of obsolete variable function_trace_stop
  ...
parents c7ed326f dc6f03f2
...@@ -1097,6 +1097,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted. ...@@ -1097,6 +1097,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
that can be changed at run time by the that can be changed at run time by the
set_graph_function file in the debugfs tracing directory. set_graph_function file in the debugfs tracing directory.
ftrace_graph_notrace=[function-list]
[FTRACE] Do not trace from the functions specified in
function-list. This list is a comma separated list of
functions that can be changed at run time by the
set_graph_notrace file in the debugfs tracing directory.
gamecon.map[2|3]= gamecon.map[2|3]=
[HW,JOY] Multisystem joystick and NES/SNES/PSX pad [HW,JOY] Multisystem joystick and NES/SNES/PSX pad
support via parallel port (up to 5 devices per port) support via parallel port (up to 5 devices per port)
......
...@@ -102,30 +102,6 @@ extern void mcount(void); ...@@ -102,30 +102,6 @@ extern void mcount(void);
EXPORT_SYMBOL(mcount); EXPORT_SYMBOL(mcount);
HAVE_FUNCTION_TRACE_MCOUNT_TEST
-------------------------------
This is an optional optimization for the normal case when tracing is turned off
in the system. If you do not enable this Kconfig option, the common ftrace
code will take care of doing the checking for you.
To support this feature, you only need to check the function_trace_stop
variable in the mcount function. If it is non-zero, there is no tracing to be
done at all, so you can return.
This additional pseudo code would simply be:
void mcount(void)
{
/* save any bare state needed in order to do initial checking */
+ if (function_trace_stop)
+ return;
extern void (*ftrace_trace_function)(unsigned long, unsigned long);
if (ftrace_trace_function != ftrace_stub)
...
HAVE_FUNCTION_GRAPH_TRACER HAVE_FUNCTION_GRAPH_TRACER
-------------------------- --------------------------
...@@ -328,8 +304,6 @@ void mcount(void) ...@@ -328,8 +304,6 @@ void mcount(void)
void ftrace_caller(void) void ftrace_caller(void)
{ {
/* implement HAVE_FUNCTION_TRACE_MCOUNT_TEST if you desire */
/* save all state needed by the ABI (see paragraph above) */ /* save all state needed by the ABI (see paragraph above) */
unsigned long frompc = ...; unsigned long frompc = ...;
......
...@@ -96,11 +96,6 @@ ...@@ -96,11 +96,6 @@
* - ftrace_graph_caller to set up an exit hook * - ftrace_graph_caller to set up an exit hook
*/ */
ENTRY(_mcount) ENTRY(_mcount)
#ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
ldr x0, =ftrace_trace_stop
ldr x0, [x0] // if ftrace_trace_stop
ret // return;
#endif
mcount_enter mcount_enter
ldr x0, =ftrace_trace_function ldr x0, =ftrace_trace_function
......
...@@ -18,7 +18,6 @@ config BLACKFIN ...@@ -18,7 +18,6 @@ config BLACKFIN
select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_TRACE_MCOUNT_TEST
select HAVE_IDE select HAVE_IDE
select HAVE_KERNEL_GZIP if RAMKERNEL select HAVE_KERNEL_GZIP if RAMKERNEL
select HAVE_KERNEL_BZIP2 if RAMKERNEL select HAVE_KERNEL_BZIP2 if RAMKERNEL
......
...@@ -33,15 +33,6 @@ ENDPROC(__mcount) ...@@ -33,15 +33,6 @@ ENDPROC(__mcount)
* function will be waiting there. mmmm pie. * function will be waiting there. mmmm pie.
*/ */
ENTRY(_ftrace_caller) ENTRY(_ftrace_caller)
# ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
/* optional micro optimization: return if stopped */
p1.l = _function_trace_stop;
p1.h = _function_trace_stop;
r3 = [p1];
cc = r3 == 0;
if ! cc jump _ftrace_stub (bp);
# endif
/* save first/second/third function arg and the return register */ /* save first/second/third function arg and the return register */
[--sp] = r2; [--sp] = r2;
[--sp] = r0; [--sp] = r0;
...@@ -83,15 +74,6 @@ ENDPROC(_ftrace_caller) ...@@ -83,15 +74,6 @@ ENDPROC(_ftrace_caller)
/* See documentation for _ftrace_caller */ /* See documentation for _ftrace_caller */
ENTRY(__mcount) ENTRY(__mcount)
# ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
/* optional micro optimization: return if stopped */
p1.l = _function_trace_stop;
p1.h = _function_trace_stop;
r3 = [p1];
cc = r3 == 0;
if ! cc jump _ftrace_stub (bp);
# endif
/* save third function arg early so we can do testing below */ /* save third function arg early so we can do testing below */
[--sp] = r2; [--sp] = r2;
......
...@@ -13,7 +13,6 @@ config METAG ...@@ -13,7 +13,6 @@ config METAG
select HAVE_DYNAMIC_FTRACE select HAVE_DYNAMIC_FTRACE
select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_TRACE_MCOUNT_TEST
select HAVE_KERNEL_BZIP2 select HAVE_KERNEL_BZIP2
select HAVE_KERNEL_GZIP select HAVE_KERNEL_GZIP
select HAVE_KERNEL_LZO select HAVE_KERNEL_LZO
......
...@@ -16,13 +16,6 @@ _mcount_wrapper: ...@@ -16,13 +16,6 @@ _mcount_wrapper:
.global _ftrace_caller .global _ftrace_caller
.type _ftrace_caller,function .type _ftrace_caller,function
_ftrace_caller: _ftrace_caller:
MOVT D0Re0,#HI(_function_trace_stop)
ADD D0Re0,D0Re0,#LO(_function_trace_stop)
GETD D0Re0,[D0Re0]
CMP D0Re0,#0
BEQ $Lcall_stub
MOV PC,D0.4
$Lcall_stub:
MSETL [A0StP], D0Ar6, D0Ar4, D0Ar2, D0.4 MSETL [A0StP], D0Ar6, D0Ar4, D0Ar2, D0.4
MOV D1Ar1, D0.4 MOV D1Ar1, D0.4
MOV D0Ar2, D1RtP MOV D0Ar2, D1RtP
...@@ -42,13 +35,6 @@ _ftrace_call: ...@@ -42,13 +35,6 @@ _ftrace_call:
.global _mcount_wrapper .global _mcount_wrapper
.type _mcount_wrapper,function .type _mcount_wrapper,function
_mcount_wrapper: _mcount_wrapper:
MOVT D0Re0,#HI(_function_trace_stop)
ADD D0Re0,D0Re0,#LO(_function_trace_stop)
GETD D0Re0,[D0Re0]
CMP D0Re0,#0
BEQ $Lcall_mcount
MOV PC,D0.4
$Lcall_mcount:
MSETL [A0StP], D0Ar6, D0Ar4, D0Ar2, D0.4 MSETL [A0StP], D0Ar6, D0Ar4, D0Ar2, D0.4
MOV D1Ar1, D0.4 MOV D1Ar1, D0.4
MOV D0Ar2, D1RtP MOV D0Ar2, D1RtP
......
...@@ -22,7 +22,6 @@ config MICROBLAZE ...@@ -22,7 +22,6 @@ config MICROBLAZE
select HAVE_DYNAMIC_FTRACE select HAVE_DYNAMIC_FTRACE
select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_FUNCTION_TRACE_MCOUNT_TEST
select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_TRACER
select HAVE_MEMBLOCK select HAVE_MEMBLOCK
select HAVE_MEMBLOCK_NODE_MAP select HAVE_MEMBLOCK_NODE_MAP
......
...@@ -27,6 +27,9 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) ...@@ -27,6 +27,9 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
unsigned long return_hooker = (unsigned long) unsigned long return_hooker = (unsigned long)
&return_to_handler; &return_to_handler;
if (unlikely(ftrace_graph_is_dead()))
return;
if (unlikely(atomic_read(&current->tracing_graph_pause))) if (unlikely(atomic_read(&current->tracing_graph_pause)))
return; return;
......
...@@ -91,11 +91,6 @@ ENTRY(ftrace_caller) ...@@ -91,11 +91,6 @@ ENTRY(ftrace_caller)
#endif /* CONFIG_DYNAMIC_FTRACE */ #endif /* CONFIG_DYNAMIC_FTRACE */
SAVE_REGS SAVE_REGS
swi r15, r1, 0; swi r15, r1, 0;
/* MS: HAVE_FUNCTION_TRACE_MCOUNT_TEST begin of checking */
lwi r5, r0, function_trace_stop;
bneid r5, end;
nop;
/* MS: HAVE_FUNCTION_TRACE_MCOUNT_TEST end of checking */
#ifdef CONFIG_FUNCTION_GRAPH_TRACER #ifdef CONFIG_FUNCTION_GRAPH_TRACER
#ifndef CONFIG_DYNAMIC_FTRACE #ifndef CONFIG_DYNAMIC_FTRACE
lwi r5, r0, ftrace_graph_return; lwi r5, r0, ftrace_graph_return;
......
...@@ -15,7 +15,6 @@ config MIPS ...@@ -15,7 +15,6 @@ config MIPS
select HAVE_BPF_JIT if !CPU_MICROMIPS select HAVE_BPF_JIT if !CPU_MICROMIPS
select ARCH_HAVE_CUSTOM_GPIO_H select ARCH_HAVE_CUSTOM_GPIO_H
select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_TRACE_MCOUNT_TEST
select HAVE_DYNAMIC_FTRACE select HAVE_DYNAMIC_FTRACE
select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_C_RECORDMCOUNT select HAVE_C_RECORDMCOUNT
......
...@@ -302,6 +302,9 @@ void prepare_ftrace_return(unsigned long *parent_ra_addr, unsigned long self_ra, ...@@ -302,6 +302,9 @@ void prepare_ftrace_return(unsigned long *parent_ra_addr, unsigned long self_ra,
&return_to_handler; &return_to_handler;
int faulted, insns; int faulted, insns;
if (unlikely(ftrace_graph_is_dead()))
return;
if (unlikely(atomic_read(&current->tracing_graph_pause))) if (unlikely(atomic_read(&current->tracing_graph_pause)))
return; return;
......
...@@ -74,10 +74,6 @@ _mcount: ...@@ -74,10 +74,6 @@ _mcount:
#endif #endif
/* When tracing is activated, it calls ftrace_caller+8 (aka here) */ /* When tracing is activated, it calls ftrace_caller+8 (aka here) */
lw t1, function_trace_stop
bnez t1, ftrace_stub
nop
MCOUNT_SAVE_REGS MCOUNT_SAVE_REGS
#ifdef KBUILD_MCOUNT_RA_ADDRESS #ifdef KBUILD_MCOUNT_RA_ADDRESS
PTR_S MCOUNT_RA_ADDRESS_REG, PT_R12(sp) PTR_S MCOUNT_RA_ADDRESS_REG, PT_R12(sp)
...@@ -105,9 +101,6 @@ ftrace_stub: ...@@ -105,9 +101,6 @@ ftrace_stub:
#else /* ! CONFIG_DYNAMIC_FTRACE */ #else /* ! CONFIG_DYNAMIC_FTRACE */
NESTED(_mcount, PT_SIZE, ra) NESTED(_mcount, PT_SIZE, ra)
lw t1, function_trace_stop
bnez t1, ftrace_stub
nop
PTR_LA t1, ftrace_stub PTR_LA t1, ftrace_stub
PTR_L t2, ftrace_trace_function /* Prepare t2 for (1) */ PTR_L t2, ftrace_trace_function /* Prepare t2 for (1) */
bne t1, t2, static_trace bne t1, t2, static_trace
......
...@@ -6,7 +6,6 @@ config PARISC ...@@ -6,7 +6,6 @@ config PARISC
select HAVE_OPROFILE select HAVE_OPROFILE
select HAVE_FUNCTION_TRACER if 64BIT select HAVE_FUNCTION_TRACER if 64BIT
select HAVE_FUNCTION_GRAPH_TRACER if 64BIT select HAVE_FUNCTION_GRAPH_TRACER if 64BIT
select HAVE_FUNCTION_TRACE_MCOUNT_TEST if 64BIT
select ARCH_WANT_FRAME_POINTERS select ARCH_WANT_FRAME_POINTERS
select RTC_CLASS select RTC_CLASS
select RTC_DRV_GENERIC select RTC_DRV_GENERIC
......
...@@ -112,6 +112,9 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) ...@@ -112,6 +112,9 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
unsigned long long calltime; unsigned long long calltime;
struct ftrace_graph_ent trace; struct ftrace_graph_ent trace;
if (unlikely(ftrace_graph_is_dead()))
return;
if (unlikely(atomic_read(&current->tracing_graph_pause))) if (unlikely(atomic_read(&current->tracing_graph_pause)))
return; return;
...@@ -152,9 +155,6 @@ void ftrace_function_trampoline(unsigned long parent, ...@@ -152,9 +155,6 @@ void ftrace_function_trampoline(unsigned long parent,
{ {
extern ftrace_func_t ftrace_trace_function; extern ftrace_func_t ftrace_trace_function;
if (function_trace_stop)
return;
if (ftrace_trace_function != ftrace_stub) { if (ftrace_trace_function != ftrace_stub) {
ftrace_trace_function(parent, self_addr); ftrace_trace_function(parent, self_addr);
return; return;
......
...@@ -525,6 +525,9 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) ...@@ -525,6 +525,9 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
struct ftrace_graph_ent trace; struct ftrace_graph_ent trace;
unsigned long return_hooker = (unsigned long)&return_to_handler; unsigned long return_hooker = (unsigned long)&return_to_handler;
if (unlikely(ftrace_graph_is_dead()))
return;
if (unlikely(atomic_read(&current->tracing_graph_pause))) if (unlikely(atomic_read(&current->tracing_graph_pause)))
return; return;
......
...@@ -116,7 +116,6 @@ config S390 ...@@ -116,7 +116,6 @@ config S390
select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_TRACE_MCOUNT_TEST
select HAVE_FUTEX_CMPXCHG if FUTEX select HAVE_FUTEX_CMPXCHG if FUTEX
select HAVE_KERNEL_BZIP2 select HAVE_KERNEL_BZIP2
select HAVE_KERNEL_GZIP select HAVE_KERNEL_GZIP
......
...@@ -21,13 +21,9 @@ ENTRY(_mcount) ...@@ -21,13 +21,9 @@ ENTRY(_mcount)
ENTRY(ftrace_caller) ENTRY(ftrace_caller)
#endif #endif
stm %r2,%r5,16(%r15) stm %r2,%r5,16(%r15)
bras %r1,2f bras %r1,1f
0: .long ftrace_trace_function 0: .long ftrace_trace_function
1: .long function_trace_stop 1: st %r14,56(%r15)
2: l %r2,1b-0b(%r1)
icm %r2,0xf,0(%r2)
jnz 3f
st %r14,56(%r15)
lr %r0,%r15 lr %r0,%r15
ahi %r15,-96 ahi %r15,-96
l %r3,100(%r15) l %r3,100(%r15)
...@@ -50,7 +46,7 @@ ENTRY(ftrace_graph_caller) ...@@ -50,7 +46,7 @@ ENTRY(ftrace_graph_caller)
#endif #endif
ahi %r15,96 ahi %r15,96
l %r14,56(%r15) l %r14,56(%r15)
3: lm %r2,%r5,16(%r15) lm %r2,%r5,16(%r15)
br %r14 br %r14
#ifdef CONFIG_FUNCTION_GRAPH_TRACER #ifdef CONFIG_FUNCTION_GRAPH_TRACER
......
...@@ -20,9 +20,6 @@ ENTRY(_mcount) ...@@ -20,9 +20,6 @@ ENTRY(_mcount)
ENTRY(ftrace_caller) ENTRY(ftrace_caller)
#endif #endif
larl %r1,function_trace_stop
icm %r1,0xf,0(%r1)
bnzr %r14
stmg %r2,%r5,32(%r15) stmg %r2,%r5,32(%r15)
stg %r14,112(%r15) stg %r14,112(%r15)
lgr %r1,%r15 lgr %r1,%r15
......
...@@ -57,7 +57,6 @@ config SUPERH32 ...@@ -57,7 +57,6 @@ config SUPERH32
select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_TRACER
select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_DYNAMIC_FTRACE select HAVE_DYNAMIC_FTRACE
select HAVE_FUNCTION_TRACE_MCOUNT_TEST
select HAVE_FTRACE_NMI_ENTER if DYNAMIC_FTRACE select HAVE_FTRACE_NMI_ENTER if DYNAMIC_FTRACE
select ARCH_WANT_IPC_PARSE_VERSION select ARCH_WANT_IPC_PARSE_VERSION
select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_GRAPH_TRACER
......
...@@ -344,6 +344,9 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) ...@@ -344,6 +344,9 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
struct ftrace_graph_ent trace; struct ftrace_graph_ent trace;
unsigned long return_hooker = (unsigned long)&return_to_handler; unsigned long return_hooker = (unsigned long)&return_to_handler;
if (unlikely(ftrace_graph_is_dead()))
return;
if (unlikely(atomic_read(&current->tracing_graph_pause))) if (unlikely(atomic_read(&current->tracing_graph_pause)))
return; return;
......
...@@ -92,13 +92,6 @@ mcount: ...@@ -92,13 +92,6 @@ mcount:
rts rts
nop nop
#else #else
#ifndef CONFIG_DYNAMIC_FTRACE
mov.l .Lfunction_trace_stop, r0
mov.l @r0, r0
tst r0, r0
bf ftrace_stub
#endif
MCOUNT_ENTER() MCOUNT_ENTER()
#ifdef CONFIG_DYNAMIC_FTRACE #ifdef CONFIG_DYNAMIC_FTRACE
...@@ -174,11 +167,6 @@ ftrace_graph_call: ...@@ -174,11 +167,6 @@ ftrace_graph_call:
.globl ftrace_caller .globl ftrace_caller
ftrace_caller: ftrace_caller:
mov.l .Lfunction_trace_stop, r0
mov.l @r0, r0
tst r0, r0
bf ftrace_stub
MCOUNT_ENTER() MCOUNT_ENTER()
.globl ftrace_call .globl ftrace_call
...@@ -196,8 +184,6 @@ ftrace_call: ...@@ -196,8 +184,6 @@ ftrace_call:
#endif /* CONFIG_DYNAMIC_FTRACE */ #endif /* CONFIG_DYNAMIC_FTRACE */
.align 2 .align 2
.Lfunction_trace_stop:
.long function_trace_stop
/* /*
* NOTE: From here on the locations of the .Lftrace_stub label and * NOTE: From here on the locations of the .Lftrace_stub label and
...@@ -217,12 +203,7 @@ ftrace_stub: ...@@ -217,12 +203,7 @@ ftrace_stub:
#ifdef CONFIG_FUNCTION_GRAPH_TRACER #ifdef CONFIG_FUNCTION_GRAPH_TRACER
.globl ftrace_graph_caller .globl ftrace_graph_caller
ftrace_graph_caller: ftrace_graph_caller:
mov.l 2f, r0 mov.l 2f, r1
mov.l @r0, r0
tst r0, r0
bt 1f
mov.l 3f, r1
jmp @r1 jmp @r1
nop nop
1: 1:
...@@ -242,8 +223,7 @@ ftrace_graph_caller: ...@@ -242,8 +223,7 @@ ftrace_graph_caller:
MCOUNT_LEAVE() MCOUNT_LEAVE()
.align 2 .align 2
2: .long function_trace_stop 2: .long skip_trace
3: .long skip_trace
.Lprepare_ftrace_return: .Lprepare_ftrace_return:
.long prepare_ftrace_return .long prepare_ftrace_return
......
...@@ -55,7 +55,6 @@ config SPARC64 ...@@ -55,7 +55,6 @@ config SPARC64
select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_FUNCTION_GRAPH_FP_TEST select HAVE_FUNCTION_GRAPH_FP_TEST
select HAVE_FUNCTION_TRACE_MCOUNT_TEST
select HAVE_KRETPROBES select HAVE_KRETPROBES
select HAVE_KPROBES select HAVE_KPROBES
select HAVE_RCU_TABLE_FREE if SMP select HAVE_RCU_TABLE_FREE if SMP
......
...@@ -24,9 +24,6 @@ mcount: ...@@ -24,9 +24,6 @@ mcount:
#ifdef CONFIG_DYNAMIC_FTRACE #ifdef CONFIG_DYNAMIC_FTRACE
/* Do nothing, the retl/nop below is all we need. */ /* Do nothing, the retl/nop below is all we need. */
#else #else
sethi %hi(function_trace_stop), %g1
lduw [%g1 + %lo(function_trace_stop)], %g2
brnz,pn %g2, 2f
sethi %hi(ftrace_trace_function), %g1 sethi %hi(ftrace_trace_function), %g1
sethi %hi(ftrace_stub), %g2 sethi %hi(ftrace_stub), %g2
ldx [%g1 + %lo(ftrace_trace_function)], %g1 ldx [%g1 + %lo(ftrace_trace_function)], %g1
...@@ -80,10 +77,7 @@ ftrace_stub: ...@@ -80,10 +77,7 @@ ftrace_stub:
.globl ftrace_caller .globl ftrace_caller
.type ftrace_caller,#function .type ftrace_caller,#function
ftrace_caller: ftrace_caller:
sethi %hi(function_trace_stop), %g1
mov %i7, %g2 mov %i7, %g2
lduw [%g1 + %lo(function_trace_stop)], %g1
brnz,pn %g1, ftrace_stub
mov %fp, %g3 mov %fp, %g3
save %sp, -176, %sp save %sp, -176, %sp
mov %g2, %o1 mov %g2, %o1
......
...@@ -128,7 +128,6 @@ config TILEGX ...@@ -128,7 +128,6 @@ config TILEGX
select SPARSE_IRQ select SPARSE_IRQ
select GENERIC_IRQ_LEGACY_ALLOC_HWIRQ select GENERIC_IRQ_LEGACY_ALLOC_HWIRQ
select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_TRACE_MCOUNT_TEST
select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_DYNAMIC_FTRACE select HAVE_DYNAMIC_FTRACE
select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FTRACE_MCOUNT_RECORD
......
...@@ -77,15 +77,6 @@ STD_ENDPROC(__mcount) ...@@ -77,15 +77,6 @@ STD_ENDPROC(__mcount)
.align 64 .align 64
STD_ENTRY(ftrace_caller) STD_ENTRY(ftrace_caller)
moveli r11, hw2_last(function_trace_stop)
{ shl16insli r11, r11, hw1(function_trace_stop); move r12, lr }
{ shl16insli r11, r11, hw0(function_trace_stop); move lr, r10 }
ld r11, r11
beqz r11, 1f
jrp r12
1:
{ move r10, lr; move lr, r12 }
MCOUNT_SAVE_REGS MCOUNT_SAVE_REGS
/* arg1: self return address */ /* arg1: self return address */
...@@ -119,15 +110,6 @@ STD_ENDPROC(ftrace_caller) ...@@ -119,15 +110,6 @@ STD_ENDPROC(ftrace_caller)
.align 64 .align 64
STD_ENTRY(__mcount) STD_ENTRY(__mcount)
moveli r11, hw2_last(function_trace_stop)
{ shl16insli r11, r11, hw1(function_trace_stop); move r12, lr }
{ shl16insli r11, r11, hw0(function_trace_stop); move lr, r10 }
ld r11, r11
beqz r11, 1f
jrp r12
1:
{ move r10, lr; move lr, r12 }
{ {
moveli r11, hw2_last(ftrace_trace_function) moveli r11, hw2_last(ftrace_trace_function)
moveli r13, hw2_last(ftrace_stub) moveli r13, hw2_last(ftrace_stub)
......
...@@ -54,7 +54,6 @@ config X86 ...@@ -54,7 +54,6 @@ config X86
select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_FUNCTION_GRAPH_FP_TEST select HAVE_FUNCTION_GRAPH_FP_TEST
select HAVE_FUNCTION_TRACE_MCOUNT_TEST
select HAVE_SYSCALL_TRACEPOINTS select HAVE_SYSCALL_TRACEPOINTS
select SYSCTL_EXCEPTION_TRACE select SYSCTL_EXCEPTION_TRACE
select HAVE_KVM select HAVE_KVM
......
...@@ -68,6 +68,8 @@ struct dyn_arch_ftrace { ...@@ -68,6 +68,8 @@ struct dyn_arch_ftrace {
int ftrace_int3_handler(struct pt_regs *regs); int ftrace_int3_handler(struct pt_regs *regs);
#define FTRACE_GRAPH_TRAMP_ADDR FTRACE_GRAPH_ADDR
#endif /* CONFIG_DYNAMIC_FTRACE */ #endif /* CONFIG_DYNAMIC_FTRACE */
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#endif /* CONFIG_FUNCTION_TRACER */ #endif /* CONFIG_FUNCTION_TRACER */
......
...@@ -1059,9 +1059,6 @@ ENTRY(mcount) ...@@ -1059,9 +1059,6 @@ ENTRY(mcount)
END(mcount) END(mcount)
ENTRY(ftrace_caller) ENTRY(ftrace_caller)
cmpl $0, function_trace_stop
jne ftrace_stub
pushl %eax pushl %eax
pushl %ecx pushl %ecx
pushl %edx pushl %edx
...@@ -1093,8 +1090,6 @@ END(ftrace_caller) ...@@ -1093,8 +1090,6 @@ END(ftrace_caller)
ENTRY(ftrace_regs_caller) ENTRY(ftrace_regs_caller)
pushf /* push flags before compare (in cs location) */ pushf /* push flags before compare (in cs location) */
cmpl $0, function_trace_stop
jne ftrace_restore_flags
/* /*
* i386 does not save SS and ESP when coming from kernel. * i386 does not save SS and ESP when coming from kernel.
...@@ -1153,7 +1148,6 @@ GLOBAL(ftrace_regs_call) ...@@ -1153,7 +1148,6 @@ GLOBAL(ftrace_regs_call)
popf /* Pop flags at end (no addl to corrupt flags) */ popf /* Pop flags at end (no addl to corrupt flags) */
jmp ftrace_ret jmp ftrace_ret
ftrace_restore_flags:
popf popf
jmp ftrace_stub jmp ftrace_stub
#else /* ! CONFIG_DYNAMIC_FTRACE */ #else /* ! CONFIG_DYNAMIC_FTRACE */
...@@ -1162,9 +1156,6 @@ ENTRY(mcount) ...@@ -1162,9 +1156,6 @@ ENTRY(mcount)
cmpl $__PAGE_OFFSET, %esp cmpl $__PAGE_OFFSET, %esp
jb ftrace_stub /* Paging not enabled yet? */ jb ftrace_stub /* Paging not enabled yet? */
cmpl $0, function_trace_stop
jne ftrace_stub
cmpl $ftrace_stub, ftrace_trace_function cmpl $ftrace_stub, ftrace_trace_function
jnz trace jnz trace
#ifdef CONFIG_FUNCTION_GRAPH_TRACER #ifdef CONFIG_FUNCTION_GRAPH_TRACER
......
...@@ -703,6 +703,9 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, ...@@ -703,6 +703,9 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
unsigned long return_hooker = (unsigned long) unsigned long return_hooker = (unsigned long)
&return_to_handler; &return_to_handler;
if (unlikely(ftrace_graph_is_dead()))
return;
if (unlikely(atomic_read(&current->tracing_graph_pause))) if (unlikely(atomic_read(&current->tracing_graph_pause)))
return; return;
......
...@@ -46,10 +46,6 @@ END(function_hook) ...@@ -46,10 +46,6 @@ END(function_hook)
.endm .endm
ENTRY(ftrace_caller) ENTRY(ftrace_caller)
/* Check if tracing was disabled (quick check) */
cmpl $0, function_trace_stop
jne ftrace_stub
ftrace_caller_setup ftrace_caller_setup
/* regs go into 4th parameter (but make it NULL) */ /* regs go into 4th parameter (but make it NULL) */
movq $0, %rcx movq $0, %rcx
...@@ -73,10 +69,6 @@ ENTRY(ftrace_regs_caller) ...@@ -73,10 +69,6 @@ ENTRY(ftrace_regs_caller)
/* Save the current flags before compare (in SS location)*/ /* Save the current flags before compare (in SS location)*/
pushfq pushfq
/* Check if tracing was disabled (quick check) */
cmpl $0, function_trace_stop
jne ftrace_restore_flags
/* skip=8 to skip flags saved in SS */ /* skip=8 to skip flags saved in SS */
ftrace_caller_setup 8 ftrace_caller_setup 8
...@@ -131,7 +123,7 @@ GLOBAL(ftrace_regs_call) ...@@ -131,7 +123,7 @@ GLOBAL(ftrace_regs_call)
popfq popfq
jmp ftrace_return jmp ftrace_return
ftrace_restore_flags:
popfq popfq
jmp ftrace_stub jmp ftrace_stub
...@@ -141,9 +133,6 @@ END(ftrace_regs_caller) ...@@ -141,9 +133,6 @@ END(ftrace_regs_caller)
#else /* ! CONFIG_DYNAMIC_FTRACE */ #else /* ! CONFIG_DYNAMIC_FTRACE */
ENTRY(function_hook) ENTRY(function_hook)
cmpl $0, function_trace_stop
jne ftrace_stub
cmpq $ftrace_stub, ftrace_trace_function cmpq $ftrace_stub, ftrace_trace_function
jnz trace jnz trace
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
__entry->unsync = sp->unsync; __entry->unsync = sp->unsync;
#define KVM_MMU_PAGE_PRINTK() ({ \ #define KVM_MMU_PAGE_PRINTK() ({ \
const char *ret = p->buffer + p->len; \ const char *ret = trace_seq_buffer_ptr(p); \
static const char *access_str[] = { \ static const char *access_str[] = { \
"---", "--x", "w--", "w-x", "-u-", "-ux", "wu-", "wux" \ "---", "--x", "w--", "w-x", "-u-", "-ux", "wu-", "wux" \
}; \ }; \
......
...@@ -165,7 +165,7 @@ static void fix_processor_context(void) ...@@ -165,7 +165,7 @@ static void fix_processor_context(void)
* by __save_processor_state() * by __save_processor_state()
* @ctxt - structure to load the registers contents from * @ctxt - structure to load the registers contents from
*/ */
static void __restore_processor_state(struct saved_context *ctxt) static void notrace __restore_processor_state(struct saved_context *ctxt)
{ {
if (ctxt->misc_enable_saved) if (ctxt->misc_enable_saved)
wrmsrl(MSR_IA32_MISC_ENABLE, ctxt->misc_enable); wrmsrl(MSR_IA32_MISC_ENABLE, ctxt->misc_enable);
...@@ -239,7 +239,7 @@ static void __restore_processor_state(struct saved_context *ctxt) ...@@ -239,7 +239,7 @@ static void __restore_processor_state(struct saved_context *ctxt)
} }
/* Needed by apm.c */ /* Needed by apm.c */
void restore_processor_state(void) void notrace restore_processor_state(void)
{ {
__restore_processor_state(&saved_context); __restore_processor_state(&saved_context);
} }
......
...@@ -28,7 +28,7 @@ scsi_trace_misc(struct trace_seq *, unsigned char *, int); ...@@ -28,7 +28,7 @@ scsi_trace_misc(struct trace_seq *, unsigned char *, int);
static const char * static const char *
scsi_trace_rw6(struct trace_seq *p, unsigned char *cdb, int len) scsi_trace_rw6(struct trace_seq *p, unsigned char *cdb, int len)
{ {
const char *ret = p->buffer + p->len; const char *ret = trace_seq_buffer_ptr(p);
sector_t lba = 0, txlen = 0; sector_t lba = 0, txlen = 0;
lba |= ((cdb[1] & 0x1F) << 16); lba |= ((cdb[1] & 0x1F) << 16);
...@@ -46,7 +46,7 @@ scsi_trace_rw6(struct trace_seq *p, unsigned char *cdb, int len) ...@@ -46,7 +46,7 @@ scsi_trace_rw6(struct trace_seq *p, unsigned char *cdb, int len)
static const char * static const char *
scsi_trace_rw10(struct trace_seq *p, unsigned char *cdb, int len) scsi_trace_rw10(struct trace_seq *p, unsigned char *cdb, int len)
{ {
const char *ret = p->buffer + p->len; const char *ret = trace_seq_buffer_ptr(p);
sector_t lba = 0, txlen = 0; sector_t lba = 0, txlen = 0;
lba |= (cdb[2] << 24); lba |= (cdb[2] << 24);
...@@ -71,7 +71,7 @@ scsi_trace_rw10(struct trace_seq *p, unsigned char *cdb, int len) ...@@ -71,7 +71,7 @@ scsi_trace_rw10(struct trace_seq *p, unsigned char *cdb, int len)
static const char * static const char *
scsi_trace_rw12(struct trace_seq *p, unsigned char *cdb, int len) scsi_trace_rw12(struct trace_seq *p, unsigned char *cdb, int len)
{ {
const char *ret = p->buffer + p->len; const char *ret = trace_seq_buffer_ptr(p);
sector_t lba = 0, txlen = 0; sector_t lba = 0, txlen = 0;
lba |= (cdb[2] << 24); lba |= (cdb[2] << 24);
...@@ -94,7 +94,7 @@ scsi_trace_rw12(struct trace_seq *p, unsigned char *cdb, int len) ...@@ -94,7 +94,7 @@ scsi_trace_rw12(struct trace_seq *p, unsigned char *cdb, int len)
static const char * static const char *
scsi_trace_rw16(struct trace_seq *p, unsigned char *cdb, int len) scsi_trace_rw16(struct trace_seq *p, unsigned char *cdb, int len)
{ {
const char *ret = p->buffer + p->len; const char *ret = trace_seq_buffer_ptr(p);
sector_t lba = 0, txlen = 0; sector_t lba = 0, txlen = 0;
lba |= ((u64)cdb[2] << 56); lba |= ((u64)cdb[2] << 56);
...@@ -125,7 +125,7 @@ scsi_trace_rw16(struct trace_seq *p, unsigned char *cdb, int len) ...@@ -125,7 +125,7 @@ scsi_trace_rw16(struct trace_seq *p, unsigned char *cdb, int len)
static const char * static const char *
scsi_trace_rw32(struct trace_seq *p, unsigned char *cdb, int len) scsi_trace_rw32(struct trace_seq *p, unsigned char *cdb, int len)
{ {
const char *ret = p->buffer + p->len, *cmd; const char *ret = trace_seq_buffer_ptr(p), *cmd;
sector_t lba = 0, txlen = 0; sector_t lba = 0, txlen = 0;
u32 ei_lbrt = 0; u32 ei_lbrt = 0;
...@@ -180,7 +180,7 @@ scsi_trace_rw32(struct trace_seq *p, unsigned char *cdb, int len) ...@@ -180,7 +180,7 @@ scsi_trace_rw32(struct trace_seq *p, unsigned char *cdb, int len)
static const char * static const char *
scsi_trace_unmap(struct trace_seq *p, unsigned char *cdb, int len) scsi_trace_unmap(struct trace_seq *p, unsigned char *cdb, int len)
{ {
const char *ret = p->buffer + p->len; const char *ret = trace_seq_buffer_ptr(p);
unsigned int regions = cdb[7] << 8 | cdb[8]; unsigned int regions = cdb[7] << 8 | cdb[8];
trace_seq_printf(p, "regions=%u", (regions - 8) / 16); trace_seq_printf(p, "regions=%u", (regions - 8) / 16);
...@@ -192,7 +192,7 @@ scsi_trace_unmap(struct trace_seq *p, unsigned char *cdb, int len) ...@@ -192,7 +192,7 @@ scsi_trace_unmap(struct trace_seq *p, unsigned char *cdb, int len)
static const char * static const char *
scsi_trace_service_action_in(struct trace_seq *p, unsigned char *cdb, int len) scsi_trace_service_action_in(struct trace_seq *p, unsigned char *cdb, int len)
{ {
const char *ret = p->buffer + p->len, *cmd; const char *ret = trace_seq_buffer_ptr(p), *cmd;
sector_t lba = 0; sector_t lba = 0;
u32 alloc_len = 0; u32 alloc_len = 0;
...@@ -247,7 +247,7 @@ scsi_trace_varlen(struct trace_seq *p, unsigned char *cdb, int len) ...@@ -247,7 +247,7 @@ scsi_trace_varlen(struct trace_seq *p, unsigned char *cdb, int len)
static const char * static const char *
scsi_trace_misc(struct trace_seq *p, unsigned char *cdb, int len) scsi_trace_misc(struct trace_seq *p, unsigned char *cdb, int len)
{ {
const char *ret = p->buffer + p->len; const char *ret = trace_seq_buffer_ptr(p);
trace_seq_printf(p, "-"); trace_seq_printf(p, "-");
trace_seq_putc(p, 0); trace_seq_putc(p, 0);
......
...@@ -33,8 +33,7 @@ ...@@ -33,8 +33,7 @@
* features, then it must call an indirect function that * features, then it must call an indirect function that
* does. Or at least does enough to prevent any unwelcomed side effects. * does. Or at least does enough to prevent any unwelcomed side effects.
*/ */
#if !defined(CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST) || \ #if !ARCH_SUPPORTS_FTRACE_OPS
!ARCH_SUPPORTS_FTRACE_OPS
# define FTRACE_FORCE_LIST_FUNC 1 # define FTRACE_FORCE_LIST_FUNC 1
#else #else
# define FTRACE_FORCE_LIST_FUNC 0 # define FTRACE_FORCE_LIST_FUNC 0
...@@ -118,17 +117,18 @@ struct ftrace_ops { ...@@ -118,17 +117,18 @@ struct ftrace_ops {
ftrace_func_t func; ftrace_func_t func;
struct ftrace_ops *next; struct ftrace_ops *next;
unsigned long flags; unsigned long flags;
int __percpu *disabled;
void *private; void *private;
int __percpu *disabled;
#ifdef CONFIG_DYNAMIC_FTRACE #ifdef CONFIG_DYNAMIC_FTRACE
int nr_trampolines;
struct ftrace_hash *notrace_hash; struct ftrace_hash *notrace_hash;
struct ftrace_hash *filter_hash; struct ftrace_hash *filter_hash;
struct ftrace_hash *tramp_hash;
struct mutex regex_lock; struct mutex regex_lock;
unsigned long trampoline;
#endif #endif
}; };
extern int function_trace_stop;
/* /*
* Type of the current tracing. * Type of the current tracing.
*/ */
...@@ -140,32 +140,6 @@ enum ftrace_tracing_type_t { ...@@ -140,32 +140,6 @@ enum ftrace_tracing_type_t {
/* Current tracing type, default is FTRACE_TYPE_ENTER */ /* Current tracing type, default is FTRACE_TYPE_ENTER */
extern enum ftrace_tracing_type_t ftrace_tracing_type; extern enum ftrace_tracing_type_t ftrace_tracing_type;
/**
* ftrace_stop - stop function tracer.
*
* A quick way to stop the function tracer. Note this an on off switch,
* it is not something that is recursive like preempt_disable.
* This does not disable the calling of mcount, it only stops the
* calling of functions from mcount.
*/
static inline void ftrace_stop(void)
{
function_trace_stop = 1;
}
/**
* ftrace_start - start the function tracer.
*
* This function is the inverse of ftrace_stop. This does not enable
* the function tracing if the function tracer is disabled. This only
* sets the function tracer flag to continue calling the functions
* from mcount.
*/
static inline void ftrace_start(void)
{
function_trace_stop = 0;
}
/* /*
* The ftrace_ops must be a static and should also * The ftrace_ops must be a static and should also
* be read_mostly. These functions do modify read_mostly variables * be read_mostly. These functions do modify read_mostly variables
...@@ -242,8 +216,6 @@ static inline int ftrace_nr_registered_ops(void) ...@@ -242,8 +216,6 @@ static inline int ftrace_nr_registered_ops(void)
} }
static inline void clear_ftrace_function(void) { } static inline void clear_ftrace_function(void) { }
static inline void ftrace_kill(void) { } static inline void ftrace_kill(void) { }
static inline void ftrace_stop(void) { }
static inline void ftrace_start(void) { }
#endif /* CONFIG_FUNCTION_TRACER */ #endif /* CONFIG_FUNCTION_TRACER */
#ifdef CONFIG_STACK_TRACER #ifdef CONFIG_STACK_TRACER
...@@ -317,13 +289,20 @@ extern int ftrace_nr_registered_ops(void); ...@@ -317,13 +289,20 @@ extern int ftrace_nr_registered_ops(void);
* from tracing that function. * from tracing that function.
*/ */
enum { enum {
FTRACE_FL_ENABLED = (1UL << 29), FTRACE_FL_ENABLED = (1UL << 31),
FTRACE_FL_REGS = (1UL << 30), FTRACE_FL_REGS = (1UL << 30),
FTRACE_FL_REGS_EN = (1UL << 31) FTRACE_FL_REGS_EN = (1UL << 29),
FTRACE_FL_TRAMP = (1UL << 28),
FTRACE_FL_TRAMP_EN = (1UL << 27),
}; };
#define FTRACE_FL_MASK (0x7UL << 29) #define FTRACE_REF_MAX_SHIFT 27
#define FTRACE_REF_MAX ((1UL << 29) - 1) #define FTRACE_FL_BITS 5
#define FTRACE_FL_MASKED_BITS ((1UL << FTRACE_FL_BITS) - 1)
#define FTRACE_FL_MASK (FTRACE_FL_MASKED_BITS << FTRACE_REF_MAX_SHIFT)
#define FTRACE_REF_MAX ((1UL << FTRACE_REF_MAX_SHIFT) - 1)
#define ftrace_rec_count(rec) ((rec)->flags & ~FTRACE_FL_MASK)
struct dyn_ftrace { struct dyn_ftrace {
unsigned long ip; /* address of mcount call-site */ unsigned long ip; /* address of mcount call-site */
...@@ -431,6 +410,10 @@ void ftrace_modify_all_code(int command); ...@@ -431,6 +410,10 @@ void ftrace_modify_all_code(int command);
#define FTRACE_ADDR ((unsigned long)ftrace_caller) #define FTRACE_ADDR ((unsigned long)ftrace_caller)
#endif #endif
#ifndef FTRACE_GRAPH_ADDR
#define FTRACE_GRAPH_ADDR ((unsigned long)ftrace_graph_caller)
#endif
#ifndef FTRACE_REGS_ADDR #ifndef FTRACE_REGS_ADDR
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
# define FTRACE_REGS_ADDR ((unsigned long)ftrace_regs_caller) # define FTRACE_REGS_ADDR ((unsigned long)ftrace_regs_caller)
...@@ -439,6 +422,16 @@ void ftrace_modify_all_code(int command); ...@@ -439,6 +422,16 @@ void ftrace_modify_all_code(int command);
#endif #endif
#endif #endif
/*
* If an arch would like functions that are only traced
* by the function graph tracer to jump directly to its own
* trampoline, then they can define FTRACE_GRAPH_TRAMP_ADDR
* to be that address to jump to.
*/
#ifndef FTRACE_GRAPH_TRAMP_ADDR
#define FTRACE_GRAPH_TRAMP_ADDR ((unsigned long) 0)
#endif
#ifdef CONFIG_FUNCTION_GRAPH_TRACER #ifdef CONFIG_FUNCTION_GRAPH_TRACER
extern void ftrace_graph_caller(void); extern void ftrace_graph_caller(void);
extern int ftrace_enable_ftrace_graph_caller(void); extern int ftrace_enable_ftrace_graph_caller(void);
...@@ -736,6 +729,7 @@ extern char __irqentry_text_end[]; ...@@ -736,6 +729,7 @@ extern char __irqentry_text_end[];
extern int register_ftrace_graph(trace_func_graph_ret_t retfunc, extern int register_ftrace_graph(trace_func_graph_ret_t retfunc,
trace_func_graph_ent_t entryfunc); trace_func_graph_ent_t entryfunc);
extern bool ftrace_graph_is_dead(void);
extern void ftrace_graph_stop(void); extern void ftrace_graph_stop(void);
/* The current handlers in use */ /* The current handlers in use */
......
...@@ -25,6 +25,21 @@ trace_seq_init(struct trace_seq *s) ...@@ -25,6 +25,21 @@ trace_seq_init(struct trace_seq *s)
s->full = 0; s->full = 0;
} }
/**
* trace_seq_buffer_ptr - return pointer to next location in buffer
* @s: trace sequence descriptor
*
* Returns the pointer to the buffer where the next write to
* the buffer will happen. This is useful to save the location
* that is about to be written to and then return the result
* of that write.
*/
static inline unsigned char *
trace_seq_buffer_ptr(struct trace_seq *s)
{
return s->buffer + s->len;
}
/* /*
* Currently only defined when tracing is enabled. * Currently only defined when tracing is enabled.
*/ */
...@@ -36,14 +51,13 @@ int trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args); ...@@ -36,14 +51,13 @@ int trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args);
extern int extern int
trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary); trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary);
extern int trace_print_seq(struct seq_file *m, struct trace_seq *s); extern int trace_print_seq(struct seq_file *m, struct trace_seq *s);
extern ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, extern int trace_seq_to_user(struct trace_seq *s, char __user *ubuf,
size_t cnt); int cnt);
extern int trace_seq_puts(struct trace_seq *s, const char *str); extern int trace_seq_puts(struct trace_seq *s, const char *str);
extern int trace_seq_putc(struct trace_seq *s, unsigned char c); extern int trace_seq_putc(struct trace_seq *s, unsigned char c);
extern int trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len); extern int trace_seq_putmem(struct trace_seq *s, const void *mem, unsigned int len);
extern int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, extern int trace_seq_putmem_hex(struct trace_seq *s, const void *mem,
size_t len); unsigned int len);
extern void *trace_seq_reserve(struct trace_seq *s, size_t len);
extern int trace_seq_path(struct trace_seq *s, const struct path *path); extern int trace_seq_path(struct trace_seq *s, const struct path *path);
extern int trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp, extern int trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp,
...@@ -71,8 +85,8 @@ static inline int trace_print_seq(struct seq_file *m, struct trace_seq *s) ...@@ -71,8 +85,8 @@ static inline int trace_print_seq(struct seq_file *m, struct trace_seq *s)
{ {
return 0; return 0;
} }
static inline ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, static inline int trace_seq_to_user(struct trace_seq *s, char __user *ubuf,
size_t cnt) int cnt)
{ {
return 0; return 0;
} }
...@@ -85,19 +99,15 @@ static inline int trace_seq_putc(struct trace_seq *s, unsigned char c) ...@@ -85,19 +99,15 @@ static inline int trace_seq_putc(struct trace_seq *s, unsigned char c)
return 0; return 0;
} }
static inline int static inline int
trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len) trace_seq_putmem(struct trace_seq *s, const void *mem, unsigned int len)
{ {
return 0; return 0;
} }
static inline int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, static inline int trace_seq_putmem_hex(struct trace_seq *s, const void *mem,
size_t len) unsigned int len)
{ {
return 0; return 0;
} }
static inline void *trace_seq_reserve(struct trace_seq *s, size_t len)
{
return NULL;
}
static inline int trace_seq_path(struct trace_seq *s, const struct path *path) static inline int trace_seq_path(struct trace_seq *s, const struct path *path)
{ {
return 0; return 0;
......
...@@ -371,7 +371,6 @@ int hibernation_snapshot(int platform_mode) ...@@ -371,7 +371,6 @@ int hibernation_snapshot(int platform_mode)
} }
suspend_console(); suspend_console();
ftrace_stop();
pm_restrict_gfp_mask(); pm_restrict_gfp_mask();
error = dpm_suspend(PMSG_FREEZE); error = dpm_suspend(PMSG_FREEZE);
...@@ -397,7 +396,6 @@ int hibernation_snapshot(int platform_mode) ...@@ -397,7 +396,6 @@ int hibernation_snapshot(int platform_mode)
if (error || !in_suspend) if (error || !in_suspend)
pm_restore_gfp_mask(); pm_restore_gfp_mask();
ftrace_start();
resume_console(); resume_console();
dpm_complete(msg); dpm_complete(msg);
...@@ -500,7 +498,6 @@ int hibernation_restore(int platform_mode) ...@@ -500,7 +498,6 @@ int hibernation_restore(int platform_mode)
pm_prepare_console(); pm_prepare_console();
suspend_console(); suspend_console();
ftrace_stop();
pm_restrict_gfp_mask(); pm_restrict_gfp_mask();
error = dpm_suspend_start(PMSG_QUIESCE); error = dpm_suspend_start(PMSG_QUIESCE);
if (!error) { if (!error) {
...@@ -508,7 +505,6 @@ int hibernation_restore(int platform_mode) ...@@ -508,7 +505,6 @@ int hibernation_restore(int platform_mode)
dpm_resume_end(PMSG_RECOVER); dpm_resume_end(PMSG_RECOVER);
} }
pm_restore_gfp_mask(); pm_restore_gfp_mask();
ftrace_start();
resume_console(); resume_console();
pm_restore_console(); pm_restore_console();
return error; return error;
...@@ -535,7 +531,6 @@ int hibernation_platform_enter(void) ...@@ -535,7 +531,6 @@ int hibernation_platform_enter(void)
entering_platform_hibernation = true; entering_platform_hibernation = true;
suspend_console(); suspend_console();
ftrace_stop();
error = dpm_suspend_start(PMSG_HIBERNATE); error = dpm_suspend_start(PMSG_HIBERNATE);
if (error) { if (error) {
if (hibernation_ops->recover) if (hibernation_ops->recover)
...@@ -579,7 +574,6 @@ int hibernation_platform_enter(void) ...@@ -579,7 +574,6 @@ int hibernation_platform_enter(void)
Resume_devices: Resume_devices:
entering_platform_hibernation = false; entering_platform_hibernation = false;
dpm_resume_end(PMSG_RESTORE); dpm_resume_end(PMSG_RESTORE);
ftrace_start();
resume_console(); resume_console();
Close: Close:
......
...@@ -248,7 +248,6 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) ...@@ -248,7 +248,6 @@ static int suspend_enter(suspend_state_t state, bool *wakeup)
goto Platform_wake; goto Platform_wake;
} }
ftrace_stop();
error = disable_nonboot_cpus(); error = disable_nonboot_cpus();
if (error || suspend_test(TEST_CPUS)) if (error || suspend_test(TEST_CPUS))
goto Enable_cpus; goto Enable_cpus;
...@@ -275,7 +274,6 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) ...@@ -275,7 +274,6 @@ static int suspend_enter(suspend_state_t state, bool *wakeup)
Enable_cpus: Enable_cpus:
enable_nonboot_cpus(); enable_nonboot_cpus();
ftrace_start();
Platform_wake: Platform_wake:
if (need_suspend_ops(state) && suspend_ops->wake) if (need_suspend_ops(state) && suspend_ops->wake)
......
...@@ -29,11 +29,6 @@ config HAVE_FUNCTION_GRAPH_FP_TEST ...@@ -29,11 +29,6 @@ config HAVE_FUNCTION_GRAPH_FP_TEST
help help
See Documentation/trace/ftrace-design.txt See Documentation/trace/ftrace-design.txt
config HAVE_FUNCTION_TRACE_MCOUNT_TEST
bool
help
See Documentation/trace/ftrace-design.txt
config HAVE_DYNAMIC_FTRACE config HAVE_DYNAMIC_FTRACE
bool bool
help help
......
...@@ -28,6 +28,7 @@ obj-$(CONFIG_RING_BUFFER_BENCHMARK) += ring_buffer_benchmark.o ...@@ -28,6 +28,7 @@ obj-$(CONFIG_RING_BUFFER_BENCHMARK) += ring_buffer_benchmark.o
obj-$(CONFIG_TRACING) += trace.o obj-$(CONFIG_TRACING) += trace.o
obj-$(CONFIG_TRACING) += trace_output.o obj-$(CONFIG_TRACING) += trace_output.o
obj-$(CONFIG_TRACING) += trace_seq.o
obj-$(CONFIG_TRACING) += trace_stat.o obj-$(CONFIG_TRACING) += trace_stat.o
obj-$(CONFIG_TRACING) += trace_printk.o obj-$(CONFIG_TRACING) += trace_printk.o
obj-$(CONFIG_CONTEXT_SWITCH_TRACER) += trace_sched_switch.o obj-$(CONFIG_CONTEXT_SWITCH_TRACER) += trace_sched_switch.o
......
This diff is collapsed.
...@@ -1689,22 +1689,14 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size, ...@@ -1689,22 +1689,14 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size,
if (!cpu_buffer->nr_pages_to_update) if (!cpu_buffer->nr_pages_to_update)
continue; continue;
/* The update must run on the CPU that is being updated. */ /* Can't run something on an offline CPU. */
preempt_disable(); if (!cpu_online(cpu)) {
if (cpu == smp_processor_id() || !cpu_online(cpu)) {
rb_update_pages(cpu_buffer); rb_update_pages(cpu_buffer);
cpu_buffer->nr_pages_to_update = 0; cpu_buffer->nr_pages_to_update = 0;
} else { } else {
/*
* Can not disable preemption for schedule_work_on()
* on PREEMPT_RT.
*/
preempt_enable();
schedule_work_on(cpu, schedule_work_on(cpu,
&cpu_buffer->update_pages_work); &cpu_buffer->update_pages_work);
preempt_disable();
} }
preempt_enable();
} }
/* wait for all the updates to complete */ /* wait for all the updates to complete */
...@@ -1742,22 +1734,14 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size, ...@@ -1742,22 +1734,14 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size,
get_online_cpus(); get_online_cpus();
preempt_disable(); /* Can't run something on an offline CPU. */
/* The update must run on the CPU that is being updated. */ if (!cpu_online(cpu_id))
if (cpu_id == smp_processor_id() || !cpu_online(cpu_id))
rb_update_pages(cpu_buffer); rb_update_pages(cpu_buffer);
else { else {
/*
* Can not disable preemption for schedule_work_on()
* on PREEMPT_RT.
*/
preempt_enable();
schedule_work_on(cpu_id, schedule_work_on(cpu_id,
&cpu_buffer->update_pages_work); &cpu_buffer->update_pages_work);
wait_for_completion(&cpu_buffer->update_done); wait_for_completion(&cpu_buffer->update_done);
preempt_disable();
} }
preempt_enable();
cpu_buffer->nr_pages_to_update = 0; cpu_buffer->nr_pages_to_update = 0;
put_online_cpus(); put_online_cpus();
...@@ -3775,7 +3759,7 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts) ...@@ -3775,7 +3759,7 @@ rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts)
if (rb_per_cpu_empty(cpu_buffer)) if (rb_per_cpu_empty(cpu_buffer))
return NULL; return NULL;
if (iter->head >= local_read(&iter->head_page->page->commit)) { if (iter->head >= rb_page_size(iter->head_page)) {
rb_inc_iter(iter); rb_inc_iter(iter);
goto again; goto again;
} }
......
...@@ -937,30 +937,6 @@ int trace_get_user(struct trace_parser *parser, const char __user *ubuf, ...@@ -937,30 +937,6 @@ int trace_get_user(struct trace_parser *parser, const char __user *ubuf,
return ret; return ret;
} }
ssize_t trace_seq_to_user(struct trace_seq *s, char __user *ubuf, size_t cnt)
{
int len;
int ret;
if (!cnt)
return 0;
if (s->len <= s->readpos)
return -EBUSY;
len = s->len - s->readpos;
if (cnt > len)
cnt = len;
ret = copy_to_user(ubuf, s->buffer + s->readpos, cnt);
if (ret == cnt)
return -EFAULT;
cnt -= ret;
s->readpos += cnt;
return cnt;
}
static ssize_t trace_seq_to_buffer(struct trace_seq *s, void *buf, size_t cnt) static ssize_t trace_seq_to_buffer(struct trace_seq *s, void *buf, size_t cnt)
{ {
int len; int len;
...@@ -3699,6 +3675,7 @@ static const char readme_msg[] = ...@@ -3699,6 +3675,7 @@ static const char readme_msg[] =
#endif #endif
#ifdef CONFIG_FUNCTION_GRAPH_TRACER #ifdef CONFIG_FUNCTION_GRAPH_TRACER
" set_graph_function\t- Trace the nested calls of a function (function_graph)\n" " set_graph_function\t- Trace the nested calls of a function (function_graph)\n"
" set_graph_notrace\t- Do not trace the nested calls of a function (function_graph)\n"
" max_graph_depth\t- Trace a limited depth of nested calls (0 is unlimited)\n" " max_graph_depth\t- Trace a limited depth of nested calls (0 is unlimited)\n"
#endif #endif
#ifdef CONFIG_TRACER_SNAPSHOT #ifdef CONFIG_TRACER_SNAPSHOT
...@@ -4238,10 +4215,9 @@ tracing_set_trace_write(struct file *filp, const char __user *ubuf, ...@@ -4238,10 +4215,9 @@ tracing_set_trace_write(struct file *filp, const char __user *ubuf,
} }
static ssize_t static ssize_t
tracing_max_lat_read(struct file *filp, char __user *ubuf, tracing_nsecs_read(unsigned long *ptr, char __user *ubuf,
size_t cnt, loff_t *ppos) size_t cnt, loff_t *ppos)
{ {
unsigned long *ptr = filp->private_data;
char buf[64]; char buf[64];
int r; int r;
...@@ -4253,10 +4229,9 @@ tracing_max_lat_read(struct file *filp, char __user *ubuf, ...@@ -4253,10 +4229,9 @@ tracing_max_lat_read(struct file *filp, char __user *ubuf,
} }
static ssize_t static ssize_t
tracing_max_lat_write(struct file *filp, const char __user *ubuf, tracing_nsecs_write(unsigned long *ptr, const char __user *ubuf,
size_t cnt, loff_t *ppos) size_t cnt, loff_t *ppos)
{ {
unsigned long *ptr = filp->private_data;
unsigned long val; unsigned long val;
int ret; int ret;
...@@ -4269,6 +4244,52 @@ tracing_max_lat_write(struct file *filp, const char __user *ubuf, ...@@ -4269,6 +4244,52 @@ tracing_max_lat_write(struct file *filp, const char __user *ubuf,
return cnt; return cnt;
} }
static ssize_t
tracing_thresh_read(struct file *filp, char __user *ubuf,
size_t cnt, loff_t *ppos)
{
return tracing_nsecs_read(&tracing_thresh, ubuf, cnt, ppos);
}
static ssize_t
tracing_thresh_write(struct file *filp, const char __user *ubuf,
size_t cnt, loff_t *ppos)
{
struct trace_array *tr = filp->private_data;
int ret;
mutex_lock(&trace_types_lock);
ret = tracing_nsecs_write(&tracing_thresh, ubuf, cnt, ppos);
if (ret < 0)
goto out;
if (tr->current_trace->update_thresh) {
ret = tr->current_trace->update_thresh(tr);
if (ret < 0)
goto out;
}
ret = cnt;
out:
mutex_unlock(&trace_types_lock);
return ret;
}
static ssize_t
tracing_max_lat_read(struct file *filp, char __user *ubuf,
size_t cnt, loff_t *ppos)
{
return tracing_nsecs_read(filp->private_data, ubuf, cnt, ppos);
}
static ssize_t
tracing_max_lat_write(struct file *filp, const char __user *ubuf,
size_t cnt, loff_t *ppos)
{
return tracing_nsecs_write(filp->private_data, ubuf, cnt, ppos);
}
static int tracing_open_pipe(struct inode *inode, struct file *filp) static int tracing_open_pipe(struct inode *inode, struct file *filp)
{ {
struct trace_array *tr = inode->i_private; struct trace_array *tr = inode->i_private;
...@@ -5170,6 +5191,13 @@ static int snapshot_raw_open(struct inode *inode, struct file *filp) ...@@ -5170,6 +5191,13 @@ static int snapshot_raw_open(struct inode *inode, struct file *filp)
#endif /* CONFIG_TRACER_SNAPSHOT */ #endif /* CONFIG_TRACER_SNAPSHOT */
static const struct file_operations tracing_thresh_fops = {
.open = tracing_open_generic,
.read = tracing_thresh_read,
.write = tracing_thresh_write,
.llseek = generic_file_llseek,
};
static const struct file_operations tracing_max_lat_fops = { static const struct file_operations tracing_max_lat_fops = {
.open = tracing_open_generic, .open = tracing_open_generic,
.read = tracing_max_lat_read, .read = tracing_max_lat_read,
...@@ -6107,10 +6135,8 @@ destroy_trace_option_files(struct trace_option_dentry *topts) ...@@ -6107,10 +6135,8 @@ destroy_trace_option_files(struct trace_option_dentry *topts)
if (!topts) if (!topts)
return; return;
for (cnt = 0; topts[cnt].opt; cnt++) { for (cnt = 0; topts[cnt].opt; cnt++)
if (topts[cnt].entry)
debugfs_remove(topts[cnt].entry); debugfs_remove(topts[cnt].entry);
}
kfree(topts); kfree(topts);
} }
...@@ -6533,7 +6559,7 @@ static __init int tracer_init_debugfs(void) ...@@ -6533,7 +6559,7 @@ static __init int tracer_init_debugfs(void)
init_tracer_debugfs(&global_trace, d_tracer); init_tracer_debugfs(&global_trace, d_tracer);
trace_create_file("tracing_thresh", 0644, d_tracer, trace_create_file("tracing_thresh", 0644, d_tracer,
&tracing_thresh, &tracing_max_lat_fops); &global_trace, &tracing_thresh_fops);
trace_create_file("README", 0444, d_tracer, trace_create_file("README", 0444, d_tracer,
NULL, &tracing_readme_fops); NULL, &tracing_readme_fops);
......
...@@ -339,6 +339,7 @@ struct tracer_flags { ...@@ -339,6 +339,7 @@ struct tracer_flags {
* @reset: called when one switches to another tracer * @reset: called when one switches to another tracer
* @start: called when tracing is unpaused (echo 1 > tracing_enabled) * @start: called when tracing is unpaused (echo 1 > tracing_enabled)
* @stop: called when tracing is paused (echo 0 > tracing_enabled) * @stop: called when tracing is paused (echo 0 > tracing_enabled)
* @update_thresh: called when tracing_thresh is updated
* @open: called when the trace file is opened * @open: called when the trace file is opened
* @pipe_open: called when the trace_pipe file is opened * @pipe_open: called when the trace_pipe file is opened
* @close: called when the trace file is released * @close: called when the trace file is released
...@@ -357,6 +358,7 @@ struct tracer { ...@@ -357,6 +358,7 @@ struct tracer {
void (*reset)(struct trace_array *tr); void (*reset)(struct trace_array *tr);
void (*start)(struct trace_array *tr); void (*start)(struct trace_array *tr);
void (*stop)(struct trace_array *tr); void (*stop)(struct trace_array *tr);
int (*update_thresh)(struct trace_array *tr);
void (*open)(struct trace_iterator *iter); void (*open)(struct trace_iterator *iter);
void (*pipe_open)(struct trace_iterator *iter); void (*pipe_open)(struct trace_iterator *iter);
void (*close)(struct trace_iterator *iter); void (*close)(struct trace_iterator *iter);
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
* *
*/ */
#define pr_fmt(fmt) fmt
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/kthread.h> #include <linux/kthread.h>
...@@ -1491,7 +1493,7 @@ event_subsystem_dir(struct trace_array *tr, const char *name, ...@@ -1491,7 +1493,7 @@ event_subsystem_dir(struct trace_array *tr, const char *name,
dir->entry = debugfs_create_dir(name, parent); dir->entry = debugfs_create_dir(name, parent);
if (!dir->entry) { if (!dir->entry) {
pr_warning("Failed to create system directory %s\n", name); pr_warn("Failed to create system directory %s\n", name);
__put_system(system); __put_system(system);
goto out_free; goto out_free;
} }
...@@ -1507,7 +1509,7 @@ event_subsystem_dir(struct trace_array *tr, const char *name, ...@@ -1507,7 +1509,7 @@ event_subsystem_dir(struct trace_array *tr, const char *name,
if (!entry) { if (!entry) {
kfree(system->filter); kfree(system->filter);
system->filter = NULL; system->filter = NULL;
pr_warning("Could not create debugfs '%s/filter' entry\n", name); pr_warn("Could not create debugfs '%s/filter' entry\n", name);
} }
trace_create_file("enable", 0644, dir->entry, dir, trace_create_file("enable", 0644, dir->entry, dir,
...@@ -1522,8 +1524,7 @@ event_subsystem_dir(struct trace_array *tr, const char *name, ...@@ -1522,8 +1524,7 @@ event_subsystem_dir(struct trace_array *tr, const char *name,
out_fail: out_fail:
/* Only print this message if failed on memory allocation */ /* Only print this message if failed on memory allocation */
if (!dir || !system) if (!dir || !system)
pr_warning("No memory to create event subsystem %s\n", pr_warn("No memory to create event subsystem %s\n", name);
name);
return NULL; return NULL;
} }
...@@ -1551,8 +1552,7 @@ event_create_dir(struct dentry *parent, struct ftrace_event_file *file) ...@@ -1551,8 +1552,7 @@ event_create_dir(struct dentry *parent, struct ftrace_event_file *file)
name = ftrace_event_name(call); name = ftrace_event_name(call);
file->dir = debugfs_create_dir(name, d_events); file->dir = debugfs_create_dir(name, d_events);
if (!file->dir) { if (!file->dir) {
pr_warning("Could not create debugfs '%s' directory\n", pr_warn("Could not create debugfs '%s' directory\n", name);
name);
return -1; return -1;
} }
...@@ -1575,8 +1575,8 @@ event_create_dir(struct dentry *parent, struct ftrace_event_file *file) ...@@ -1575,8 +1575,8 @@ event_create_dir(struct dentry *parent, struct ftrace_event_file *file)
if (list_empty(head)) { if (list_empty(head)) {
ret = call->class->define_fields(call); ret = call->class->define_fields(call);
if (ret < 0) { if (ret < 0) {
pr_warning("Could not initialize trace point" pr_warn("Could not initialize trace point events/%s\n",
" events/%s\n", name); name);
return -1; return -1;
} }
} }
...@@ -1649,8 +1649,7 @@ static int event_init(struct ftrace_event_call *call) ...@@ -1649,8 +1649,7 @@ static int event_init(struct ftrace_event_call *call)
if (call->class->raw_init) { if (call->class->raw_init) {
ret = call->class->raw_init(call); ret = call->class->raw_init(call);
if (ret < 0 && ret != -ENOSYS) if (ret < 0 && ret != -ENOSYS)
pr_warn("Could not initialize trace events/%s\n", pr_warn("Could not initialize trace events/%s\n", name);
name);
} }
return ret; return ret;
...@@ -1895,7 +1894,7 @@ __trace_add_event_dirs(struct trace_array *tr) ...@@ -1895,7 +1894,7 @@ __trace_add_event_dirs(struct trace_array *tr)
list_for_each_entry(call, &ftrace_events, list) { list_for_each_entry(call, &ftrace_events, list) {
ret = __trace_add_new_event(call, tr); ret = __trace_add_new_event(call, tr);
if (ret < 0) if (ret < 0)
pr_warning("Could not create directory for event %s\n", pr_warn("Could not create directory for event %s\n",
ftrace_event_name(call)); ftrace_event_name(call));
} }
} }
...@@ -2208,7 +2207,7 @@ __trace_early_add_event_dirs(struct trace_array *tr) ...@@ -2208,7 +2207,7 @@ __trace_early_add_event_dirs(struct trace_array *tr)
list_for_each_entry(file, &tr->events, list) { list_for_each_entry(file, &tr->events, list) {
ret = event_create_dir(tr->event_dir, file); ret = event_create_dir(tr->event_dir, file);
if (ret < 0) if (ret < 0)
pr_warning("Could not create directory for event %s\n", pr_warn("Could not create directory for event %s\n",
ftrace_event_name(file->event_call)); ftrace_event_name(file->event_call));
} }
} }
...@@ -2232,7 +2231,7 @@ __trace_early_add_events(struct trace_array *tr) ...@@ -2232,7 +2231,7 @@ __trace_early_add_events(struct trace_array *tr)
ret = __trace_early_add_new_event(call, tr); ret = __trace_early_add_new_event(call, tr);
if (ret < 0) if (ret < 0)
pr_warning("Could not create early event %s\n", pr_warn("Could not create early event %s\n",
ftrace_event_name(call)); ftrace_event_name(call));
} }
} }
...@@ -2280,13 +2279,13 @@ create_event_toplevel_files(struct dentry *parent, struct trace_array *tr) ...@@ -2280,13 +2279,13 @@ create_event_toplevel_files(struct dentry *parent, struct trace_array *tr)
entry = debugfs_create_file("set_event", 0644, parent, entry = debugfs_create_file("set_event", 0644, parent,
tr, &ftrace_set_event_fops); tr, &ftrace_set_event_fops);
if (!entry) { if (!entry) {
pr_warning("Could not create debugfs 'set_event' entry\n"); pr_warn("Could not create debugfs 'set_event' entry\n");
return -ENOMEM; return -ENOMEM;
} }
d_events = debugfs_create_dir("events", parent); d_events = debugfs_create_dir("events", parent);
if (!d_events) { if (!d_events) {
pr_warning("Could not create debugfs 'events' directory\n"); pr_warn("Could not create debugfs 'events' directory\n");
return -ENOMEM; return -ENOMEM;
} }
...@@ -2462,11 +2461,10 @@ static __init int event_trace_init(void) ...@@ -2462,11 +2461,10 @@ static __init int event_trace_init(void)
entry = debugfs_create_file("available_events", 0444, d_tracer, entry = debugfs_create_file("available_events", 0444, d_tracer,
tr, &ftrace_avail_fops); tr, &ftrace_avail_fops);
if (!entry) if (!entry)
pr_warning("Could not create debugfs " pr_warn("Could not create debugfs 'available_events' entry\n");
"'available_events' entry\n");
if (trace_define_common_fields()) if (trace_define_common_fields())
pr_warning("tracing: Failed to allocate common fields"); pr_warn("tracing: Failed to allocate common fields");
ret = early_event_add_tracer(d_tracer, tr); ret = early_event_add_tracer(d_tracer, tr);
if (ret) if (ret)
...@@ -2475,7 +2473,7 @@ static __init int event_trace_init(void) ...@@ -2475,7 +2473,7 @@ static __init int event_trace_init(void)
#ifdef CONFIG_MODULES #ifdef CONFIG_MODULES
ret = register_module_notifier(&trace_module_nb); ret = register_module_notifier(&trace_module_nb);
if (ret) if (ret)
pr_warning("Failed to register trace events module notifier\n"); pr_warn("Failed to register trace events module notifier\n");
#endif #endif
return 0; return 0;
} }
...@@ -2579,7 +2577,7 @@ static __init void event_trace_self_tests(void) ...@@ -2579,7 +2577,7 @@ static __init void event_trace_self_tests(void)
* it and the self test should not be on. * it and the self test should not be on.
*/ */
if (file->flags & FTRACE_EVENT_FL_ENABLED) { if (file->flags & FTRACE_EVENT_FL_ENABLED) {
pr_warning("Enabled event during self test!\n"); pr_warn("Enabled event during self test!\n");
WARN_ON_ONCE(1); WARN_ON_ONCE(1);
continue; continue;
} }
...@@ -2607,7 +2605,7 @@ static __init void event_trace_self_tests(void) ...@@ -2607,7 +2605,7 @@ static __init void event_trace_self_tests(void)
ret = __ftrace_set_clr_event(tr, NULL, system->name, NULL, 1); ret = __ftrace_set_clr_event(tr, NULL, system->name, NULL, 1);
if (WARN_ON_ONCE(ret)) { if (WARN_ON_ONCE(ret)) {
pr_warning("error enabling system %s\n", pr_warn("error enabling system %s\n",
system->name); system->name);
continue; continue;
} }
...@@ -2616,7 +2614,7 @@ static __init void event_trace_self_tests(void) ...@@ -2616,7 +2614,7 @@ static __init void event_trace_self_tests(void)
ret = __ftrace_set_clr_event(tr, NULL, system->name, NULL, 0); ret = __ftrace_set_clr_event(tr, NULL, system->name, NULL, 0);
if (WARN_ON_ONCE(ret)) { if (WARN_ON_ONCE(ret)) {
pr_warning("error disabling system %s\n", pr_warn("error disabling system %s\n",
system->name); system->name);
continue; continue;
} }
...@@ -2631,7 +2629,7 @@ static __init void event_trace_self_tests(void) ...@@ -2631,7 +2629,7 @@ static __init void event_trace_self_tests(void)
ret = __ftrace_set_clr_event(tr, NULL, NULL, NULL, 1); ret = __ftrace_set_clr_event(tr, NULL, NULL, NULL, 1);
if (WARN_ON_ONCE(ret)) { if (WARN_ON_ONCE(ret)) {
pr_warning("error enabling all events\n"); pr_warn("error enabling all events\n");
return; return;
} }
...@@ -2640,7 +2638,7 @@ static __init void event_trace_self_tests(void) ...@@ -2640,7 +2638,7 @@ static __init void event_trace_self_tests(void)
/* reset sysname */ /* reset sysname */
ret = __ftrace_set_clr_event(tr, NULL, NULL, NULL, 0); ret = __ftrace_set_clr_event(tr, NULL, NULL, NULL, 0);
if (WARN_ON_ONCE(ret)) { if (WARN_ON_ONCE(ret)) {
pr_warning("error disabling all events\n"); pr_warn("error disabling all events\n");
return; return;
} }
......
...@@ -15,6 +15,33 @@ ...@@ -15,6 +15,33 @@
#include "trace.h" #include "trace.h"
#include "trace_output.h" #include "trace_output.h"
static bool kill_ftrace_graph;
/**
* ftrace_graph_is_dead - returns true if ftrace_graph_stop() was called
*
* ftrace_graph_stop() is called when a severe error is detected in
* the function graph tracing. This function is called by the critical
* paths of function graph to keep those paths from doing any more harm.
*/
bool ftrace_graph_is_dead(void)
{
return kill_ftrace_graph;
}
/**
* ftrace_graph_stop - set to permanently disable function graph tracincg
*
* In case of an error int function graph tracing, this is called
* to try to keep function graph tracing from causing any more harm.
* Usually this is pretty severe and this is called to try to at least
* get a warning out to the user.
*/
void ftrace_graph_stop(void)
{
kill_ftrace_graph = true;
}
/* When set, irq functions will be ignored */ /* When set, irq functions will be ignored */
static int ftrace_graph_skip_irqs; static int ftrace_graph_skip_irqs;
...@@ -92,6 +119,9 @@ ftrace_push_return_trace(unsigned long ret, unsigned long func, int *depth, ...@@ -92,6 +119,9 @@ ftrace_push_return_trace(unsigned long ret, unsigned long func, int *depth,
unsigned long long calltime; unsigned long long calltime;
int index; int index;
if (unlikely(ftrace_graph_is_dead()))
return -EBUSY;
if (!current->ret_stack) if (!current->ret_stack)
return -EBUSY; return -EBUSY;
...@@ -323,7 +353,7 @@ int trace_graph_entry(struct ftrace_graph_ent *trace) ...@@ -323,7 +353,7 @@ int trace_graph_entry(struct ftrace_graph_ent *trace)
return ret; return ret;
} }
int trace_graph_thresh_entry(struct ftrace_graph_ent *trace) static int trace_graph_thresh_entry(struct ftrace_graph_ent *trace)
{ {
if (tracing_thresh) if (tracing_thresh)
return 1; return 1;
...@@ -412,7 +442,7 @@ void set_graph_array(struct trace_array *tr) ...@@ -412,7 +442,7 @@ void set_graph_array(struct trace_array *tr)
smp_mb(); smp_mb();
} }
void trace_graph_thresh_return(struct ftrace_graph_ret *trace) static void trace_graph_thresh_return(struct ftrace_graph_ret *trace)
{ {
if (tracing_thresh && if (tracing_thresh &&
(trace->rettime - trace->calltime < tracing_thresh)) (trace->rettime - trace->calltime < tracing_thresh))
...@@ -445,6 +475,12 @@ static void graph_trace_reset(struct trace_array *tr) ...@@ -445,6 +475,12 @@ static void graph_trace_reset(struct trace_array *tr)
unregister_ftrace_graph(); unregister_ftrace_graph();
} }
static int graph_trace_update_thresh(struct trace_array *tr)
{
graph_trace_reset(tr);
return graph_trace_init(tr);
}
static int max_bytes_for_cpu; static int max_bytes_for_cpu;
static enum print_line_t static enum print_line_t
...@@ -1399,7 +1435,7 @@ static void __print_graph_headers_flags(struct seq_file *s, u32 flags) ...@@ -1399,7 +1435,7 @@ static void __print_graph_headers_flags(struct seq_file *s, u32 flags)
seq_printf(s, " | | | |\n"); seq_printf(s, " | | | |\n");
} }
void print_graph_headers(struct seq_file *s) static void print_graph_headers(struct seq_file *s)
{ {
print_graph_headers_flags(s, tracer_flags.val); print_graph_headers_flags(s, tracer_flags.val);
} }
...@@ -1495,6 +1531,7 @@ static struct trace_event graph_trace_ret_event = { ...@@ -1495,6 +1531,7 @@ static struct trace_event graph_trace_ret_event = {
static struct tracer graph_trace __tracer_data = { static struct tracer graph_trace __tracer_data = {
.name = "function_graph", .name = "function_graph",
.update_thresh = graph_trace_update_thresh,
.open = graph_trace_open, .open = graph_trace_open,
.pipe_open = graph_trace_open, .pipe_open = graph_trace_open,
.close = graph_trace_close, .close = graph_trace_close,
......
...@@ -20,23 +20,6 @@ static struct hlist_head event_hash[EVENT_HASHSIZE] __read_mostly; ...@@ -20,23 +20,6 @@ static struct hlist_head event_hash[EVENT_HASHSIZE] __read_mostly;
static int next_event_type = __TRACE_LAST_TYPE + 1; static int next_event_type = __TRACE_LAST_TYPE + 1;
int trace_print_seq(struct seq_file *m, struct trace_seq *s)
{
int len = s->len >= PAGE_SIZE ? PAGE_SIZE - 1 : s->len;
int ret;
ret = seq_write(m, s->buffer, len);
/*
* Only reset this buffer if we successfully wrote to the
* seq_file buffer.
*/
if (!ret)
trace_seq_init(s);
return ret;
}
enum print_line_t trace_print_bputs_msg_only(struct trace_iterator *iter) enum print_line_t trace_print_bputs_msg_only(struct trace_iterator *iter)
{ {
struct trace_seq *s = &iter->seq; struct trace_seq *s = &iter->seq;
...@@ -85,257 +68,6 @@ enum print_line_t trace_print_printk_msg_only(struct trace_iterator *iter) ...@@ -85,257 +68,6 @@ enum print_line_t trace_print_printk_msg_only(struct trace_iterator *iter)
return TRACE_TYPE_HANDLED; return TRACE_TYPE_HANDLED;
} }
/**
* trace_seq_printf - sequence printing of trace information
* @s: trace sequence descriptor
* @fmt: printf format string
*
* It returns 0 if the trace oversizes the buffer's free
* space, 1 otherwise.
*
* The tracer may use either sequence operations or its own
* copy to user routines. To simplify formating of a trace
* trace_seq_printf is used to store strings into a special
* buffer (@s). Then the output may be either used by
* the sequencer or pulled into another buffer.
*/
int
trace_seq_printf(struct trace_seq *s, const char *fmt, ...)
{
int len = (PAGE_SIZE - 1) - s->len;
va_list ap;
int ret;
if (s->full || !len)
return 0;
va_start(ap, fmt);
ret = vsnprintf(s->buffer + s->len, len, fmt, ap);
va_end(ap);
/* If we can't write it all, don't bother writing anything */
if (ret >= len) {
s->full = 1;
return 0;
}
s->len += ret;
return 1;
}
EXPORT_SYMBOL_GPL(trace_seq_printf);
/**
* trace_seq_bitmask - put a list of longs as a bitmask print output
* @s: trace sequence descriptor
* @maskp: points to an array of unsigned longs that represent a bitmask
* @nmaskbits: The number of bits that are valid in @maskp
*
* It returns 0 if the trace oversizes the buffer's free
* space, 1 otherwise.
*
* Writes a ASCII representation of a bitmask string into @s.
*/
int
trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp,
int nmaskbits)
{
int len = (PAGE_SIZE - 1) - s->len;
int ret;
if (s->full || !len)
return 0;
ret = bitmap_scnprintf(s->buffer, len, maskp, nmaskbits);
s->len += ret;
return 1;
}
EXPORT_SYMBOL_GPL(trace_seq_bitmask);
/**
* trace_seq_vprintf - sequence printing of trace information
* @s: trace sequence descriptor
* @fmt: printf format string
*
* The tracer may use either sequence operations or its own
* copy to user routines. To simplify formating of a trace
* trace_seq_printf is used to store strings into a special
* buffer (@s). Then the output may be either used by
* the sequencer or pulled into another buffer.
*/
int
trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args)
{
int len = (PAGE_SIZE - 1) - s->len;
int ret;
if (s->full || !len)
return 0;
ret = vsnprintf(s->buffer + s->len, len, fmt, args);
/* If we can't write it all, don't bother writing anything */
if (ret >= len) {
s->full = 1;
return 0;
}
s->len += ret;
return len;
}
EXPORT_SYMBOL_GPL(trace_seq_vprintf);
int trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *binary)
{
int len = (PAGE_SIZE - 1) - s->len;
int ret;
if (s->full || !len)
return 0;
ret = bstr_printf(s->buffer + s->len, len, fmt, binary);
/* If we can't write it all, don't bother writing anything */
if (ret >= len) {
s->full = 1;
return 0;
}
s->len += ret;
return len;
}
/**
* trace_seq_puts - trace sequence printing of simple string
* @s: trace sequence descriptor
* @str: simple string to record
*
* The tracer may use either the sequence operations or its own
* copy to user routines. This function records a simple string
* into a special buffer (@s) for later retrieval by a sequencer
* or other mechanism.
*/
int trace_seq_puts(struct trace_seq *s, const char *str)
{
int len = strlen(str);
if (s->full)
return 0;
if (len > ((PAGE_SIZE - 1) - s->len)) {
s->full = 1;
return 0;
}
memcpy(s->buffer + s->len, str, len);
s->len += len;
return len;
}
int trace_seq_putc(struct trace_seq *s, unsigned char c)
{
if (s->full)
return 0;
if (s->len >= (PAGE_SIZE - 1)) {
s->full = 1;
return 0;
}
s->buffer[s->len++] = c;
return 1;
}
EXPORT_SYMBOL(trace_seq_putc);
int trace_seq_putmem(struct trace_seq *s, const void *mem, size_t len)
{
if (s->full)
return 0;
if (len > ((PAGE_SIZE - 1) - s->len)) {
s->full = 1;
return 0;
}
memcpy(s->buffer + s->len, mem, len);
s->len += len;
return len;
}
int trace_seq_putmem_hex(struct trace_seq *s, const void *mem, size_t len)
{
unsigned char hex[HEX_CHARS];
const unsigned char *data = mem;
int i, j;
if (s->full)
return 0;
#ifdef __BIG_ENDIAN
for (i = 0, j = 0; i < len; i++) {
#else
for (i = len-1, j = 0; i >= 0; i--) {
#endif
hex[j++] = hex_asc_hi(data[i]);
hex[j++] = hex_asc_lo(data[i]);
}
hex[j++] = ' ';
return trace_seq_putmem(s, hex, j);
}
void *trace_seq_reserve(struct trace_seq *s, size_t len)
{
void *ret;
if (s->full)
return NULL;
if (len > ((PAGE_SIZE - 1) - s->len)) {
s->full = 1;
return NULL;
}
ret = s->buffer + s->len;
s->len += len;
return ret;
}
int trace_seq_path(struct trace_seq *s, const struct path *path)
{
unsigned char *p;
if (s->full)
return 0;
if (s->len >= (PAGE_SIZE - 1)) {
s->full = 1;
return 0;
}
p = d_path(path, s->buffer + s->len, PAGE_SIZE - s->len);
if (!IS_ERR(p)) {
p = mangle_path(s->buffer + s->len, p, "\n");
if (p) {
s->len = p - s->buffer;
return 1;
}
} else {
s->buffer[s->len++] = '?';
return 1;
}
s->full = 1;
return 0;
}
const char * const char *
ftrace_print_flags_seq(struct trace_seq *p, const char *delim, ftrace_print_flags_seq(struct trace_seq *p, const char *delim,
unsigned long flags, unsigned long flags,
...@@ -343,7 +75,7 @@ ftrace_print_flags_seq(struct trace_seq *p, const char *delim, ...@@ -343,7 +75,7 @@ ftrace_print_flags_seq(struct trace_seq *p, const char *delim,
{ {
unsigned long mask; unsigned long mask;
const char *str; const char *str;
const char *ret = p->buffer + p->len; const char *ret = trace_seq_buffer_ptr(p);
int i, first = 1; int i, first = 1;
for (i = 0; flag_array[i].name && flags; i++) { for (i = 0; flag_array[i].name && flags; i++) {
...@@ -379,7 +111,7 @@ ftrace_print_symbols_seq(struct trace_seq *p, unsigned long val, ...@@ -379,7 +111,7 @@ ftrace_print_symbols_seq(struct trace_seq *p, unsigned long val,
const struct trace_print_flags *symbol_array) const struct trace_print_flags *symbol_array)
{ {
int i; int i;
const char *ret = p->buffer + p->len; const char *ret = trace_seq_buffer_ptr(p);
for (i = 0; symbol_array[i].name; i++) { for (i = 0; symbol_array[i].name; i++) {
...@@ -390,7 +122,7 @@ ftrace_print_symbols_seq(struct trace_seq *p, unsigned long val, ...@@ -390,7 +122,7 @@ ftrace_print_symbols_seq(struct trace_seq *p, unsigned long val,
break; break;
} }
if (ret == (const char *)(p->buffer + p->len)) if (ret == (const char *)(trace_seq_buffer_ptr(p)))
trace_seq_printf(p, "0x%lx", val); trace_seq_printf(p, "0x%lx", val);
trace_seq_putc(p, 0); trace_seq_putc(p, 0);
...@@ -405,7 +137,7 @@ ftrace_print_symbols_seq_u64(struct trace_seq *p, unsigned long long val, ...@@ -405,7 +137,7 @@ ftrace_print_symbols_seq_u64(struct trace_seq *p, unsigned long long val,
const struct trace_print_flags_u64 *symbol_array) const struct trace_print_flags_u64 *symbol_array)
{ {
int i; int i;
const char *ret = p->buffer + p->len; const char *ret = trace_seq_buffer_ptr(p);
for (i = 0; symbol_array[i].name; i++) { for (i = 0; symbol_array[i].name; i++) {
...@@ -416,7 +148,7 @@ ftrace_print_symbols_seq_u64(struct trace_seq *p, unsigned long long val, ...@@ -416,7 +148,7 @@ ftrace_print_symbols_seq_u64(struct trace_seq *p, unsigned long long val,
break; break;
} }
if (ret == (const char *)(p->buffer + p->len)) if (ret == (const char *)(trace_seq_buffer_ptr(p)))
trace_seq_printf(p, "0x%llx", val); trace_seq_printf(p, "0x%llx", val);
trace_seq_putc(p, 0); trace_seq_putc(p, 0);
...@@ -430,7 +162,7 @@ const char * ...@@ -430,7 +162,7 @@ const char *
ftrace_print_bitmask_seq(struct trace_seq *p, void *bitmask_ptr, ftrace_print_bitmask_seq(struct trace_seq *p, void *bitmask_ptr,
unsigned int bitmask_size) unsigned int bitmask_size)
{ {
const char *ret = p->buffer + p->len; const char *ret = trace_seq_buffer_ptr(p);
trace_seq_bitmask(p, bitmask_ptr, bitmask_size * 8); trace_seq_bitmask(p, bitmask_ptr, bitmask_size * 8);
trace_seq_putc(p, 0); trace_seq_putc(p, 0);
...@@ -443,7 +175,7 @@ const char * ...@@ -443,7 +175,7 @@ const char *
ftrace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int buf_len) ftrace_print_hex_seq(struct trace_seq *p, const unsigned char *buf, int buf_len)
{ {
int i; int i;
const char *ret = p->buffer + p->len; const char *ret = trace_seq_buffer_ptr(p);
for (i = 0; i < buf_len; i++) for (i = 0; i < buf_len; i++)
trace_seq_printf(p, "%s%2.2x", i == 0 ? "" : " ", buf[i]); trace_seq_printf(p, "%s%2.2x", i == 0 ? "" : " ", buf[i]);
......
...@@ -35,9 +35,6 @@ trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry); ...@@ -35,9 +35,6 @@ trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry);
extern int __unregister_ftrace_event(struct trace_event *event); extern int __unregister_ftrace_event(struct trace_event *event);
extern struct rw_semaphore trace_event_sem; extern struct rw_semaphore trace_event_sem;
#define MAX_MEMHEX_BYTES 8
#define HEX_CHARS (MAX_MEMHEX_BYTES*2 + 1)
#define SEQ_PUT_FIELD_RET(s, x) \ #define SEQ_PUT_FIELD_RET(s, x) \
do { \ do { \
if (!trace_seq_putmem(s, &(x), sizeof(x))) \ if (!trace_seq_putmem(s, &(x), sizeof(x))) \
...@@ -46,7 +43,6 @@ do { \ ...@@ -46,7 +43,6 @@ do { \
#define SEQ_PUT_HEX_FIELD_RET(s, x) \ #define SEQ_PUT_HEX_FIELD_RET(s, x) \
do { \ do { \
BUILD_BUG_ON(sizeof(x) > MAX_MEMHEX_BYTES); \
if (!trace_seq_putmem_hex(s, &(x), sizeof(x))) \ if (!trace_seq_putmem_hex(s, &(x), sizeof(x))) \
return TRACE_TYPE_PARTIAL_LINE; \ return TRACE_TYPE_PARTIAL_LINE; \
} while (0) } while (0)
......
This diff is collapsed.
...@@ -87,7 +87,7 @@ TRACE_EVENT(foo_bar, ...@@ -87,7 +87,7 @@ TRACE_EVENT(foo_bar,
), ),
TP_fast_assign( TP_fast_assign(
strncpy(__entry->foo, foo, 10); strlcpy(__entry->foo, foo, 10);
__entry->bar = bar; __entry->bar = bar;
), ),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment