Add probe registry
[lttng-modules.git] / ltt-probes.c
1 /*
2 * ltt-probes.c
3 *
4 * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 *
6 * Holds LTTng probes registry.
7 */
8
9 #include <linux/module.h>
10 #include <linux/list.h>
11 #include <linux/mutex.h>
12 #include <linux/slab.h>
13
14 struct ltt_probe {
15 const char *name;
16 void *cb;
17 struct list_head list;
18 };
19
20 static LIST_HEAD(probe_list);
21 static DEFINE_MUTEX(probe_mutex);
22 static struct kmem_cache *probe_cache;
23
24 static void *find_probe(const char *name)
25 {
26 struct ltt_probe *probe;
27
28 list_for_each_entry(probe, &probe_list, list) {
29 if (!strcmp(probe->name, name))
30 return probe->cb;
31 }
32 return NULL;
33 }
34
35 int ltt_probe_register(const char *name, void *cb)
36 {
37 struct ltt_probe *probe;
38 int ret = 0;
39
40 if (!cb)
41 return -EPERM;
42
43 mutex_lock(&probe_mutex);
44 if (find_probe(name)) {
45 ret = -EEXIST;
46 goto end;
47 }
48 probe = kmem_cache_zalloc(probe_cache, GFP_KERNEL);
49 if (!probe) {
50 ret = -ENOMEM;
51 goto end;
52 }
53 probe->name = name;
54 probe->cb = cb;
55 list_add(&probe->list, &probe_list);
56 end:
57 mutex_unlock(&probe_mutex);
58 return ret;
59 }
60 EXPORT_SYMBOL_GPL(ltt_probe_register);
61
62 void ltt_probe_unregister(const char *name)
63 {
64 struct ltt_probe *probe;
65
66 mutex_lock(&probe_mutex);
67 probe = find_probe(name);
68 WARN_ON_ONCE(!probe);
69 list_del(&probe->list);
70 mutex_unlock(&probe_mutex);
71 kmem_cache_free(probe_cache, probe);
72 }
73 EXPORT_SYMBOL_GPL(ltt_probe_unregister);
74
75 void *ltt_probe_get(const char *name)
76 {
77 struct ltt_probe *probe;
78 void *cb = NULL;
79 int ret;
80
81 mutex_lock(&probe_mutex);
82 probe = find_probe(name);
83 if (!probe)
84 goto end;
85 cb = probe->cb;
86 ret = try_module_get(__module_text_address((unsigned long) cb));
87 WARN_ON_ONCE(!ret);
88 end:
89 mutex_unlock(&probe_mutex);
90 return cb;
91 }
92 EXPORT_SYMBOL_GPL(ltt_probe_get);
93
94 void ltt_probe_put(void *cb)
95 {
96 module_put(__module_text_address((unsigned long) cb));
97 }
98 EXPORT_SYMBOL_GPL(ltt_probe_put);
99
100 int __init ltt_probes_init(void)
101 {
102 probe_cache = KMEM_CACHE(ltt_probe, 0);
103 if (!probe_cache)
104 return -ENOMEM;
105 return 0;
106 }
107
108 void __exit ltt_probes_exit(void)
109 {
110 kmem_cache_destroy(probe_cache);
111 }
This page took 0.031211 seconds and 4 git commands to generate.