Add probe registry
[lttng-modules.git] / ltt-probes.c
CommitLineData
02119ee5
MD
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
14struct ltt_probe {
15 const char *name;
16 void *cb;
17 struct list_head list;
18};
19
20static LIST_HEAD(probe_list);
21static DEFINE_MUTEX(probe_mutex);
22static struct kmem_cache *probe_cache;
23
24static 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
35int 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);
56end:
57 mutex_unlock(&probe_mutex);
58 return ret;
59}
60EXPORT_SYMBOL_GPL(ltt_probe_register);
61
62void 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}
73EXPORT_SYMBOL_GPL(ltt_probe_unregister);
74
75void *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);
88end:
89 mutex_unlock(&probe_mutex);
90 return cb;
91}
92EXPORT_SYMBOL_GPL(ltt_probe_get);
93
94void ltt_probe_put(void *cb)
95{
96 module_put(__module_text_address((unsigned long) cb));
97}
98EXPORT_SYMBOL_GPL(ltt_probe_put);
99
100int __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
108void __exit ltt_probes_exit(void)
109{
110 kmem_cache_destroy(probe_cache);
111}
This page took 0.026262 seconds and 4 git commands to generate.