Merge e9f0a36347 ("tracing: Remove TRACE_FLAG_IRQS_NOSUPPORT") into android-mainline
Steps on the way to 6.13-rc1 Change-Id: I51d5ede4811cf586d9d99aff905e91fbb71817d9 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
commit
ad7b53dbaa
19 files changed
+224
-177
No files matched your search
@@ -1031,9 +1031,6 @@ explains which is which.
|
||||
CPU#: The CPU which the process was running on.
|
||||
|
||||
irqs-off: 'd' interrupts are disabled. '.' otherwise.
|
||||
.. caution:: If the architecture does not support a way to
|
||||
read the irq flags variable, an 'X' will always
|
||||
be printed here.
|
||||
|
||||
need-resched:
|
||||
- 'N' both TIF_NEED_RESCHED and PREEMPT_NEED_RESCHED is set,
|
||||
|
||||
@@ -184,7 +184,6 @@ unsigned int tracing_gen_ctx_irq_test(unsigned int irqs_status);
|
||||
|
||||
enum trace_flag_type {
|
||||
TRACE_FLAG_IRQS_OFF = 0x01,
|
||||
TRACE_FLAG_IRQS_NOSUPPORT = 0x02,
|
||||
TRACE_FLAG_NEED_RESCHED = 0x04,
|
||||
TRACE_FLAG_HARDIRQ = 0x08,
|
||||
TRACE_FLAG_SOFTIRQ = 0x10,
|
||||
@@ -193,7 +192,6 @@ enum trace_flag_type {
|
||||
TRACE_FLAG_BH_OFF = 0x80,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT
|
||||
static inline unsigned int tracing_gen_ctx_flags(unsigned long irqflags)
|
||||
{
|
||||
unsigned int irq_status = irqs_disabled_flags(irqflags) ?
|
||||
@@ -207,17 +205,6 @@ static inline unsigned int tracing_gen_ctx(void)
|
||||
local_save_flags(irqflags);
|
||||
return tracing_gen_ctx_flags(irqflags);
|
||||
}
|
||||
#else
|
||||
|
||||
static inline unsigned int tracing_gen_ctx_flags(unsigned long irqflags)
|
||||
{
|
||||
return tracing_gen_ctx_irq_test(TRACE_FLAG_IRQS_NOSUPPORT);
|
||||
}
|
||||
static inline unsigned int tracing_gen_ctx(void)
|
||||
{
|
||||
return tracing_gen_ctx_irq_test(TRACE_FLAG_IRQS_NOSUPPORT);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline unsigned int tracing_gen_ctx_dec(void)
|
||||
{
|
||||
|
||||
+56
-65
@@ -17,6 +17,7 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/rcupdate.h>
|
||||
#include <linux/rcupdate_trace.h>
|
||||
#include <linux/tracepoint-defs.h>
|
||||
#include <linux/static_call.h>
|
||||
|
||||
@@ -32,8 +33,6 @@ struct trace_eval_map {
|
||||
|
||||
#define TRACEPOINT_DEFAULT_PRIO 10
|
||||
|
||||
extern struct srcu_struct tracepoint_srcu;
|
||||
|
||||
extern int
|
||||
tracepoint_probe_register(struct tracepoint *tp, void *probe, void *data);
|
||||
extern int
|
||||
@@ -109,7 +108,7 @@ void for_each_tracepoint_in_module(struct module *mod,
|
||||
#ifdef CONFIG_TRACEPOINTS
|
||||
static inline void tracepoint_synchronize_unregister(void)
|
||||
{
|
||||
synchronize_srcu(&tracepoint_srcu);
|
||||
synchronize_rcu_tasks_trace();
|
||||
synchronize_rcu();
|
||||
}
|
||||
#else
|
||||
@@ -196,67 +195,36 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
|
||||
#define __DO_TRACE_CALL(name, args) __traceiter_##name(NULL, args)
|
||||
#endif /* CONFIG_HAVE_STATIC_CALL */
|
||||
|
||||
/*
|
||||
* ARCH_WANTS_NO_INSTR archs are expected to have sanitized entry and idle
|
||||
* code that disallow any/all tracing/instrumentation when RCU isn't watching.
|
||||
*/
|
||||
#ifdef CONFIG_ARCH_WANTS_NO_INSTR
|
||||
#define RCUIDLE_COND(rcuidle) (rcuidle)
|
||||
#else
|
||||
/* srcu can't be used from NMI */
|
||||
#define RCUIDLE_COND(rcuidle) (rcuidle && in_nmi())
|
||||
#endif
|
||||
|
||||
/*
|
||||
* it_func[0] is never NULL because there is at least one element in the array
|
||||
* when the array itself is non NULL.
|
||||
*
|
||||
* With @syscall=0, the tracepoint callback array dereference is
|
||||
* protected by disabling preemption.
|
||||
* With @syscall=1, the tracepoint callback array dereference is
|
||||
* protected by Tasks Trace RCU, which allows probes to handle page
|
||||
* faults.
|
||||
*/
|
||||
#define __DO_TRACE(name, args, cond, rcuidle) \
|
||||
#define __DO_TRACE(name, args, cond, syscall) \
|
||||
do { \
|
||||
int __maybe_unused __idx = 0; \
|
||||
\
|
||||
if (!(cond)) \
|
||||
return; \
|
||||
\
|
||||
if (WARN_ONCE(RCUIDLE_COND(rcuidle), \
|
||||
"Bad RCU usage for tracepoint")) \
|
||||
return; \
|
||||
\
|
||||
/* keep srcu and sched-rcu usage consistent */ \
|
||||
preempt_disable_notrace(); \
|
||||
\
|
||||
/* \
|
||||
* For rcuidle callers, use srcu since sched-rcu \
|
||||
* doesn't work from the idle path. \
|
||||
*/ \
|
||||
if (rcuidle) { \
|
||||
__idx = srcu_read_lock_notrace(&tracepoint_srcu);\
|
||||
ct_irq_enter_irqson(); \
|
||||
} \
|
||||
if (syscall) \
|
||||
rcu_read_lock_trace(); \
|
||||
else \
|
||||
preempt_disable_notrace(); \
|
||||
\
|
||||
__DO_TRACE_CALL(name, TP_ARGS(args)); \
|
||||
\
|
||||
if (rcuidle) { \
|
||||
ct_irq_exit_irqson(); \
|
||||
srcu_read_unlock_notrace(&tracepoint_srcu, __idx);\
|
||||
} \
|
||||
\
|
||||
preempt_enable_notrace(); \
|
||||
if (syscall) \
|
||||
rcu_read_unlock_trace(); \
|
||||
else \
|
||||
preempt_enable_notrace(); \
|
||||
} while (0)
|
||||
|
||||
#ifndef MODULE
|
||||
#define __DECLARE_TRACE_RCU(name, proto, args, cond) \
|
||||
static inline void trace_##name##_rcuidle(proto) \
|
||||
{ \
|
||||
if (static_branch_unlikely(&__tracepoint_##name.key)) \
|
||||
__DO_TRACE(name, \
|
||||
TP_ARGS(args), \
|
||||
TP_CONDITION(cond), 1); \
|
||||
}
|
||||
#else
|
||||
#define __DECLARE_TRACE_RCU(name, proto, args, cond)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Make sure the alignment of the structure in the __tracepoints section will
|
||||
* not add unwanted padding between the beginning of the section and the
|
||||
@@ -268,23 +236,10 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
|
||||
* site if it is not watching, as it will need to be active when the
|
||||
* tracepoint is enabled.
|
||||
*/
|
||||
#define __DECLARE_TRACE(name, proto, args, cond, data_proto) \
|
||||
#define __DECLARE_TRACE_COMMON(name, proto, args, cond, data_proto) \
|
||||
extern int __traceiter_##name(data_proto); \
|
||||
DECLARE_STATIC_CALL(tp_func_##name, __traceiter_##name); \
|
||||
extern struct tracepoint __tracepoint_##name; \
|
||||
static inline void trace_##name(proto) \
|
||||
{ \
|
||||
if (static_branch_unlikely(&__tracepoint_##name.key)) \
|
||||
__DO_TRACE(name, \
|
||||
TP_ARGS(args), \
|
||||
TP_CONDITION(cond), 0); \
|
||||
if (IS_ENABLED(CONFIG_LOCKDEP) && (cond)) { \
|
||||
WARN_ONCE(!rcu_is_watching(), \
|
||||
"RCU not watching for tracepoint"); \
|
||||
} \
|
||||
} \
|
||||
__DECLARE_TRACE_RCU(name, PARAMS(proto), PARAMS(args), \
|
||||
PARAMS(cond)) \
|
||||
static inline int \
|
||||
register_trace_##name(void (*probe)(data_proto), void *data) \
|
||||
{ \
|
||||
@@ -314,6 +269,34 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
|
||||
return static_branch_unlikely(&__tracepoint_##name.key);\
|
||||
}
|
||||
|
||||
#define __DECLARE_TRACE(name, proto, args, cond, data_proto) \
|
||||
__DECLARE_TRACE_COMMON(name, PARAMS(proto), PARAMS(args), cond, PARAMS(data_proto)) \
|
||||
static inline void trace_##name(proto) \
|
||||
{ \
|
||||
if (static_branch_unlikely(&__tracepoint_##name.key)) \
|
||||
__DO_TRACE(name, \
|
||||
TP_ARGS(args), \
|
||||
TP_CONDITION(cond), 0); \
|
||||
if (IS_ENABLED(CONFIG_LOCKDEP) && (cond)) { \
|
||||
WARN_ONCE(!rcu_is_watching(), \
|
||||
"RCU not watching for tracepoint"); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define __DECLARE_TRACE_SYSCALL(name, proto, args, cond, data_proto) \
|
||||
__DECLARE_TRACE_COMMON(name, PARAMS(proto), PARAMS(args), cond, PARAMS(data_proto)) \
|
||||
static inline void trace_##name(proto) \
|
||||
{ \
|
||||
if (static_branch_unlikely(&__tracepoint_##name.key)) \
|
||||
__DO_TRACE(name, \
|
||||
TP_ARGS(args), \
|
||||
TP_CONDITION(cond), 1); \
|
||||
if (IS_ENABLED(CONFIG_LOCKDEP) && (cond)) { \
|
||||
WARN_ONCE(!rcu_is_watching(), \
|
||||
"RCU not watching for tracepoint"); \
|
||||
} \
|
||||
}
|
||||
|
||||
/*
|
||||
* We have no guarantee that gcc and the linker won't up-align the tracepoint
|
||||
* structures, so we create an array of pointers that will be used for iteration
|
||||
@@ -375,8 +358,6 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
|
||||
#define __DECLARE_TRACE(name, proto, args, cond, data_proto) \
|
||||
static inline void trace_##name(proto) \
|
||||
{ } \
|
||||
static inline void trace_##name##_rcuidle(proto) \
|
||||
{ } \
|
||||
static inline int \
|
||||
register_trace_##name(void (*probe)(data_proto), \
|
||||
void *data) \
|
||||
@@ -398,6 +379,8 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
|
||||
return false; \
|
||||
}
|
||||
|
||||
#define __DECLARE_TRACE_SYSCALL __DECLARE_TRACE
|
||||
|
||||
#define DEFINE_TRACE_FN(name, reg, unreg, proto, args)
|
||||
#define DEFINE_TRACE(name, proto, args)
|
||||
#define EXPORT_TRACEPOINT_SYMBOL_GPL(name)
|
||||
@@ -459,6 +442,11 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
|
||||
cpu_online(raw_smp_processor_id()) && (PARAMS(cond)), \
|
||||
PARAMS(void *__data, proto))
|
||||
|
||||
#define DECLARE_TRACE_SYSCALL(name, proto, args) \
|
||||
__DECLARE_TRACE_SYSCALL(name, PARAMS(proto), PARAMS(args), \
|
||||
cpu_online(raw_smp_processor_id()), \
|
||||
PARAMS(void *__data, proto))
|
||||
|
||||
#define TRACE_EVENT_FLAGS(event, flag)
|
||||
|
||||
#define TRACE_EVENT_PERF_PERM(event, expr...)
|
||||
@@ -596,6 +584,9 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
|
||||
struct, assign, print) \
|
||||
DECLARE_TRACE_CONDITION(name, PARAMS(proto), \
|
||||
PARAMS(args), PARAMS(cond))
|
||||
#define TRACE_EVENT_SYSCALL(name, proto, args, struct, assign, \
|
||||
print, reg, unreg) \
|
||||
DECLARE_TRACE_SYSCALL(name, PARAMS(proto), PARAMS(args))
|
||||
|
||||
#define TRACE_EVENT_FLAGS(event, flag)
|
||||
|
||||
|
||||
@@ -53,6 +53,20 @@ __bpf_trace_##call(void *__data, proto) \
|
||||
#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
|
||||
__BPF_DECLARE_TRACE(call, PARAMS(proto), PARAMS(args))
|
||||
|
||||
#define __BPF_DECLARE_TRACE_SYSCALL(call, proto, args) \
|
||||
static notrace void \
|
||||
__bpf_trace_##call(void *__data, proto) \
|
||||
{ \
|
||||
might_fault(); \
|
||||
preempt_disable_notrace(); \
|
||||
CONCATENATE(bpf_trace_run, COUNT_ARGS(args))(__data, CAST_TO_U64(args)); \
|
||||
preempt_enable_notrace(); \
|
||||
}
|
||||
|
||||
#undef DECLARE_EVENT_SYSCALL_CLASS
|
||||
#define DECLARE_EVENT_SYSCALL_CLASS(call, proto, args, tstruct, assign, print) \
|
||||
__BPF_DECLARE_TRACE_SYSCALL(call, PARAMS(proto), PARAMS(args))
|
||||
|
||||
/*
|
||||
* This part is compiled out, it is only here as a build time check
|
||||
* to make sure that if the tracepoint handling changes, the
|
||||
|
||||
@@ -46,6 +46,10 @@
|
||||
assign, print, reg, unreg) \
|
||||
DEFINE_TRACE_FN(name, reg, unreg, PARAMS(proto), PARAMS(args))
|
||||
|
||||
#undef TRACE_EVENT_SYSCALL
|
||||
#define TRACE_EVENT_SYSCALL(name, proto, args, struct, assign, print, reg, unreg) \
|
||||
DEFINE_TRACE_FN(name, reg, unreg, PARAMS(proto), PARAMS(args))
|
||||
|
||||
#undef TRACE_EVENT_NOP
|
||||
#define TRACE_EVENT_NOP(name, proto, args, struct, assign, print)
|
||||
|
||||
@@ -107,6 +111,7 @@
|
||||
#undef TRACE_EVENT
|
||||
#undef TRACE_EVENT_FN
|
||||
#undef TRACE_EVENT_FN_COND
|
||||
#undef TRACE_EVENT_SYSCALL
|
||||
#undef TRACE_EVENT_CONDITION
|
||||
#undef TRACE_EVENT_NOP
|
||||
#undef DEFINE_EVENT_NOP
|
||||
|
||||
@@ -43,8 +43,6 @@ DEFINE_EVENT(preemptirq_template, irq_enable,
|
||||
#else
|
||||
#define trace_irq_enable(...)
|
||||
#define trace_irq_disable(...)
|
||||
#define trace_irq_enable_rcuidle(...)
|
||||
#define trace_irq_disable_rcuidle(...)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TRACE_PREEMPT_TOGGLE
|
||||
@@ -58,8 +56,6 @@ DEFINE_EVENT(preemptirq_template, preempt_enable,
|
||||
#else
|
||||
#define trace_preempt_enable(...)
|
||||
#define trace_preempt_disable(...)
|
||||
#define trace_preempt_enable_rcuidle(...)
|
||||
#define trace_preempt_disable_rcuidle(...)
|
||||
#endif
|
||||
|
||||
#endif /* _TRACE_PREEMPTIRQ_H */
|
||||
@@ -69,10 +65,6 @@ DEFINE_EVENT(preemptirq_template, preempt_enable,
|
||||
#else /* !CONFIG_PREEMPTIRQ_TRACEPOINTS */
|
||||
#define trace_irq_enable(...)
|
||||
#define trace_irq_disable(...)
|
||||
#define trace_irq_enable_rcuidle(...)
|
||||
#define trace_irq_disable_rcuidle(...)
|
||||
#define trace_preempt_enable(...)
|
||||
#define trace_preempt_disable(...)
|
||||
#define trace_preempt_enable_rcuidle(...)
|
||||
#define trace_preempt_disable_rcuidle(...)
|
||||
#endif
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
|
||||
|
||||
TRACE_EVENT_FN(sys_enter,
|
||||
TRACE_EVENT_SYSCALL(sys_enter,
|
||||
|
||||
TP_PROTO(struct pt_regs *regs, long id),
|
||||
|
||||
@@ -41,7 +41,7 @@ TRACE_EVENT_FN(sys_enter,
|
||||
|
||||
TRACE_EVENT_FLAGS(sys_enter, TRACE_EVENT_FL_CAP_ANY)
|
||||
|
||||
TRACE_EVENT_FN(sys_exit,
|
||||
TRACE_EVENT_SYSCALL(sys_exit,
|
||||
|
||||
TP_PROTO(struct pt_regs *regs, long ret),
|
||||
|
||||
|
||||
+41
-3
@@ -12,10 +12,10 @@
|
||||
#undef __perf_task
|
||||
#define __perf_task(t) (__task = (t))
|
||||
|
||||
#undef DECLARE_EVENT_CLASS
|
||||
#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
|
||||
#undef __DECLARE_EVENT_CLASS
|
||||
#define __DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
|
||||
static notrace void \
|
||||
perf_trace_##call(void *__data, proto) \
|
||||
do_perf_trace_##call(void *__data, proto) \
|
||||
{ \
|
||||
struct trace_event_call *event_call = __data; \
|
||||
struct trace_event_data_offsets_##call __maybe_unused __data_offsets;\
|
||||
@@ -55,6 +55,41 @@ perf_trace_##call(void *__data, proto) \
|
||||
head, __task); \
|
||||
}
|
||||
|
||||
/*
|
||||
* Define unused __count and __task variables to use @args to pass
|
||||
* arguments to do_perf_trace_##call. This is needed because the
|
||||
* macros __perf_count and __perf_task introduce the side-effect to
|
||||
* store copies into those local variables.
|
||||
*/
|
||||
#undef DECLARE_EVENT_CLASS
|
||||
#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
|
||||
__DECLARE_EVENT_CLASS(call, PARAMS(proto), PARAMS(args), PARAMS(tstruct), \
|
||||
PARAMS(assign), PARAMS(print)) \
|
||||
static notrace void \
|
||||
perf_trace_##call(void *__data, proto) \
|
||||
{ \
|
||||
u64 __count __attribute__((unused)); \
|
||||
struct task_struct *__task __attribute__((unused)); \
|
||||
\
|
||||
do_perf_trace_##call(__data, args); \
|
||||
}
|
||||
|
||||
#undef DECLARE_EVENT_SYSCALL_CLASS
|
||||
#define DECLARE_EVENT_SYSCALL_CLASS(call, proto, args, tstruct, assign, print) \
|
||||
__DECLARE_EVENT_CLASS(call, PARAMS(proto), PARAMS(args), PARAMS(tstruct), \
|
||||
PARAMS(assign), PARAMS(print)) \
|
||||
static notrace void \
|
||||
perf_trace_##call(void *__data, proto) \
|
||||
{ \
|
||||
u64 __count __attribute__((unused)); \
|
||||
struct task_struct *__task __attribute__((unused)); \
|
||||
\
|
||||
might_fault(); \
|
||||
preempt_disable_notrace(); \
|
||||
do_perf_trace_##call(__data, args); \
|
||||
preempt_enable_notrace(); \
|
||||
}
|
||||
|
||||
/*
|
||||
* This part is compiled out, it is only here as a build time check
|
||||
* to make sure that if the tracepoint handling changes, the
|
||||
@@ -73,4 +108,7 @@ static inline void perf_test_probe_##call(void) \
|
||||
DEFINE_EVENT(template, name, PARAMS(proto), PARAMS(args))
|
||||
|
||||
#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
|
||||
|
||||
#undef __DECLARE_EVENT_CLASS
|
||||
|
||||
#endif /* CONFIG_PERF_EVENTS */
|
||||
@@ -45,6 +45,16 @@
|
||||
PARAMS(print)); \
|
||||
DEFINE_EVENT(name, name, PARAMS(proto), PARAMS(args));
|
||||
|
||||
#undef TRACE_EVENT_SYSCALL
|
||||
#define TRACE_EVENT_SYSCALL(name, proto, args, tstruct, assign, print, reg, unreg) \
|
||||
DECLARE_EVENT_SYSCALL_CLASS(name, \
|
||||
PARAMS(proto), \
|
||||
PARAMS(args), \
|
||||
PARAMS(tstruct), \
|
||||
PARAMS(assign), \
|
||||
PARAMS(print)); \
|
||||
DEFINE_EVENT(name, name, PARAMS(proto), PARAMS(args));
|
||||
|
||||
#include "stages/stage1_struct_define.h"
|
||||
|
||||
#undef DECLARE_EVENT_CLASS
|
||||
@@ -57,6 +67,9 @@
|
||||
\
|
||||
static struct trace_event_class event_class_##name;
|
||||
|
||||
#undef DECLARE_EVENT_SYSCALL_CLASS
|
||||
#define DECLARE_EVENT_SYSCALL_CLASS DECLARE_EVENT_CLASS
|
||||
|
||||
#undef DEFINE_EVENT
|
||||
#define DEFINE_EVENT(template, name, proto, args) \
|
||||
static struct trace_event_call __used \
|
||||
@@ -117,6 +130,9 @@
|
||||
tstruct; \
|
||||
};
|
||||
|
||||
#undef DECLARE_EVENT_SYSCALL_CLASS
|
||||
#define DECLARE_EVENT_SYSCALL_CLASS DECLARE_EVENT_CLASS
|
||||
|
||||
#undef DEFINE_EVENT
|
||||
#define DEFINE_EVENT(template, name, proto, args)
|
||||
|
||||
@@ -208,6 +224,9 @@ static struct trace_event_functions trace_event_type_funcs_##call = { \
|
||||
.trace = trace_raw_output_##call, \
|
||||
};
|
||||
|
||||
#undef DECLARE_EVENT_SYSCALL_CLASS
|
||||
#define DECLARE_EVENT_SYSCALL_CLASS DECLARE_EVENT_CLASS
|
||||
|
||||
#undef DEFINE_EVENT_PRINT
|
||||
#define DEFINE_EVENT_PRINT(template, call, proto, args, print) \
|
||||
static notrace enum print_line_t \
|
||||
@@ -244,6 +263,9 @@ static struct trace_event_fields trace_event_fields_##call[] = { \
|
||||
tstruct \
|
||||
{} };
|
||||
|
||||
#undef DECLARE_EVENT_SYSCALL_CLASS
|
||||
#define DECLARE_EVENT_SYSCALL_CLASS DECLARE_EVENT_CLASS
|
||||
|
||||
#undef DEFINE_EVENT_PRINT
|
||||
#define DEFINE_EVENT_PRINT(template, name, proto, args, print)
|
||||
|
||||
@@ -265,6 +287,9 @@ static inline notrace int trace_event_get_offsets_##call( \
|
||||
return __data_size; \
|
||||
}
|
||||
|
||||
#undef DECLARE_EVENT_SYSCALL_CLASS
|
||||
#define DECLARE_EVENT_SYSCALL_CLASS DECLARE_EVENT_CLASS
|
||||
|
||||
#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
|
||||
|
||||
/*
|
||||
@@ -374,11 +399,11 @@ static inline notrace int trace_event_get_offsets_##call( \
|
||||
|
||||
#include "stages/stage6_event_callback.h"
|
||||
|
||||
#undef DECLARE_EVENT_CLASS
|
||||
#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
|
||||
\
|
||||
|
||||
#undef __DECLARE_EVENT_CLASS
|
||||
#define __DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
|
||||
static notrace void \
|
||||
trace_event_raw_event_##call(void *__data, proto) \
|
||||
do_trace_event_raw_event_##call(void *__data, proto) \
|
||||
{ \
|
||||
struct trace_event_file *trace_file = __data; \
|
||||
struct trace_event_data_offsets_##call __maybe_unused __data_offsets;\
|
||||
@@ -403,6 +428,30 @@ trace_event_raw_event_##call(void *__data, proto) \
|
||||
\
|
||||
trace_event_buffer_commit(&fbuffer); \
|
||||
}
|
||||
|
||||
#undef DECLARE_EVENT_CLASS
|
||||
#define DECLARE_EVENT_CLASS(call, proto, args, tstruct, assign, print) \
|
||||
__DECLARE_EVENT_CLASS(call, PARAMS(proto), PARAMS(args), PARAMS(tstruct), \
|
||||
PARAMS(assign), PARAMS(print)) \
|
||||
static notrace void \
|
||||
trace_event_raw_event_##call(void *__data, proto) \
|
||||
{ \
|
||||
do_trace_event_raw_event_##call(__data, args); \
|
||||
}
|
||||
|
||||
#undef DECLARE_EVENT_SYSCALL_CLASS
|
||||
#define DECLARE_EVENT_SYSCALL_CLASS(call, proto, args, tstruct, assign, print) \
|
||||
__DECLARE_EVENT_CLASS(call, PARAMS(proto), PARAMS(args), PARAMS(tstruct), \
|
||||
PARAMS(assign), PARAMS(print)) \
|
||||
static notrace void \
|
||||
trace_event_raw_event_##call(void *__data, proto) \
|
||||
{ \
|
||||
might_fault(); \
|
||||
preempt_disable_notrace(); \
|
||||
do_trace_event_raw_event_##call(__data, args); \
|
||||
preempt_enable_notrace(); \
|
||||
}
|
||||
|
||||
/*
|
||||
* The ftrace_test_probe is compiled out, it is only here as a build time check
|
||||
* to make sure that if the tracepoint handling changes, the ftrace probe will
|
||||
@@ -418,6 +467,8 @@ static inline void ftrace_test_probe_##call(void) \
|
||||
|
||||
#include TRACE_INCLUDE(TRACE_INCLUDE_FILE)
|
||||
|
||||
#undef __DECLARE_EVENT_CLASS
|
||||
|
||||
#include "stages/stage7_class_define.h"
|
||||
|
||||
#undef DECLARE_EVENT_CLASS
|
||||
@@ -434,6 +485,9 @@ static struct trace_event_class __used __refdata event_class_##call = { \
|
||||
_TRACE_PERF_INIT(call) \
|
||||
};
|
||||
|
||||
#undef DECLARE_EVENT_SYSCALL_CLASS
|
||||
#define DECLARE_EVENT_SYSCALL_CLASS DECLARE_EVENT_CLASS
|
||||
|
||||
#undef DEFINE_EVENT
|
||||
#define DEFINE_EVENT(template, call, proto, args) \
|
||||
\
|
||||
|
||||
@@ -1999,6 +1999,7 @@ config BINDGEN_VERSION_TEXT
|
||||
#
|
||||
config TRACEPOINTS
|
||||
bool
|
||||
select TASKS_TRACE_RCU
|
||||
|
||||
source "kernel/Kconfig.kexec"
|
||||
|
||||
|
||||
@@ -2915,7 +2915,7 @@ trace_function(struct trace_array *tr, unsigned long ip, unsigned long
|
||||
/* Allow 4 levels of nesting: normal, softirq, irq, NMI */
|
||||
#define FTRACE_KSTACK_NESTING 4
|
||||
|
||||
#define FTRACE_KSTACK_ENTRIES (PAGE_SIZE / FTRACE_KSTACK_NESTING)
|
||||
#define FTRACE_KSTACK_ENTRIES (SZ_4K / FTRACE_KSTACK_NESTING)
|
||||
|
||||
struct ftrace_stack {
|
||||
unsigned long calls[FTRACE_KSTACK_ENTRIES];
|
||||
|
||||
@@ -154,5 +154,5 @@ static atomic64_t trace_counter;
|
||||
*/
|
||||
u64 notrace trace_clock_counter(void)
|
||||
{
|
||||
return atomic64_add_return(1, &trace_counter);
|
||||
return atomic64_inc_return(&trace_counter);
|
||||
}
|
||||
@@ -352,10 +352,16 @@ void perf_uprobe_destroy(struct perf_event *p_event)
|
||||
int perf_trace_add(struct perf_event *p_event, int flags)
|
||||
{
|
||||
struct trace_event_call *tp_event = p_event->tp_event;
|
||||
struct hw_perf_event *hwc = &p_event->hw;
|
||||
|
||||
if (!(flags & PERF_EF_START))
|
||||
p_event->hw.state = PERF_HES_STOPPED;
|
||||
|
||||
if (is_sampling_event(p_event)) {
|
||||
hwc->last_period = hwc->sample_period;
|
||||
perf_swevent_set_period(p_event);
|
||||
}
|
||||
|
||||
/*
|
||||
* If TRACE_REG_PERF_ADD returns false; no custom action was performed
|
||||
* and we need to take the default action of enqueueing our event on
|
||||
|
||||
@@ -1616,7 +1616,7 @@ static int parse_pred(const char *str, void *data,
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
strncpy(num_buf, str + s, len);
|
||||
memcpy(num_buf, str + s, len);
|
||||
num_buf[len] = 0;
|
||||
|
||||
ret = kstrtoul(num_buf, 0, &ip);
|
||||
@@ -1694,7 +1694,7 @@ static int parse_pred(const char *str, void *data,
|
||||
if (!pred->regex)
|
||||
goto err_mem;
|
||||
pred->regex->len = len;
|
||||
strncpy(pred->regex->pattern, str + s, len);
|
||||
memcpy(pred->regex->pattern, str + s, len);
|
||||
pred->regex->pattern[len] = 0;
|
||||
|
||||
} else if (!strncmp(str + i, "CPUS", 4)) {
|
||||
@@ -1859,7 +1859,7 @@ static int parse_pred(const char *str, void *data,
|
||||
if (!pred->regex)
|
||||
goto err_mem;
|
||||
pred->regex->len = len;
|
||||
strncpy(pred->regex->pattern, str + s, len);
|
||||
memcpy(pred->regex->pattern, str + s, len);
|
||||
pred->regex->pattern[len] = 0;
|
||||
|
||||
filter_build_regex(pred);
|
||||
@@ -1919,7 +1919,7 @@ static int parse_pred(const char *str, void *data,
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
strncpy(num_buf, str + s, len);
|
||||
memcpy(num_buf, str + s, len);
|
||||
num_buf[len] = 0;
|
||||
|
||||
/* Make sure it is a value */
|
||||
|
||||
@@ -460,7 +460,6 @@ int trace_print_lat_fmt(struct trace_seq *s, struct trace_entry *entry)
|
||||
(entry->flags & TRACE_FLAG_IRQS_OFF && bh_off) ? 'D' :
|
||||
(entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
|
||||
bh_off ? 'b' :
|
||||
(entry->flags & TRACE_FLAG_IRQS_NOSUPPORT) ? 'X' :
|
||||
'.';
|
||||
|
||||
switch (entry->flags & (TRACE_FLAG_NEED_RESCHED |
|
||||
|
||||
@@ -15,20 +15,6 @@
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include <trace/events/preemptirq.h>
|
||||
|
||||
/*
|
||||
* Use regular trace points on architectures that implement noinstr
|
||||
* tooling: these calls will only happen with RCU enabled, which can
|
||||
* use a regular tracepoint.
|
||||
*
|
||||
* On older architectures, use the rcuidle tracing methods (which
|
||||
* aren't NMI-safe - so exclude NMI contexts):
|
||||
*/
|
||||
#ifdef CONFIG_ARCH_WANTS_NO_INSTR
|
||||
#define trace(point) trace_##point
|
||||
#else
|
||||
#define trace(point) if (!in_nmi()) trace_##point##_rcuidle
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||
/* Per-cpu variable to prevent redundant calls when IRQs already off */
|
||||
static DEFINE_PER_CPU(int, tracing_irq_cpu);
|
||||
@@ -42,7 +28,7 @@ static DEFINE_PER_CPU(int, tracing_irq_cpu);
|
||||
void trace_hardirqs_on_prepare(void)
|
||||
{
|
||||
if (this_cpu_read(tracing_irq_cpu)) {
|
||||
trace(irq_enable)(CALLER_ADDR0, CALLER_ADDR1);
|
||||
trace_irq_enable(CALLER_ADDR0, CALLER_ADDR1);
|
||||
tracer_hardirqs_on(CALLER_ADDR0, CALLER_ADDR1);
|
||||
this_cpu_write(tracing_irq_cpu, 0);
|
||||
}
|
||||
@@ -53,7 +39,7 @@ NOKPROBE_SYMBOL(trace_hardirqs_on_prepare);
|
||||
void trace_hardirqs_on(void)
|
||||
{
|
||||
if (this_cpu_read(tracing_irq_cpu)) {
|
||||
trace(irq_enable)(CALLER_ADDR0, CALLER_ADDR1);
|
||||
trace_irq_enable(CALLER_ADDR0, CALLER_ADDR1);
|
||||
tracer_hardirqs_on(CALLER_ADDR0, CALLER_ADDR1);
|
||||
this_cpu_write(tracing_irq_cpu, 0);
|
||||
}
|
||||
@@ -75,7 +61,7 @@ void trace_hardirqs_off_finish(void)
|
||||
if (!this_cpu_read(tracing_irq_cpu)) {
|
||||
this_cpu_write(tracing_irq_cpu, 1);
|
||||
tracer_hardirqs_off(CALLER_ADDR0, CALLER_ADDR1);
|
||||
trace(irq_disable)(CALLER_ADDR0, CALLER_ADDR1);
|
||||
trace_irq_disable(CALLER_ADDR0, CALLER_ADDR1);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -89,7 +75,7 @@ void trace_hardirqs_off(void)
|
||||
if (!this_cpu_read(tracing_irq_cpu)) {
|
||||
this_cpu_write(tracing_irq_cpu, 1);
|
||||
tracer_hardirqs_off(CALLER_ADDR0, CALLER_ADDR1);
|
||||
trace(irq_disable)(CALLER_ADDR0, CALLER_ADDR1);
|
||||
trace_irq_disable(CALLER_ADDR0, CALLER_ADDR1);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(trace_hardirqs_off);
|
||||
@@ -100,13 +86,13 @@ NOKPROBE_SYMBOL(trace_hardirqs_off);
|
||||
|
||||
void trace_preempt_on(unsigned long a0, unsigned long a1)
|
||||
{
|
||||
trace(preempt_enable)(a0, a1);
|
||||
trace_preempt_enable(a0, a1);
|
||||
tracer_preempt_on(a0, a1);
|
||||
}
|
||||
|
||||
void trace_preempt_off(unsigned long a0, unsigned long a1)
|
||||
{
|
||||
trace(preempt_disable)(a0, a1);
|
||||
trace_preempt_disable(a0, a1);
|
||||
tracer_preempt_off(a0, a1);
|
||||
}
|
||||
#endif
|
||||
@@ -299,6 +299,13 @@ static void ftrace_syscall_enter(void *data, struct pt_regs *regs, long id)
|
||||
int syscall_nr;
|
||||
int size;
|
||||
|
||||
/*
|
||||
* Syscall probe called with preemption enabled, but the ring
|
||||
* buffer and per-cpu data require preemption to be disabled.
|
||||
*/
|
||||
might_fault();
|
||||
guard(preempt_notrace)();
|
||||
|
||||
syscall_nr = trace_get_syscall_nr(current, regs);
|
||||
if (syscall_nr < 0 || syscall_nr >= NR_syscalls)
|
||||
return;
|
||||
@@ -338,6 +345,13 @@ static void ftrace_syscall_exit(void *data, struct pt_regs *regs, long ret)
|
||||
struct trace_event_buffer fbuffer;
|
||||
int syscall_nr;
|
||||
|
||||
/*
|
||||
* Syscall probe called with preemption enabled, but the ring
|
||||
* buffer and per-cpu data require preemption to be disabled.
|
||||
*/
|
||||
might_fault();
|
||||
guard(preempt_notrace)();
|
||||
|
||||
syscall_nr = trace_get_syscall_nr(current, regs);
|
||||
if (syscall_nr < 0 || syscall_nr >= NR_syscalls)
|
||||
return;
|
||||
@@ -584,6 +598,13 @@ static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id)
|
||||
int rctx;
|
||||
int size;
|
||||
|
||||
/*
|
||||
* Syscall probe called with preemption enabled, but the ring
|
||||
* buffer and per-cpu data require preemption to be disabled.
|
||||
*/
|
||||
might_fault();
|
||||
guard(preempt_notrace)();
|
||||
|
||||
syscall_nr = trace_get_syscall_nr(current, regs);
|
||||
if (syscall_nr < 0 || syscall_nr >= NR_syscalls)
|
||||
return;
|
||||
@@ -686,6 +707,13 @@ static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret)
|
||||
int rctx;
|
||||
int size;
|
||||
|
||||
/*
|
||||
* Syscall probe called with preemption enabled, but the ring
|
||||
* buffer and per-cpu data require preemption to be disabled.
|
||||
*/
|
||||
might_fault();
|
||||
guard(preempt_notrace)();
|
||||
|
||||
syscall_nr = trace_get_syscall_nr(current, regs);
|
||||
if (syscall_nr < 0 || syscall_nr >= NR_syscalls)
|
||||
return;
|
||||
|
||||
+1
-50
@@ -26,9 +26,6 @@ enum tp_func_state {
|
||||
extern tracepoint_ptr_t __start___tracepoints_ptrs[];
|
||||
extern tracepoint_ptr_t __stop___tracepoints_ptrs[];
|
||||
|
||||
DEFINE_SRCU(tracepoint_srcu);
|
||||
EXPORT_SYMBOL_GPL(tracepoint_srcu);
|
||||
|
||||
enum tp_transition_sync {
|
||||
TP_TRANSITION_SYNC_1_0_1,
|
||||
TP_TRANSITION_SYNC_N_2_1,
|
||||
@@ -38,7 +35,6 @@ enum tp_transition_sync {
|
||||
|
||||
struct tp_transition_snapshot {
|
||||
unsigned long rcu;
|
||||
unsigned long srcu;
|
||||
bool ongoing;
|
||||
};
|
||||
|
||||
@@ -51,7 +47,6 @@ static void tp_rcu_get_state(enum tp_transition_sync sync)
|
||||
|
||||
/* Keep the latest get_state snapshot. */
|
||||
snapshot->rcu = get_state_synchronize_rcu();
|
||||
snapshot->srcu = start_poll_synchronize_srcu(&tracepoint_srcu);
|
||||
snapshot->ongoing = true;
|
||||
}
|
||||
|
||||
@@ -62,8 +57,6 @@ static void tp_rcu_cond_sync(enum tp_transition_sync sync)
|
||||
if (!snapshot->ongoing)
|
||||
return;
|
||||
cond_synchronize_rcu(snapshot->rcu);
|
||||
if (!poll_state_synchronize_srcu(&tracepoint_srcu, snapshot->srcu))
|
||||
synchronize_srcu(&tracepoint_srcu);
|
||||
snapshot->ongoing = false;
|
||||
}
|
||||
|
||||
@@ -86,9 +79,6 @@ static LIST_HEAD(tracepoint_module_list);
|
||||
*/
|
||||
static DEFINE_MUTEX(tracepoints_mutex);
|
||||
|
||||
static struct rcu_head *early_probes;
|
||||
static bool ok_to_free_tracepoints;
|
||||
|
||||
/*
|
||||
* Note about RCU :
|
||||
* It is used to delay the free of multiple probes array until a quiescent
|
||||
@@ -112,56 +102,17 @@ static inline void *allocate_probes(int count)
|
||||
return p == NULL ? NULL : p->probes;
|
||||
}
|
||||
|
||||
static void srcu_free_old_probes(struct rcu_head *head)
|
||||
static void rcu_free_old_probes(struct rcu_head *head)
|
||||
{
|
||||
kfree(container_of(head, struct tp_probes, rcu));
|
||||
}
|
||||
|
||||
static void rcu_free_old_probes(struct rcu_head *head)
|
||||
{
|
||||
call_srcu(&tracepoint_srcu, head, srcu_free_old_probes);
|
||||
}
|
||||
|
||||
static __init int release_early_probes(void)
|
||||
{
|
||||
struct rcu_head *tmp;
|
||||
|
||||
ok_to_free_tracepoints = true;
|
||||
|
||||
while (early_probes) {
|
||||
tmp = early_probes;
|
||||
early_probes = tmp->next;
|
||||
call_rcu(tmp, rcu_free_old_probes);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* SRCU is initialized at core_initcall */
|
||||
postcore_initcall(release_early_probes);
|
||||
|
||||
static inline void release_probes(struct tracepoint_func *old)
|
||||
{
|
||||
if (old) {
|
||||
struct tp_probes *tp_probes = container_of(old,
|
||||
struct tp_probes, probes[0]);
|
||||
|
||||
/*
|
||||
* We can't free probes if SRCU is not initialized yet.
|
||||
* Postpone the freeing till after SRCU is initialized.
|
||||
*/
|
||||
if (unlikely(!ok_to_free_tracepoints)) {
|
||||
tp_probes->rcu.next = early_probes;
|
||||
early_probes = &tp_probes->rcu;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tracepoint probes are protected by both sched RCU and SRCU,
|
||||
* by calling the SRCU callback in the sched RCU callback we
|
||||
* cover both cases. So let us chain the SRCU and sched RCU
|
||||
* callbacks to wait for both grace periods.
|
||||
*/
|
||||
call_rcu(&tp_probes->rcu, rcu_free_old_probes);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,9 +152,7 @@ regex_c=(
|
||||
'/^BPF_CALL_[0-9]([[:space:]]*\([[:alnum:]_]*\).*/\1/'
|
||||
'/^COMPAT_SYSCALL_DEFINE[0-9]([[:space:]]*\([[:alnum:]_]*\).*/compat_sys_\1/'
|
||||
'/^TRACE_EVENT([[:space:]]*\([[:alnum:]_]*\).*/trace_\1/'
|
||||
'/^TRACE_EVENT([[:space:]]*\([[:alnum:]_]*\).*/trace_\1_rcuidle/'
|
||||
'/^DEFINE_EVENT([^,)]*,[[:space:]]*\([[:alnum:]_]*\).*/trace_\1/'
|
||||
'/^DEFINE_EVENT([^,)]*,[[:space:]]*\([[:alnum:]_]*\).*/trace_\1_rcuidle/'
|
||||
'/^DEFINE_INSN_CACHE_OPS([[:space:]]*\([[:alnum:]_]*\).*/get_\1_slot/'
|
||||
'/^DEFINE_INSN_CACHE_OPS([[:space:]]*\([[:alnum:]_]*\).*/free_\1_slot/'
|
||||
'/^PAGEFLAG([[:space:]]*\([[:alnum:]_]*\).*/Page\1/'
|
||||
|
||||
Reference in new issue
Block a user