4 * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
6 * Holds LTTng probes registry.
8 * Dual LGPL v2.1/GPL v2 license.
11 #include <linux/module.h>
12 #include <linux/list.h>
13 #include <linux/mutex.h>
14 #include <linux/seq_file.h>
16 #include "ltt-events.h"
18 static LIST_HEAD(probe_list
);
19 static DEFINE_MUTEX(probe_mutex
);
22 const struct lttng_event_desc
*find_event(const char *name
)
24 struct lttng_probe_desc
*probe_desc
;
27 list_for_each_entry(probe_desc
, &probe_list
, head
) {
28 for (i
= 0; i
< probe_desc
->nr_events
; i
++) {
29 if (!strcmp(probe_desc
->event_desc
[i
].name
, name
))
30 return &probe_desc
->event_desc
[i
];
36 int ltt_probe_register(struct lttng_probe_desc
*desc
)
41 mutex_lock(&probe_mutex
);
43 * TODO: This is O(N^2). Turn into a hash table when probe registration
44 * overhead becomes an issue.
46 for (i
= 0; i
< desc
->nr_events
; i
++) {
47 if (find_event(desc
->event_desc
[i
].name
)) {
52 list_add(&desc
->head
, &probe_list
);
54 mutex_unlock(&probe_mutex
);
57 EXPORT_SYMBOL_GPL(ltt_probe_register
);
59 void ltt_probe_unregister(struct lttng_probe_desc
*desc
)
61 mutex_lock(&probe_mutex
);
62 list_del(&desc
->head
);
63 mutex_unlock(&probe_mutex
);
65 EXPORT_SYMBOL_GPL(ltt_probe_unregister
);
67 const struct lttng_event_desc
*ltt_event_get(const char *name
)
69 const struct lttng_event_desc
*event
;
72 mutex_lock(&probe_mutex
);
73 event
= find_event(name
);
74 mutex_unlock(&probe_mutex
);
77 ret
= try_module_get(event
->owner
);
81 EXPORT_SYMBOL_GPL(ltt_event_get
);
83 void ltt_event_put(const struct lttng_event_desc
*event
)
85 module_put(event
->owner
);
87 EXPORT_SYMBOL_GPL(ltt_event_put
);
90 void *tp_list_start(struct seq_file
*m
, loff_t
*pos
)
92 struct lttng_probe_desc
*probe_desc
;
95 mutex_lock(&probe_mutex
);
96 list_for_each_entry(probe_desc
, &probe_list
, head
) {
97 for (i
= 0; i
< probe_desc
->nr_events
; i
++) {
99 return (void *) &probe_desc
->event_desc
[i
];
107 void *tp_list_next(struct seq_file
*m
, void *p
, loff_t
*ppos
)
109 struct lttng_probe_desc
*probe_desc
;
113 list_for_each_entry(probe_desc
, &probe_list
, head
) {
114 for (i
= 0; i
< probe_desc
->nr_events
; i
++) {
116 return (void *) &probe_desc
->event_desc
[i
];
124 void tp_list_stop(struct seq_file
*m
, void *p
)
126 mutex_unlock(&probe_mutex
);
130 int tp_list_show(struct seq_file
*m
, void *p
)
132 const struct lttng_event_desc
*probe_desc
= p
;
135 * Don't export lttng internal events (metadata).
137 if (!strncmp(probe_desc
->name
, "lttng_", sizeof("lttng_") - 1))
139 seq_printf(m
, "event { name = %s; };\n",
145 const struct seq_operations lttng_tracepoint_list_seq_ops
= {
146 .start
= tp_list_start
,
147 .next
= tp_list_next
,
148 .stop
= tp_list_stop
,
149 .show
= tp_list_show
,
153 int lttng_tracepoint_list_open(struct inode
*inode
, struct file
*file
)
155 return seq_open(file
, <tng_tracepoint_list_seq_ops
);
158 const struct file_operations lttng_tracepoint_list_fops
= {
159 .owner
= THIS_MODULE
,
160 .open
= lttng_tracepoint_list_open
,
163 .release
= seq_release
,