From: Mathieu Desnoyers Date: Wed, 22 Dec 2010 17:45:51 +0000 (-0500) Subject: Add probe registry X-Git-Tag: v2.0-pre1~184 X-Git-Url: http://git.lttng.org/?p=lttng-modules.git;a=commitdiff_plain;h=02119ee59d5c39dfc2d3f7d82b0921314f64a624 Add probe registry Signed-off-by: Mathieu Desnoyers --- diff --git a/Makefile b/Makefile index 19acdbb6..ac00f9c4 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,8 @@ obj-m += ltt-ring-buffer-client-discard.o obj-m += ltt-ring-buffer-client-overwrite.o obj-m += ltt-relay.o -ltt-relay-objs := ltt-events.o ltt-event-header.o ltt-debugfs-abi.o +ltt-relay-objs := ltt-events.o ltt-event-header.o ltt-debugfs-abi.o \ + ltt-probes.o obj-m += probes/ diff --git a/ltt-events.c b/ltt-events.c index b8dbec69..0e34f6f8 100644 --- a/ltt-events.c +++ b/ltt-events.c @@ -284,10 +284,15 @@ static int __init ltt_events_init(void) event_cache = KMEM_CACHE(ltt_event, 0); if (!event_cache) return -ENOMEM; - ret = ltt_debugfs_abi_init(); + ret = ltt_probes_init(); if (ret) goto error; + ret = ltt_debugfs_abi_init(); + if (ret) + goto error_abi; return 0; +error_abi: + ltt_probes_exit(); error: kmem_cache_destroy(event_cache); return ret; @@ -300,6 +305,7 @@ static void __exit ltt_events_exit(void) struct ltt_session *session, *tmpsession; ltt_debugfs_abi_exit(); + ltt_probes_exit(); list_for_each_entry_safe(session, tmpsession, &sessions, list) ltt_session_destroy(session); kmem_cache_destroy(event_cache); diff --git a/ltt-events.h b/ltt-events.h index ab90bad3..b888dd2b 100644 --- a/ltt-events.h +++ b/ltt-events.h @@ -96,4 +96,11 @@ void ltt_transport_unregister(struct ltt_transport *transport); int ltt_debugfs_abi_init(void); void ltt_debugfs_abi_exit(void); +int ltt_probe_register(const char *name, void *cb); +void ltt_probe_unregister(const char *name); +void *ltt_probe_get(const char *name); +void ltt_probe_put(void *cb); +int ltt_probes_init(void); +void ltt_probes_exit(void); + #endif /* _LTT_EVENTS_H */ diff --git a/ltt-probes.c b/ltt-probes.c new file mode 100644 index 00000000..9870b9d8 --- /dev/null +++ b/ltt-probes.c @@ -0,0 +1,111 @@ +/* + * ltt-probes.c + * + * Copyright 2010 (c) - Mathieu Desnoyers + * + * Holds LTTng probes registry. + */ + +#include +#include +#include +#include + +struct ltt_probe { + const char *name; + void *cb; + struct list_head list; +}; + +static LIST_HEAD(probe_list); +static DEFINE_MUTEX(probe_mutex); +static struct kmem_cache *probe_cache; + +static void *find_probe(const char *name) +{ + struct ltt_probe *probe; + + list_for_each_entry(probe, &probe_list, list) { + if (!strcmp(probe->name, name)) + return probe->cb; + } + return NULL; +} + +int ltt_probe_register(const char *name, void *cb) +{ + struct ltt_probe *probe; + int ret = 0; + + if (!cb) + return -EPERM; + + mutex_lock(&probe_mutex); + if (find_probe(name)) { + ret = -EEXIST; + goto end; + } + probe = kmem_cache_zalloc(probe_cache, GFP_KERNEL); + if (!probe) { + ret = -ENOMEM; + goto end; + } + probe->name = name; + probe->cb = cb; + list_add(&probe->list, &probe_list); +end: + mutex_unlock(&probe_mutex); + return ret; +} +EXPORT_SYMBOL_GPL(ltt_probe_register); + +void ltt_probe_unregister(const char *name) +{ + struct ltt_probe *probe; + + mutex_lock(&probe_mutex); + probe = find_probe(name); + WARN_ON_ONCE(!probe); + list_del(&probe->list); + mutex_unlock(&probe_mutex); + kmem_cache_free(probe_cache, probe); +} +EXPORT_SYMBOL_GPL(ltt_probe_unregister); + +void *ltt_probe_get(const char *name) +{ + struct ltt_probe *probe; + void *cb = NULL; + int ret; + + mutex_lock(&probe_mutex); + probe = find_probe(name); + if (!probe) + goto end; + cb = probe->cb; + ret = try_module_get(__module_text_address((unsigned long) cb)); + WARN_ON_ONCE(!ret); +end: + mutex_unlock(&probe_mutex); + return cb; +} +EXPORT_SYMBOL_GPL(ltt_probe_get); + +void ltt_probe_put(void *cb) +{ + module_put(__module_text_address((unsigned long) cb)); +} +EXPORT_SYMBOL_GPL(ltt_probe_put); + +int __init ltt_probes_init(void) +{ + probe_cache = KMEM_CACHE(ltt_probe, 0); + if (!probe_cache) + return -ENOMEM; + return 0; +} + +void __exit ltt_probes_exit(void) +{ + kmem_cache_destroy(probe_cache); +}