diff options
author | Namhyung Kim <namhyung@kernel.org> | 2014-01-15 21:31:07 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-01-16 14:26:24 -0500 |
commit | ad13701d4905e820f32ce3c2590e19ca65765d63 (patch) | |
tree | adfe7047e71aabd5452eae04c663ab56e3eb2042 | |
parent | 3e7e09dbd1080de5dcf10092830e39bc2e2932ec (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.c | 113 | ||||
-rw-r--r-- | tools/lib/traceevent/event-parse.h | 3 |
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 | ||
5563 | static 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 | ||
5652 | static 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 | */ | ||
5687 | int 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 | |||
5708 | not_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, | |||
624 | int pevent_register_event_handler(struct pevent *pevent, int id, | 624 | int 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); |
627 | int 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); | ||
627 | int pevent_register_print_function(struct pevent *pevent, | 630 | int 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, |