Skip to content

Commit

Permalink
Merge tag 'trace-3.15' of git://git.kernel.org/pub/scm/linux/kernel/g…
Browse files Browse the repository at this point in the history
…it/rostedt/linux-trace

Pull tracing updates from Steven Rostedt:
 "Most of the changes were largely clean ups, and some documentation.
  But there were a few features that were added:

  Uprobes now work with event triggers and multi buffers and have
  support under ftrace and perf.

  The big feature is that the function tracer can now be used within the
  multi buffer instances.  That is, you can now trace some functions in
  one buffer, others in another buffer, all functions in a third buffer
  and so on.  They are basically agnostic from each other.  This only
  works for the function tracer and not for the function graph trace,
  although you can have the function graph tracer running in the top
  level buffer (or any tracer for that matter) and have different
  function tracing going on in the sub buffers"

* tag 'trace-3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace: (45 commits)
  tracing: Add BUG_ON when stack end location is over written
  tracepoint: Remove unused API functions
  Revert "tracing: Move event storage for array from macro to standalone function"
  ftrace: Constify ftrace_text_reserved
  tracepoints: API doc update to tracepoint_probe_register() return value
  tracepoints: API doc update to data argument
  ftrace: Fix compilation warning about control_ops_free
  ftrace/x86: BUG when ftrace recovery fails
  ftrace: Warn on error when modifying ftrace function
  ftrace: Remove freelist from struct dyn_ftrace
  ftrace: Do not pass data to ftrace_dyn_arch_init
  ftrace: Pass retval through return in ftrace_dyn_arch_init()
  ftrace: Inline the code from ftrace_dyn_table_alloc()
  ftrace: Cleanup of global variables ftrace_new_pgs and ftrace_update_cnt
  tracing: Evaluate len expression only once in __dynamic_array macro
  tracing: Correctly expand len expressions from __dynamic_array macro
  tracing/module: Replace include of tracepoint.h with jump_label.h in module.h
  tracing: Fix event header migrate.h to include tracepoint.h
  tracing: Fix event header writeback.h to include tracepoint.h
  tracing: Warn if a tracepoint is not set via debugfs
  ...
  • Loading branch information
Linus Torvalds committed Apr 3, 2014
2 parents 59ecc26 + 3862807 commit 68114e5
Show file tree
Hide file tree
Showing 36 changed files with 739 additions and 591 deletions.
5 changes: 1 addition & 4 deletions Documentation/trace/ftrace-design.txt
Original file line number Diff line number Diff line change
Expand Up @@ -358,11 +358,8 @@ Every arch has an init callback function. If you need to do something early on
to initialize some state, this is the time to do that. Otherwise, this simple
function below should be sufficient for most people:

int __init ftrace_dyn_arch_init(void *data)
int __init ftrace_dyn_arch_init(void)
{
/* return value is done indirectly via data */
*(unsigned long *)data = 0;

return 0;
}

Expand Down
4 changes: 1 addition & 3 deletions arch/arm/kernel/ftrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,8 @@ int ftrace_make_nop(struct module *mod,
return ret;
}

int __init ftrace_dyn_arch_init(void *data)
int __init ftrace_dyn_arch_init(void)
{
*(unsigned long *)data = 0;

return 0;
}
#endif /* CONFIG_DYNAMIC_FTRACE */
Expand Down
5 changes: 1 addition & 4 deletions arch/blackfin/kernel/ftrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,8 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
return ftrace_modify_code(ip, call, sizeof(call));
}

int __init ftrace_dyn_arch_init(void *data)
int __init ftrace_dyn_arch_init(void)
{
/* return value is done indirectly via data */
*(unsigned long *)data = 0;

return 0;
}

Expand Down
4 changes: 1 addition & 3 deletions arch/ia64/kernel/ftrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,7 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
}

/* run from kstop_machine */
int __init ftrace_dyn_arch_init(void *data)
int __init ftrace_dyn_arch_init(void)
{
*(unsigned long *)data = 0;

return 0;
}
5 changes: 1 addition & 4 deletions arch/metag/kernel/ftrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
}

/* run from kstop_machine */
int __init ftrace_dyn_arch_init(void *data)
int __init ftrace_dyn_arch_init(void)
{
/* The return code is returned via data */
writel(0, data);

return 0;
}
5 changes: 1 addition & 4 deletions arch/microblaze/kernel/ftrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,8 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
return ret;
}

int __init ftrace_dyn_arch_init(void *data)
int __init ftrace_dyn_arch_init(void)
{
/* The return code is retured via data */
*(unsigned long *)data = 0;

return 0;
}

Expand Down
5 changes: 1 addition & 4 deletions arch/mips/kernel/ftrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,17 +201,14 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
return ftrace_modify_code(FTRACE_CALL_IP, new);
}

