mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	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
					
				
					 1 changed files with 55 additions and 37 deletions
				
			
		| 
						 | 
					@ -2123,12 +2123,48 @@ event_subsystem_dir(struct trace_array *tr, const char *name,
 | 
				
			||||||
	return NULL;
 | 
						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
 | 
					static int
 | 
				
			||||||
event_create_dir(struct dentry *parent, struct trace_event_file *file)
 | 
					event_create_dir(struct dentry *parent, struct trace_event_file *file)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct trace_event_call *call = file->event_call;
 | 
						struct trace_event_call *call = file->event_call;
 | 
				
			||||||
	struct trace_array *tr = file->tr;
 | 
						struct trace_array *tr = file->tr;
 | 
				
			||||||
	struct list_head *head;
 | 
					 | 
				
			||||||
	struct dentry *d_events;
 | 
						struct dentry *d_events;
 | 
				
			||||||
	const char *name;
 | 
						const char *name;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
| 
						 | 
					@ -2162,35 +2198,10 @@ event_create_dir(struct dentry *parent, struct trace_event_file *file)
 | 
				
			||||||
				  &ftrace_event_id_fops);
 | 
									  &ftrace_event_id_fops);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						ret = event_define_fields(call);
 | 
				
			||||||
	 * 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) {
 | 
						if (ret < 0) {
 | 
				
			||||||
			pr_warn("Could not initialize trace point events/%s\n",
 | 
							pr_warn("Could not initialize trace point events/%s\n", name);
 | 
				
			||||||
				name);
 | 
							return ret;
 | 
				
			||||||
			return -1;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					@ -2493,7 +2504,7 @@ __trace_early_add_new_event(struct trace_event_call *call,
 | 
				
			||||||
	if (!file)
 | 
						if (!file)
 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return event_define_fields(call);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct ftrace_module_file_ops;
 | 
					struct ftrace_module_file_ops;
 | 
				
			||||||
| 
						 | 
					@ -3431,6 +3442,18 @@ static __init int event_trace_enable_again(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
early_initcall(event_trace_enable_again);
 | 
					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)
 | 
					__init int event_trace_init(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct trace_array *tr;
 | 
						struct trace_array *tr;
 | 
				
			||||||
| 
						 | 
					@ -3446,12 +3469,6 @@ __init int event_trace_init(void)
 | 
				
			||||||
	if (!entry)
 | 
						if (!entry)
 | 
				
			||||||
		pr_warn("Could not create tracefs 'available_events' entry\n");
 | 
							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);
 | 
						ret = early_event_add_tracer(NULL, tr);
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
| 
						 | 
					@ -3469,6 +3486,7 @@ void __init trace_event_init(void)
 | 
				
			||||||
	event_trace_memsetup();
 | 
						event_trace_memsetup();
 | 
				
			||||||
	init_ftrace_syscalls();
 | 
						init_ftrace_syscalls();
 | 
				
			||||||
	event_trace_enable();
 | 
						event_trace_enable();
 | 
				
			||||||
 | 
						event_trace_init_fields();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_EVENT_TRACE_STARTUP_TEST
 | 
					#ifdef CONFIG_EVENT_TRACE_STARTUP_TEST
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue