Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 45e6af06 authored by Ingo Molnar's avatar Ingo Molnar
Browse files

Merge tag 'perf-core-for-mingo' of...

Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux

 into perf/core

Pull perf improvements and fixes from Arnaldo Carvalho de Melo:

Infrastructure changes:

 * Improve callchain processing by removing unnecessary work. (Frederic Weisbecker)

 * Fix comm override error handling (Frederic Weisbecker)

 * Improve 'perf probe' exit path, release resources (Masami Hiramatsu)

 * Improve libtraceevent plugins exit path, allowing the registering of
   an unregister handler to be called at exit time (Namhyung Kim)

 * Add an alias to the build test makefile (make -C tools/perf build-test)
   (Namhyung Kim)

Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents 3e7e09db 2a29190c
Loading
Loading
Loading
Loading
+122 −14
Original line number Diff line number Diff line
@@ -5560,6 +5560,52 @@ int pevent_register_print_function(struct pevent *pevent,
	return ret;
}

/**
 * pevent_unregister_print_function - unregister a helper function
 * @pevent: the handle to the pevent
 * @func: the function to process the helper function
 * @name: the name of the helper function
 *
 * This function removes existing print handler for function @name.
 *
 * Returns 0 if the handler was removed successully, -1 otherwise.
 */
int pevent_unregister_print_function(struct pevent *pevent,
				     pevent_func_handler func, char *name)
{
	struct pevent_function_handler *func_handle;

	func_handle = find_func_handler(pevent, name);
	if (func_handle && func_handle->func == func) {
		remove_func_handler(pevent, name);
		return 0;
	}
	return -1;
}

static struct event_format *pevent_search_event(struct pevent *pevent, int id,
						const char *sys_name,
						const char *event_name)
{
	struct event_format *event;

	if (id >= 0) {
		/* search by id */
		event = pevent_find_event(pevent, id);
		if (!event)
			return NULL;
		if (event_name && (strcmp(event_name, event->name) != 0))
			return NULL;
		if (sys_name && (strcmp(sys_name, event->system) != 0))
			return NULL;
	} else {
		event = pevent_find_event_by_name(pevent, sys_name, event_name);
		if (!event)
			return NULL;
	}
	return event;
}

/**
 * pevent_register_event_handler - register a way to parse an event
 * @pevent: the handle to the pevent
@@ -5584,20 +5630,9 @@ int pevent_register_event_handler(struct pevent *pevent, int id,
	struct event_format *event;
	struct event_handler *handle;

	if (id >= 0) {
		/* search by id */
		event = pevent_find_event(pevent, id);
		if (!event)
			goto not_found;
		if (event_name && (strcmp(event_name, event->name) != 0))
			goto not_found;
		if (sys_name && (strcmp(sys_name, event->system) != 0))
			goto not_found;
	} else {
		event = pevent_find_event_by_name(pevent, sys_name, event_name);
		if (!event)
	event = pevent_search_event(pevent, id, sys_name, event_name);
	if (event == NULL)
		goto not_found;
	}

	pr_stat("overriding event (%d) %s:%s with new print handler",
		event->id, event->system, event->name);
@@ -5637,6 +5672,79 @@ int pevent_register_event_handler(struct pevent *pevent, int id,
	return -1;
}

static int handle_matches(struct event_handler *handler, int id,
			  const char *sys_name, const char *event_name,
			  pevent_event_handler_func func, void *context)
{
	if (id >= 0 && id != handler->id)
		return 0;

	if (event_name && (strcmp(event_name, handler->event_name) != 0))
		return 0;

	if (sys_name && (strcmp(sys_name, handler->sys_name) != 0))
		return 0;

	if (func != handler->func || context != handler->context)
		return 0;

	return 1;
}

/**
 * pevent_unregister_event_handler - unregister an existing event handler
 * @pevent: the handle to the pevent
 * @id: the id of the event to unregister
 * @sys_name: the system name the handler belongs to
 * @event_name: the name of the event handler
 * @func: the function to call to parse the event information
 * @context: the data to be passed to @func
 *
 * This function removes existing event handler (parser).
 *
 * If @id is >= 0, then it is used to find the event.
 * else @sys_name and @event_name are used.
 *
 * Returns 0 if handler was removed successfully, -1 if event was not found.
 */
int pevent_unregister_event_handler(struct pevent *pevent, int id,
				    const char *sys_name, const char *event_name,
				    pevent_event_handler_func func, void *context)
{
	struct event_format *event;
	struct event_handler *handle;
	struct event_handler **next;

	event = pevent_search_event(pevent, id, sys_name, event_name);
	if (event == NULL)
		goto not_found;

	if (event->handler == func && event->context == context) {
		pr_stat("removing override handler for event (%d) %s:%s. Going back to default handler.",
			event->id, event->system, event->name);

		event->handler = NULL;
		event->context = NULL;
		return 0;
	}

not_found:
	for (next = &pevent->handlers; *next; next = &(*next)->next) {
		handle = *next;
		if (handle_matches(handle, id, sys_name, event_name,
				   func, context))
			break;
	}

	if (!(*next))
		return -1;

	*next = handle->next;
	free_handler(handle);

	return 0;
}

/**
 * pevent_alloc - create a pevent handle
 */
+5 −0
Original line number Diff line number Diff line
@@ -624,10 +624,15 @@ int pevent_print_func_field(struct trace_seq *s, const char *fmt,
int pevent_register_event_handler(struct pevent *pevent, int id,
				  const char *sys_name, const char *event_name,
				  pevent_event_handler_func func, void *context);
int pevent_unregister_event_handler(struct pevent *pevent, int id,
				    const char *sys_name, const char *event_name,
				    pevent_event_handler_func func, void *context);
int pevent_register_print_function(struct pevent *pevent,
				   pevent_func_handler func,
				   enum pevent_func_arg_type ret_type,
				   char *name, ...);
int pevent_unregister_print_function(struct pevent *pevent,
				     pevent_func_handler func, char *name);

struct format_field *pevent_find_common_field(struct event_format *event, const char *name);
struct format_field *pevent_find_field(struct event_format *event, const char *name);
+6 −0
Original line number Diff line number Diff line
@@ -22,3 +22,9 @@ int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
				       PEVENT_FUNC_ARG_VOID);
	return 0;
}

void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent)
{
	pevent_unregister_print_function(pevent, process___le16_to_cpup,
					 "__le16_to_cpup");
}
+3 −0
Original line number Diff line number Diff line
@@ -148,6 +148,9 @@ void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent)
{
	int i, x;

	pevent_unregister_event_handler(pevent, -1, "ftrace", "function",
					function_handler, NULL);

	for (i = 0; i <= cpus; i++) {
		for (x = 0; x < fstack[i].size && fstack[i].stack[x]; x++)
			free(fstack[i].stack[x]);
+10 −0
Original line number Diff line number Diff line
@@ -76,3 +76,13 @@ int PEVENT_PLUGIN_LOADER(struct pevent *pevent)
				      timer_start_handler, NULL);
	return 0;
}

void PEVENT_PLUGIN_UNLOADER(struct pevent *pevent)
{
	pevent_unregister_event_handler(pevent, -1,
					"timer", "hrtimer_expire_entry",
					timer_expire_handler, NULL);

	pevent_unregister_event_handler(pevent, -1, "timer", "hrtimer_start",
					timer_start_handler, NULL);
}
Loading