int __init ftrace_dyn_arch_init(void *data)
int __init ftrace_dyn_arch_init(void)
{
/* Encode the instructions when booting */
ftrace_dyn_arch_init_insns();

/* Remove "b ftrace_stub" to ensure ftrace_caller() is executed */
ftrace_modify_code(MCOUNT_ADDR, INSN_NOP);

/* The return code is retured via data */
*(unsigned long *)data = 0;

return 0;
}
#endif /* CONFIG_DYNAMIC_FTRACE */
Expand Down
7 changes: 1 addition & 6 deletions arch/powerpc/kernel/ftrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -532,13 +532,8 @@ void arch_ftrace_update_code(int command)
ftrace_disable_ftrace_graph_caller();
}

int __init ftrace_dyn_arch_init(void *data)
int __init ftrace_dyn_arch_init(void)
{
/* caller expects data to be zero */
unsigned long *p = data;

*p = 0;

return 0;
}
#endif /* CONFIG_DYNAMIC_FTRACE */
Expand Down
3 changes: 1 addition & 2 deletions arch/s390/kernel/ftrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,8 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
return 0;
}

int __init ftrace_dyn_arch_init(void *data)
int __init ftrace_dyn_arch_init(void)
{
*(unsigned long *) data = 0;
return 0;
}

Expand Down
5 changes: 1 addition & 4 deletions arch/sh/kernel/ftrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,11 +272,8 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
return ftrace_modify_code(rec->ip, old, new);
}

int __init ftrace_dyn_arch_init(void *data)
int __init ftrace_dyn_arch_init(void)
{
/* The return code is retured via data */
__raw_writel(0, (unsigned long)data);

return 0;
}
#endif /* CONFIG_DYNAMIC_FTRACE */
Expand Down
6 changes: 1 addition & 5 deletions arch/sparc/kernel/ftrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,8 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
return ftrace_modify_code(ip, old, new);
}

int __init ftrace_dyn_arch_init(void *data)
int __init ftrace_dyn_arch_init(void)
{
unsigned long *p = data;

*p = 0;

return 0;
}
#endif
Expand Down
4 changes: 1 addition & 3 deletions arch/tile/kernel/ftrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,8 @@ int ftrace_make_nop(struct module *mod,
return ret;
}

int __init ftrace_dyn_arch_init(void *data)
int __init ftrace_dyn_arch_init(void)
{
*(unsigned long *)data = 0;

return 0;
}
#endif /* CONFIG_DYNAMIC_FTRACE */
Expand Down
55 changes: 27 additions & 28 deletions arch/x86/kernel/ftrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,10 @@ static int ftrace_write(unsigned long ip, const char *val, int size)
if (within(ip, (unsigned long)_text, (unsigned long)_etext))
ip = (unsigned long)__va(__pa_symbol(ip));

return probe_kernel_write((void *)ip, val, size);
if (probe_kernel_write((void *)ip, val, size))
return -EPERM;

return 0;
}

static int add_break(unsigned long ip, const char *old)
Expand All @@ -323,10 +326,7 @@ static int add_break(unsigned long ip, const char *old)
if (memcmp(replaced, old, MCOUNT_INSN_SIZE) != 0)
return -EINVAL;

if (ftrace_write(ip, &brk, 1))
return -EPERM;

return 0;
return ftrace_write(ip, &brk, 1);
}

static int add_brk_on_call(struct dyn_ftrace *rec, unsigned long addr)
Expand Down Expand Up @@ -425,7 +425,7 @@ static int remove_breakpoint(struct dyn_ftrace *rec)

/* If this does not have a breakpoint, we are done */
if (ins[0] != brk)
return -1;
return 0;

nop = ftrace_nop_replace();

Expand Down Expand Up @@ -455,17 +455,15 @@ static int remove_breakpoint(struct dyn_ftrace *rec)
}

update:
return probe_kernel_write((void *)ip, &nop[0], 1);
return ftrace_write(ip, nop, 1);
}

static int add_update_code(unsigned long ip, unsigned const char *new)
{
/* skip breakpoint */
ip++;
new++;
if (ftrace_write(ip, new, MCOUNT_INSN_SIZE - 1))
return -EPERM;
return 0;
return ftrace_write(ip, new, MCOUNT_INSN_SIZE - 1);
}

static int add_update_call(struct dyn_ftrace *rec, unsigned long addr)
Expand Down Expand Up @@ -520,10 +518,7 @@ static int finish_update_call(struct dyn_ftrace *rec, unsigned long addr)

new = ftrace_call_replace(ip, addr);

if (ftrace_write(ip, new, 1))
return -EPERM;

return 0;
return ftrace_write(ip, new, 1);
}

static int finish_update_nop(struct dyn_ftrace *rec)
Expand All @@ -533,9 +528,7 @@ static int finish_update_nop(struct dyn_ftrace *rec)

new = ftrace_nop_replace();

if (ftrace_write(ip, new, 1))
return -EPERM;
return 0;
return ftrace_write(ip, new, 1);
}

