aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNamhyung Kim <namhyung@kernel.org>2014-01-15 21:31:07 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2014-01-16 14:26:24 -0500
commitad13701d4905e820f32ce3c2590e19ca65765d63 (patch)
treeadfe7047e71aabd5452eae04c663ab56e3eb2042
parent3e7e09dbd1080de5dcf10092830e39bc2e2932ec (diff)
tools lib traceevent: Add pevent_unregister_event_handler()
When a plugin is unloaded it needs to unregister its handler from pevent. So add an unregister function to do it. Signed-off-by: Namhyung Kim <namhyung@kernel.org> Reviewed-by: Jiri Olsa <jolsa@redhat.com> Acked-by: Steven Rostedt <rostedt@goodmis.org> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung.kim@lge.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Steven Rostedt <rostedt@goodmis.org> Link: http://lkml.kernel.org/r/1389839478-5887-2-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/lib/traceevent/event-parse.c113
-rw-r--r--tools/lib/traceevent/event-parse.h3
2 files changed, 102 insertions, 14 deletions
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index 2ce565a73dd5..d1973cb8388b 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -5560,6 +5560,29 @@ int pevent_register_print_function(struct pevent *pevent,
5560 return ret; 5560 return ret;
5561} 5561}
5562 5562
5563static struct event_format *pevent_search_event(struct pevent *pevent, int id,
5564 const char *sys_name,
5565 const char *event_name)
5566{
5567 struct event_format *event;
5568
5569 if (id >= 0) {
5570 /* search by id */
5571 event = pevent_find_event(pevent, id);
5572 if (!event)
5573 return NULL;
5574 if (event_name && (strcmp(event_name, event->name) != 0))
5575 return NULL;
5576 if (sys_name && (strcmp(sys_name, event->system) != 0))
5577 return NULL;
5578 } else {
5579 event = pevent_find_event_by_name(pevent, sys_name, event_name);
5580 if (!event)
5581 return NULL;
5582 }
5583 return event;
5584}
5585
5563/** 5586/**
5564 * pevent_register_event_handler - register a way to parse an event 5587 * pevent_register_event_handler - register a way to parse an event
5565 * @pevent: the handle to the pevent 5588 * @pevent: the handle to the pevent
@@ -5584,20 +5607,9 @@ int pevent_register_event_handler(struct pevent *pevent, int id,
5584 struct event_format *event; 5607 struct event_format *event;
5585 struct event_handler *handle; 5608 struct event_handler *handle;
5586 5609
5587 if (id >= 0) { 5610 event = pevent_search_event(pevent, id, sys_name, event_name);
5588 /* search by id */ 5611 if (event == NULL)
5589 event = pevent_find_event(pevent, id); 5612 goto not_found;
5590 if (!event)
5591 goto not_found;
5592 if (event_name && (strcmp(event_name, event->name) != 0))
5593 goto not_found;
5594 if (sys_name && (strcmp(sys_name, event->system) != 0))
5595 goto not_found;
5596 } else {
5597 event = pevent_find_event_by_name(pevent, sys_name, event_name);
5598 if (!event)
5599 goto not_found;
5600 }
5601 5613
5602 pr_stat("overriding event (%d) %s:%s with new print handler", 5614 pr_stat("overriding event (%d) %s:%s with new print handler",
5603 event->id, event->system, event->name); 5615 event->id, event->system, event->name);
@@ -5637,6 +5649,79 @@ int pevent_register_event_handler(struct pevent *pevent, int id,
5637 return -1; 5649 return -1;
5638} 5650}
5639 5651
5652static int handle_matches(struct event_handler *handler, int id,
5653 const char *sys_name, const char *event_name,
5654 pevent_event_handler_func func, void *context)
5655{
5656 if (id >= 0 && id != handler->id)
5657 return 0;
5658
5659 if (event_name && (strcmp(event_name, handler->event_name) != 0))
5660 return 0;
5661
5662 if (sys_name && (strcmp(sys_name, handler->sys_name) != 0))
5663 return 0;
5664
5665 if (func != handler->func || context != handler->context)
5666 return 0;
5667
5668 return 1;
5669}
5670
5671/**
5672 * pevent_unregister_event_handler - unregister an existing event handler
5673 * @pevent: the handle to the pevent
5674 * @id: the id of the event to unregister
5675 * @sys_name: the system name the handler belongs to
5676 * @event_name: the name of the event handler
5677 * @func: the function to call to parse the event information
5678 * @context: the data to be passed to @func
5679 *
5680 * This function removes existing event handler (parser).
5681 *
5682 * If @id is >= 0, then it is used to find the event.
5683 * else @sys_name and @event_name are used.
5684 *
5685 * Returns 0 if handler was removed successfully, -1 if event was not found.
5686 */
5687int pevent_unregister_event_handler(struct pevent *pevent, int id,
5688 const char *sys_name, const char *event_name,
5689 pevent_event_handler_func func, void *context)
5690{
5691 struct event_format *event;
5692 struct event_handler *handle;
5693 struct event_handler **next;
5694
5695 event = pevent_search_event(pevent, id, sys_name, event_name);
5696 if (event == NULL)
5697 goto not_found;
5698
5699 if (event->handler == func && event->context == context) {
5700 pr_stat("removing override handler for event (%d) %s:%s. Going back to default handler.",
5701 event->id, event->system, event->name);
5702
5703 event->handler = NULL;
5704 event->context = NULL;
5705 return 0;
5706 }
5707
5708not_found:
5709 for (next = &pevent->handlers; *next; next = &(*next)->next) {
5710 handle = *next;
5711 if (handle_matches(handle, id, sys_name, event_name,
5712 func, context))
5713 break;
5714 }
5715
5716 if (!(*next))
5717 return -1;
5718
5719 *next = handle->next;
5720 free_handler(handle);
5721
5722 return 0;
5723}
5724
5640/** 5725/**
5641 * pevent_alloc - create a pevent handle 5726 * pevent_alloc - create a pevent handle
5642 */ 5727 */
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index a3beca56cb35..c48acfbc6230 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -624,6 +624,9 @@ int pevent_print_func_field(struct trace_seq *s, const char *fmt,
624int pevent_register_event_handler(struct pevent *pevent, int id, 624int pevent_register_event_handler(struct pevent *pevent, int id,
625 const char *sys_name, const char *event_name, 625 const char *sys_name, const char *event_name,
626 pevent_event_handler_func func, void *context); 626 pevent_event_handler_func func, void *context);
627int pevent_unregister_event_handler(struct pevent *pevent, int id,
628 const char *sys_name, const char *event_name,
629 pevent_event_handler_func func, void *context);
627int pevent_register_print_function(struct pevent *pevent, 630int pevent_register_print_function(struct pevent *pevent,
628 pevent_func_handler func, 631 pevent_func_handler func,
629 enum pevent_func_arg_type ret_type, 632 enum pevent_func_arg_type ret_type,