Add probe registry
authorMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Wed, 22 Dec 2010 17:45:51 +0000 (12:45 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Wed, 22 Dec 2010 17:45:51 +0000 (12:45 -0500)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Makefile
ltt-events.c
ltt-events.h
ltt-probes.c [new file with mode: 0644]

index 19acdbb64d84fbe3335ede4cc5d01c0b50a58e5b..ac00f9c46664b36eea1c27823598ca564a504d33 100644 (file)
--- 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/
 
index b8dbec69a2dfb40cb8d38c73092fbf81389c913c..0e34f6f8b0585bdc3f192467a4e5f75096f33d66 100644 (file)
@@ -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);
index ab90bad3d842ed892847184852de4140115cddf9..b888dd2b493b873a6155c2725bbcf9b496f8ab61 100644 (file)
@@ -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 (file)
index 0000000..9870b9d
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * ltt-probes.c
+ *
+ * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * Holds LTTng probes registry.
+ */
+
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+
+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);
+}
This page took 0.029706 seconds and 4 git commands to generate.