mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-24 21:54:34 -04:00
Merge branches 'tracing/branch-tracer', 'tracing/ftrace', 'tracing/function-return-tracer', 'tracing/tracepoints' and 'tracing/urgent' into tracing/core
This commit is contained in:
commit
3f8e402f34
39 changed files with 841 additions and 429 deletions
|
|
@ -25,6 +25,17 @@ struct ftrace_ops {
|
|||
|
||||
extern int function_trace_stop;
|
||||
|
||||
/*
|
||||
* Type of the current tracing.
|
||||
*/
|
||||
enum ftrace_tracing_type_t {
|
||||
FTRACE_TYPE_ENTER = 0, /* Hook the call of the function */
|
||||
FTRACE_TYPE_RETURN, /* Hook the return of the function */
|
||||
};
|
||||
|
||||
/* Current tracing type, default is FTRACE_TYPE_ENTER */
|
||||
extern enum ftrace_tracing_type_t ftrace_tracing_type;
|
||||
|
||||
/**
|
||||
* ftrace_stop - stop function tracer.
|
||||
*
|
||||
|
|
@ -74,6 +85,9 @@ static inline void ftrace_start(void) { }
|
|||
#endif /* CONFIG_FUNCTION_TRACER */
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE
|
||||
/* asm/ftrace.h must be defined for archs supporting dynamic ftrace */
|
||||
#include <asm/ftrace.h>
|
||||
|
||||
enum {
|
||||
FTRACE_FL_FREE = (1 << 0),
|
||||
FTRACE_FL_FAILED = (1 << 1),
|
||||
|
|
@ -88,6 +102,7 @@ struct dyn_ftrace {
|
|||
struct list_head list;
|
||||
unsigned long ip; /* address of mcount call-site */
|
||||
unsigned long flags;
|
||||
struct dyn_arch_ftrace arch;
|
||||
};
|
||||
|
||||
int ftrace_force_update(void);
|
||||
|
|
@ -95,22 +110,20 @@ void ftrace_set_filter(unsigned char *buf, int len, int reset);
|
|||
|
||||
/* defined in arch */
|
||||
extern int ftrace_ip_converted(unsigned long ip);
|
||||
extern unsigned char *ftrace_nop_replace(void);
|
||||
extern unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr);
|
||||
extern int ftrace_dyn_arch_init(void *data);
|
||||
extern int ftrace_update_ftrace_func(ftrace_func_t func);
|
||||
extern void ftrace_caller(void);
|
||||
extern void ftrace_call(void);
|
||||
extern void mcount_call(void);
|
||||
|
||||
/* May be defined in arch */
|
||||
extern int ftrace_arch_read_dyn_info(char *buf, int size);
|
||||
#ifdef CONFIG_FUNCTION_RET_TRACER
|
||||
extern void ftrace_return_caller(void);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* ftrace_modify_code - modify code segment
|
||||
* @ip: the address of the code segment
|
||||
* @old_code: the contents of what is expected to be there
|
||||
* @new_code: the code to patch in
|
||||
* ftrace_make_nop - convert code into top
|
||||
* @mod: module structure if called by module load initialization
|
||||
* @rec: the mcount call site record
|
||||
* @addr: the address that the call site should be calling
|
||||
*
|
||||
* This is a very sensitive operation and great care needs
|
||||
* to be taken by the arch. The operation should carefully
|
||||
|
|
@ -118,6 +131,8 @@ extern int ftrace_arch_read_dyn_info(char *buf, int size);
|
|||
* what we expect it to be, and then on success of the compare,
|
||||
* it should write to the location.
|
||||
*
|
||||
* The code segment at @rec->ip should be a caller to @addr
|
||||
*
|
||||
* Return must be:
|
||||
* 0 on success
|
||||
* -EFAULT on error reading the location
|
||||
|
|
@ -125,8 +140,34 @@ extern int ftrace_arch_read_dyn_info(char *buf, int size);
|
|||
* -EPERM on error writing to the location
|
||||
* Any other value will be considered a failure.
|
||||
*/
|
||||
extern int ftrace_modify_code(unsigned long ip, unsigned char *old_code,
|
||||
unsigned char *new_code);
|
||||
extern int ftrace_make_nop(struct module *mod,
|
||||
struct dyn_ftrace *rec, unsigned long addr);
|
||||
|
||||
/**
|
||||
* ftrace_make_call - convert a nop call site into a call to addr
|
||||
* @rec: the mcount call site record
|
||||
* @addr: the address that the call site should call
|
||||
*
|
||||
* This is a very sensitive operation and great care needs
|
||||
* to be taken by the arch. The operation should carefully
|
||||
* read the location, check to see if what is read is indeed
|
||||
* what we expect it to be, and then on success of the compare,
|
||||
* it should write to the location.
|
||||
*
|
||||
* The code segment at @rec->ip should be a nop
|
||||
*
|
||||
* Return must be:
|
||||
* 0 on success
|
||||
* -EFAULT on error reading the location
|
||||
* -EINVAL on a failed compare of the contents
|
||||
* -EPERM on error writing to the location
|
||||
* Any other value will be considered a failure.
|
||||
*/
|
||||
extern int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr);
|
||||
|
||||
|
||||
/* May be defined in arch */
|
||||
extern int ftrace_arch_read_dyn_info(char *buf, int size);
|
||||
|
||||
extern int skip_trace(unsigned long ip);
|
||||
|
||||
|
|
@ -259,11 +300,13 @@ static inline void ftrace_dump(void) { }
|
|||
|
||||
#ifdef CONFIG_FTRACE_MCOUNT_RECORD
|
||||
extern void ftrace_init(void);
|
||||
extern void ftrace_init_module(unsigned long *start, unsigned long *end);
|
||||
extern void ftrace_init_module(struct module *mod,
|
||||
unsigned long *start, unsigned long *end);
|
||||
#else
|
||||
static inline void ftrace_init(void) { }
|
||||
static inline void
|
||||
ftrace_init_module(unsigned long *start, unsigned long *end) { }
|
||||
ftrace_init_module(struct module *mod,
|
||||
unsigned long *start, unsigned long *end) { }
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -281,7 +324,7 @@ struct ftrace_retfunc {
|
|||
/* Type of a callback handler of tracing return function */
|
||||
typedef void (*trace_function_return_t)(struct ftrace_retfunc *);
|
||||
|
||||
extern void register_ftrace_return(trace_function_return_t func);
|
||||
extern int register_ftrace_return(trace_function_return_t func);
|
||||
/* The current handler in use */
|
||||
extern trace_function_return_t ftrace_function_return;
|
||||
extern void unregister_ftrace_return(void);
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
* See the file COPYING for more details.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
struct module;
|
||||
|
|
@ -48,10 +49,28 @@ struct marker {
|
|||
void (*call)(const struct marker *mdata, void *call_private, ...);
|
||||
struct marker_probe_closure single;
|
||||
struct marker_probe_closure *multi;
|
||||
const char *tp_name; /* Optional tracepoint name */
|
||||
void *tp_cb; /* Optional tracepoint callback */
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
#ifdef CONFIG_MARKERS
|
||||
|
||||
#define _DEFINE_MARKER(name, tp_name_str, tp_cb, format) \
|
||||
static const char __mstrtab_##name[] \
|
||||
__attribute__((section("__markers_strings"))) \
|
||||
= #name "\0" format; \
|
||||
static struct marker __mark_##name \
|
||||
__attribute__((section("__markers"), aligned(8))) = \
|
||||
{ __mstrtab_##name, &__mstrtab_##name[sizeof(#name)], \
|
||||
0, 0, marker_probe_cb, { __mark_empty_function, NULL},\
|
||||
NULL, tp_name_str, tp_cb }
|
||||
|
||||
#define DEFINE_MARKER(name, format) \
|
||||
_DEFINE_MARKER(name, NULL, NULL, format)
|
||||
|
||||
#define DEFINE_MARKER_TP(name, tp_name, tp_cb, format) \
|
||||
_DEFINE_MARKER(name, #tp_name, tp_cb, format)
|
||||
|
||||
/*
|
||||
* Note : the empty asm volatile with read constraint is used here instead of a
|
||||
* "used" attribute to fix a gcc 4.1.x bug.
|
||||
|
|
@ -65,14 +84,7 @@ struct marker {
|
|||
*/
|
||||
#define __trace_mark(generic, name, call_private, format, args...) \
|
||||
do { \
|
||||
static const char __mstrtab_##name[] \
|
||||
__attribute__((section("__markers_strings"))) \
|
||||
= #name "\0" format; \
|
||||
static struct marker __mark_##name \
|
||||
__attribute__((section("__markers"), aligned(8))) = \
|
||||
{ __mstrtab_##name, &__mstrtab_##name[sizeof(#name)], \
|
||||
0, 0, marker_probe_cb, \
|
||||
{ __mark_empty_function, NULL}, NULL }; \
|
||||
DEFINE_MARKER(name, format); \
|
||||
__mark_check_format(format, ## args); \
|
||||
if (unlikely(__mark_##name.state)) { \
|
||||
(*__mark_##name.call) \
|
||||
|
|
@ -80,14 +92,39 @@ struct marker {
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
#define __trace_mark_tp(name, call_private, tp_name, tp_cb, format, args...) \
|
||||
do { \
|
||||
void __check_tp_type(void) \
|
||||
{ \
|
||||
register_trace_##tp_name(tp_cb); \
|
||||
} \
|
||||
DEFINE_MARKER_TP(name, tp_name, tp_cb, format); \
|
||||
__mark_check_format(format, ## args); \
|
||||
(*__mark_##name.call)(&__mark_##name, call_private, \
|
||||
## args); \
|
||||
} while (0)
|
||||
|
||||
extern void marker_update_probe_range(struct marker *begin,
|
||||
struct marker *end);
|
||||
|
||||
#define GET_MARKER(name) (__mark_##name)
|
||||
|
||||
#else /* !CONFIG_MARKERS */
|
||||
#define DEFINE_MARKER(name, tp_name, tp_cb, format)
|
||||
#define __trace_mark(generic, name, call_private, format, args...) \
|
||||
__mark_check_format(format, ## args)
|
||||
#define __trace_mark_tp(name, call_private, tp_name, tp_cb, format, args...) \
|
||||
do { \
|
||||
void __check_tp_type(void) \
|
||||
{ \
|
||||
register_trace_##tp_name(tp_cb); \
|
||||
} \
|
||||
__mark_check_format(format, ## args); \
|
||||
} while (0)
|
||||
static inline void marker_update_probe_range(struct marker *begin,
|
||||
struct marker *end)
|
||||
{ }
|
||||
#define GET_MARKER(name)
|
||||
#endif /* CONFIG_MARKERS */
|
||||
|
||||
/**
|
||||
|
|
@ -116,6 +153,20 @@ static inline void marker_update_probe_range(struct marker *begin,
|
|||
#define _trace_mark(name, format, args...) \
|
||||
__trace_mark(1, name, NULL, format, ## args)
|
||||
|
||||
/**
|
||||
* trace_mark_tp - Marker in a tracepoint callback
|
||||
* @name: marker name, not quoted.
|
||||
* @tp_name: tracepoint name, not quoted.
|
||||
* @tp_cb: tracepoint callback. Should have an associated global symbol so it
|
||||
* is not optimized away by the compiler (should not be static).
|
||||
* @format: format string
|
||||
* @args...: variable argument list
|
||||
*
|
||||
* Places a marker in a tracepoint callback.
|
||||
*/
|
||||
#define trace_mark_tp(name, tp_name, tp_cb, format, args...) \
|
||||
__trace_mark_tp(name, NULL, tp_name, tp_cb, format, ## args)
|
||||
|
||||
/**
|
||||
* MARK_NOARGS - Format string for a marker with no argument.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -142,6 +142,7 @@ struct rcu_head {
|
|||
* on the write-side to insure proper synchronization.
|
||||
*/
|
||||
#define rcu_read_lock_sched() preempt_disable()
|
||||
#define rcu_read_lock_sched_notrace() preempt_disable_notrace()
|
||||
|
||||
/*
|
||||
* rcu_read_unlock_sched - marks the end of a RCU-classic critical section
|
||||
|
|
@ -149,6 +150,7 @@ struct rcu_head {
|
|||
* See rcu_read_lock_sched for more information.
|
||||
*/
|
||||
#define rcu_read_unlock_sched() preempt_enable()
|
||||
#define rcu_read_unlock_sched_notrace() preempt_enable_notrace()
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -24,8 +24,12 @@ struct tracepoint {
|
|||
const char *name; /* Tracepoint name */
|
||||
int state; /* State. */
|
||||
void **funcs;
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
} __attribute__((aligned(32))); /*
|
||||
* Aligned on 32 bytes because it is
|
||||
* globally visible and gcc happily
|
||||
* align these on the structure size.
|
||||
* Keep in sync with vmlinux.lds.h.
|
||||
*/
|
||||
|
||||
#define TPPROTO(args...) args
|
||||
#define TPARGS(args...) args
|
||||
|
|
@ -40,14 +44,14 @@ struct tracepoint {
|
|||
do { \
|
||||
void **it_func; \
|
||||
\
|
||||
rcu_read_lock_sched(); \
|
||||
rcu_read_lock_sched_notrace(); \
|
||||
it_func = rcu_dereference((tp)->funcs); \
|
||||
if (it_func) { \
|
||||
do { \
|
||||
((void(*)(proto))(*it_func))(args); \
|
||||
} while (*(++it_func)); \
|
||||
} \
|
||||
rcu_read_unlock_sched(); \
|
||||
rcu_read_unlock_sched_notrace(); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
|
|
@ -55,35 +59,40 @@ struct tracepoint {
|
|||
* not add unwanted padding between the beginning of the section and the
|
||||
* structure. Force alignment to the same alignment as the section start.
|
||||
*/
|
||||
#define DEFINE_TRACE(name, proto, args) \
|
||||
#define DECLARE_TRACE(name, proto, args) \
|
||||
extern struct tracepoint __tracepoint_##name; \
|
||||
static inline void trace_##name(proto) \
|
||||
{ \
|
||||
static const char __tpstrtab_##name[] \
|
||||
__attribute__((section("__tracepoints_strings"))) \
|
||||
= #name ":" #proto; \
|
||||
static struct tracepoint __tracepoint_##name \
|
||||
__attribute__((section("__tracepoints"), aligned(8))) = \
|
||||
{ __tpstrtab_##name, 0, NULL }; \
|
||||
if (unlikely(__tracepoint_##name.state)) \
|
||||
__DO_TRACE(&__tracepoint_##name, \
|
||||
TPPROTO(proto), TPARGS(args)); \
|
||||
} \
|
||||
static inline int register_trace_##name(void (*probe)(proto)) \
|
||||
{ \
|
||||
return tracepoint_probe_register(#name ":" #proto, \
|
||||
(void *)probe); \
|
||||
return tracepoint_probe_register(#name, (void *)probe); \
|
||||
} \
|
||||
static inline void unregister_trace_##name(void (*probe)(proto))\
|
||||
static inline int unregister_trace_##name(void (*probe)(proto)) \
|
||||
{ \
|
||||
tracepoint_probe_unregister(#name ":" #proto, \
|
||||
(void *)probe); \
|
||||
return tracepoint_probe_unregister(#name, (void *)probe);\
|
||||
}
|
||||
|
||||
#define DEFINE_TRACE(name) \
|
||||
static const char __tpstrtab_##name[] \
|
||||
__attribute__((section("__tracepoints_strings"))) = #name; \
|
||||
struct tracepoint __tracepoint_##name \
|
||||
__attribute__((section("__tracepoints"), aligned(32))) = \
|
||||
{ __tpstrtab_##name, 0, NULL }
|
||||
|
||||
#define EXPORT_TRACEPOINT_SYMBOL_GPL(name) \
|
||||
EXPORT_SYMBOL_GPL(__tracepoint_##name)
|
||||
#define EXPORT_TRACEPOINT_SYMBOL(name) \
|
||||
EXPORT_SYMBOL(__tracepoint_##name)
|
||||
|
||||
extern void tracepoint_update_probe_range(struct tracepoint *begin,
|
||||
struct tracepoint *end);
|
||||
|
||||
#else /* !CONFIG_TRACEPOINTS */
|
||||
#define DEFINE_TRACE(name, proto, args) \
|
||||
#define DECLARE_TRACE(name, proto, args) \
|
||||
static inline void _do_trace_##name(struct tracepoint *tp, proto) \
|
||||
{ } \
|
||||
static inline void trace_##name(proto) \
|
||||
|
|
@ -92,8 +101,14 @@ extern void tracepoint_update_probe_range(struct tracepoint *begin,
|
|||
{ \
|
||||
return -ENOSYS; \
|
||||
} \
|
||||
static inline void unregister_trace_##name(void (*probe)(proto))\
|
||||
{ }
|
||||
static inline int unregister_trace_##name(void (*probe)(proto)) \
|
||||
{ \
|
||||
return -ENOSYS; \
|
||||
}
|
||||
|
||||
#define DEFINE_TRACE(name)
|
||||
#define EXPORT_TRACEPOINT_SYMBOL_GPL(name)
|
||||
#define EXPORT_TRACEPOINT_SYMBOL(name)
|
||||
|
||||
static inline void tracepoint_update_probe_range(struct tracepoint *begin,
|
||||
struct tracepoint *end)
|
||||
|
|
|
|||
Loading…
Reference in a new issue