static int finish_update(struct dyn_ftrace *rec, int enable)
Expand Down Expand Up @@ -632,8 +625,14 @@ void ftrace_replace_code(int enable)
printk(KERN_WARNING "Failed on %s (%d):\n", report, count);
for_ftrace_rec_iter(iter) {
rec = ftrace_rec_iter_record(iter);
remove_breakpoint(rec);
/*
* Breakpoints are handled only when this function is in
* progress. The system could not work with them.
*/
if (remove_breakpoint(rec))
BUG();
}
run_sync();
}

static int
Expand All @@ -655,16 +654,19 @@ ftrace_modify_code(unsigned long ip, unsigned const char *old_code,
run_sync();

ret = ftrace_write(ip, new_code, 1);
if (ret) {
ret = -EPERM;
goto out;
}
run_sync();
/*
* The breakpoint is handled only when this function is in progress.
* The system could not work if we could not remove it.
*/
BUG_ON(ret);
out:
run_sync();
return ret;

fail_update:
probe_kernel_write((void *)ip, &old_code[0], 1);
/* Also here the system could not work with the breakpoint */
if (ftrace_write(ip, old_code, 1))
BUG();
goto out;
}

Expand All @@ -678,11 +680,8 @@ void arch_ftrace_update_code(int command)
atomic_dec(&modifying_ftrace_code);
}

int __init ftrace_dyn_arch_init(void *data)
int __init ftrace_dyn_arch_init(void)
{
/* The return code is retured via data */
*(unsigned long *)data = 0;

return 0;
}
#endif
Expand Down
27 changes: 19 additions & 8 deletions include/linux/ftrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ typedef void (*ftrace_func_t)(unsigned long ip, unsigned long parent_ip,
* STUB - The ftrace_ops is just a place holder.
* INITIALIZED - The ftrace_ops has already been initialized (first use time
* register_ftrace_function() is called, it will initialized the ops)
* DELETED - The ops are being deleted, do not let them be registered again.
*/
enum {
FTRACE_OPS_FL_ENABLED = 1 << 0,
Expand All @@ -103,13 +104,26 @@ enum {
FTRACE_OPS_FL_RECURSION_SAFE = 1 << 6,
FTRACE_OPS_FL_STUB = 1 << 7,
FTRACE_OPS_FL_INITIALIZED = 1 << 8,
FTRACE_OPS_FL_DELETED = 1 << 9,
};

/*
* Note, ftrace_ops can be referenced outside of RCU protection.
* (Although, for perf, the control ops prevent that). If ftrace_ops is
* allocated and not part of kernel core data, the unregistering of it will
* perform a scheduling on all CPUs to make sure that there are no more users.
* Depending on the load of the system that may take a bit of time.
*
* Any private data added must also take care not to be freed and if private
* data is added to a ftrace_ops that is in core code, the user of the
* ftrace_ops must perform a schedule_on_each_cpu() before freeing it.
*/
struct ftrace_ops {
ftrace_func_t func;
struct ftrace_ops *next;
unsigned long flags;
int __percpu *disabled;
void *private;
#ifdef CONFIG_DYNAMIC_FTRACE
struct ftrace_hash *notrace_hash;
struct ftrace_hash *filter_hash;
Expand Down Expand Up @@ -285,7 +299,7 @@ extern void
unregister_ftrace_function_probe_func(char *glob, struct ftrace_probe_ops *ops);
extern void unregister_ftrace_function_probe_all(char *glob);

extern int ftrace_text_reserved(void *start, void *end);
extern int ftrace_text_reserved(const void *start, const void *end);

extern int ftrace_nr_registered_ops(void);

Expand Down Expand Up @@ -316,12 +330,9 @@ enum {
#define FTRACE_REF_MAX ((1UL << 29) - 1)

struct dyn_ftrace {
union {
unsigned long ip; /* address of mcount call-site */
struct dyn_ftrace *freelist;
};
unsigned long ip; /* address of mcount call-site */
unsigned long flags;
struct dyn_arch_ftrace arch;
struct dyn_arch_ftrace arch;
};

int ftrace_force_update(void);
Expand Down Expand Up @@ -409,7 +420,7 @@ ftrace_set_early_filter(struct ftrace_ops *ops, char *buf, int enable);

/* defined in arch */
extern int ftrace_ip_converted(unsigned long ip);
extern int ftrace_dyn_arch_init(void *data);
extern int ftrace_dyn_arch_init(void);
extern void ftrace_replace_code(int enable);
extern int ftrace_update_ftrace_func(ftrace_func_t func);
extern void ftrace_caller(void);
Expand Down Expand Up @@ -541,7 +552,7 @@ static inline __init int unregister_ftrace_command(char *cmd_name)
{
return -EINVAL;
}
static inline int ftrace_text_reserved(void *start, void *end)
static inline int ftrace_text_reserved(const void *start, const void *end)
{
return 0;
}
Expand Down
Loading

0 comments on commit 68114e5

Please sign in to comment.