forked from Minki/linux
tracing: Define event fields early stage
Define event fields at early stage so that boot-time tracing can access the event fields (like per-event filter setting). Link: https://lkml.kernel.org/r/159974152862.478751.2023768466808361350.stgit@devnote2 Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
This commit is contained in:
parent
36dadef23f
commit
ac343da7bc
@ -2123,12 +2123,48 @@ event_subsystem_dir(struct trace_array *tr, const char *name,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
event_define_fields(struct trace_event_call *call)
|
||||
{
|
||||
struct list_head *head;
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
* Other events may have the same class. Only update
|
||||
* the fields if they are not already defined.
|
||||
*/
|
||||
head = trace_get_fields(call);
|
||||
if (list_empty(head)) {
|
||||
struct trace_event_fields *field = call->class->fields_array;
|
||||
unsigned int offset = sizeof(struct trace_entry);
|
||||
|
||||
for (; field->type; field++) {
|
||||
if (field->type == TRACE_FUNCTION_TYPE) {
|
||||
field->define_fields(call);
|
||||
break;
|
||||
}
|
||||
|
||||
offset = ALIGN(offset, field->align);
|
||||
ret = trace_define_field(call, field->type, field->name,
|
||||
offset, field->size,
|
||||
field->is_signed, field->filter_type);
|
||||
if (WARN_ON_ONCE(ret)) {
|
||||
pr_err("error code is %d\n", ret);
|
||||
break;
|
||||
}
|
||||
|
||||
offset += field->size;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
event_create_dir(struct dentry *parent, struct trace_event_file *file)
|
||||
{
|
||||
struct trace_event_call *call = file->event_call;
|
||||
struct trace_array *tr = file->tr;
|
||||
struct list_head *head;
|
||||
struct dentry *d_events;
|
||||
const char *name;
|
||||
int ret;
|
||||
@ -2162,35 +2198,10 @@ event_create_dir(struct dentry *parent, struct trace_event_file *file)
|
||||
&ftrace_event_id_fops);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Other events may have the same class. Only update
|
||||
* the fields if they are not already defined.
|
||||
*/
|
||||
head = trace_get_fields(call);
|
||||
if (list_empty(head)) {
|
||||
struct trace_event_fields *field = call->class->fields_array;
|
||||
unsigned int offset = sizeof(struct trace_entry);
|
||||
|
||||
for (; field->type; field++) {
|
||||
if (field->type == TRACE_FUNCTION_TYPE) {
|
||||
ret = field->define_fields(call);
|
||||
break;
|
||||
}
|
||||
|
||||
offset = ALIGN(offset, field->align);
|
||||
ret = trace_define_field(call, field->type, field->name,
|
||||
offset, field->size,
|
||||
field->is_signed, field->filter_type);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
offset += field->size;
|
||||
}
|
||||
if (ret < 0) {
|
||||
pr_warn("Could not initialize trace point events/%s\n",
|
||||
name);
|
||||
return -1;
|
||||
}
|
||||
ret = event_define_fields(call);
|
||||
if (ret < 0) {
|
||||
pr_warn("Could not initialize trace point events/%s\n", name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2493,7 +2504,7 @@ __trace_early_add_new_event(struct trace_event_call *call,
|
||||
if (!file)
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
return event_define_fields(call);
|
||||
}
|
||||
|
||||
struct ftrace_module_file_ops;
|
||||
@ -3431,6 +3442,18 @@ static __init int event_trace_enable_again(void)
|
||||
|
||||
early_initcall(event_trace_enable_again);
|
||||
|
||||
/* Init fields which doesn't related to the tracefs */
|
||||
static __init int event_trace_init_fields(void)
|
||||
{
|
||||
if (trace_define_generic_fields())
|
||||
pr_warn("tracing: Failed to allocated generic fields");
|
||||
|
||||
if (trace_define_common_fields())
|
||||
pr_warn("tracing: Failed to allocate common fields");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__init int event_trace_init(void)
|
||||
{
|
||||
struct trace_array *tr;
|
||||
@ -3446,12 +3469,6 @@ __init int event_trace_init(void)
|
||||
if (!entry)
|
||||
pr_warn("Could not create tracefs 'available_events' entry\n");
|
||||
|
||||
if (trace_define_generic_fields())
|
||||
pr_warn("tracing: Failed to allocated generic fields");
|
||||
|
||||
if (trace_define_common_fields())
|
||||
pr_warn("tracing: Failed to allocate common fields");
|
||||
|
||||
ret = early_event_add_tracer(NULL, tr);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -3469,6 +3486,7 @@ void __init trace_event_init(void)
|
||||
event_trace_memsetup();
|
||||
init_ftrace_syscalls();
|
||||
event_trace_enable();
|
||||
event_trace_init_fields();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_EVENT_TRACE_STARTUP_TEST
|
||||
|
Loading…
Reference in New Issue
Block a user