tracing: Have dynamic events have a ref counter
As dynamic events are not created by modules, if something is attached to one, calling "try_module_get()" on its "mod" field, is not going to keep the dynamic event from going away. Since dynamic events do not need the "mod" pointer of the event structure, make a union out of it in order to save memory (there's one structure for each of the thousand+ events in the kernel), and have any event with the DYNAMIC flag set to use a ref counter instead. Link: https://lore.kernel.org/linux-trace-devel/20210813004448.51c7de69ce432d338f4d226b@kernel.org/ Link: https://lkml.kernel.org/r/20210817035027.174869074@goodmis.org Suggested-by: Masami Hiramatsu <mhiramat@kernel.org> Acked-by: Masami Hiramatsu <mhiramat@kernel.org> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
This commit is contained in:
@@ -350,7 +350,14 @@ struct trace_event_call {
|
||||
struct trace_event event;
|
||||
char *print_fmt;
|
||||
struct event_filter *filter;
|
||||
void *mod;
|
||||
/*
|
||||
* Static events can disappear with modules,
|
||||
* where as dynamic ones need their own ref count.
|
||||
*/
|
||||
union {
|
||||
void *module;
|
||||
atomic_t refcnt;
|
||||
};
|
||||
void *data;
|
||||
|
||||
/* See the TRACE_EVENT_FL_* flags above */
|
||||
@@ -366,6 +373,42 @@ struct trace_event_call {
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_EVENTS
|
||||
bool trace_event_dyn_try_get_ref(struct trace_event_call *call);
|
||||
void trace_event_dyn_put_ref(struct trace_event_call *call);
|
||||
bool trace_event_dyn_busy(struct trace_event_call *call);
|
||||
#else
|
||||
static inline bool trace_event_dyn_try_get_ref(struct trace_event_call *call)
|
||||
{
|
||||
/* Without DYNAMIC_EVENTS configured, nothing should be calling this */
|
||||
return false;
|
||||
}
|
||||
static inline void trace_event_dyn_put_ref(struct trace_event_call *call)
|
||||
{
|
||||
}
|
||||
static inline bool trace_event_dyn_busy(struct trace_event_call *call)
|
||||
{
|
||||
/* Nothing should call this without DYNAIMIC_EVENTS configured. */
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline bool trace_event_try_get_ref(struct trace_event_call *call)
|
||||
{
|
||||
if (call->flags & TRACE_EVENT_FL_DYNAMIC)
|
||||
return trace_event_dyn_try_get_ref(call);
|
||||
else
|
||||
return try_module_get(call->module);
|
||||
}
|
||||
|
||||
static inline void trace_event_put_ref(struct trace_event_call *call)
|
||||
{
|
||||
if (call->flags & TRACE_EVENT_FL_DYNAMIC)
|
||||
trace_event_dyn_put_ref(call);
|
||||
else
|
||||
module_put(call->module);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PERF_EVENTS
|
||||
static inline bool bpf_prog_array_valid(struct trace_event_call *call)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user