diff options
Diffstat (limited to 'kernel/trace/trace_eprobe.c')
| -rw-r--r-- | kernel/trace/trace_eprobe.c | 61 | 
1 files changed, 58 insertions, 3 deletions
diff --git a/kernel/trace/trace_eprobe.c b/kernel/trace/trace_eprobe.c index 3044b762cbd7..c4a15aef36af 100644 --- a/kernel/trace/trace_eprobe.c +++ b/kernel/trace/trace_eprobe.c @@ -119,10 +119,58 @@ static bool eprobe_dyn_event_match(const char *system, const char *event,  			int argc, const char **argv, struct dyn_event *ev)  {  	struct trace_eprobe *ep = to_trace_eprobe(ev); +	const char *slash; -	return strcmp(trace_probe_name(&ep->tp), event) == 0 && -	    (!system || strcmp(trace_probe_group_name(&ep->tp), system) == 0) && -	    trace_probe_match_command_args(&ep->tp, argc, argv); +	/* +	 * We match the following: +	 *  event only			- match all eprobes with event name +	 *  system and event only	- match all system/event probes +	 * +	 * The below has the above satisfied with more arguments: +	 * +	 *  attached system/event	- If the arg has the system and event +	 *				  the probe is attached to, match +	 *				  probes with the attachment. +	 * +	 *  If any more args are given, then it requires a full match. +	 */ + +	/* +	 * If system exists, but this probe is not part of that system +	 * do not match. +	 */ +	if (system && strcmp(trace_probe_group_name(&ep->tp), system) != 0) +		return false; + +	/* Must match the event name */ +	if (strcmp(trace_probe_name(&ep->tp), event) != 0) +		return false; + +	/* No arguments match all */ +	if (argc < 1) +		return true; + +	/* First argument is the system/event the probe is attached to */ + +	slash = strchr(argv[0], '/'); +	if (!slash) +		slash = strchr(argv[0], '.'); +	if (!slash) +		return false; + +	if (strncmp(ep->event_system, argv[0], slash - argv[0])) +		return false; +	if (strcmp(ep->event_name, slash + 1)) +		return false; + +	argc--; +	argv++; + +	/* If there are no other args, then match */ +	if (argc < 1) +		return true; + +	return trace_probe_match_command_args(&ep->tp, argc, argv);  }  static struct dyn_event_operations eprobe_dyn_event_ops = { @@ -632,6 +680,13 @@ static int disable_eprobe(struct trace_eprobe *ep,  	trace_event_trigger_enable_disable(file, 0);  	update_cond_flag(file); + +	/* Make sure nothing is using the edata or trigger */ +	tracepoint_synchronize_unregister(); + +	kfree(edata); +	kfree(trigger); +  	return 0;  }  | 
