4 * Holds LTTng probes registry.
6 * Copyright (C) 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; only
11 * version 2.1 of the License.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 #include <linux/module.h>
24 #include <linux/list.h>
25 #include <linux/mutex.h>
26 #include <linux/seq_file.h>
28 #include "lttng-events.h"
30 static LIST_HEAD(probe_list
);
31 static DEFINE_MUTEX(probe_mutex
);
34 const struct lttng_event_desc
*find_event(const char *name
)
36 struct lttng_probe_desc
*probe_desc
;
39 list_for_each_entry(probe_desc
, &probe_list
, head
) {
40 for (i
= 0; i
< probe_desc
->nr_events
; i
++) {
41 if (!strcmp(probe_desc
->event_desc
[i
]->name
, name
))
42 return probe_desc
->event_desc
[i
];
48 int lttng_probe_register(struct lttng_probe_desc
*desc
)
53 mutex_lock(&probe_mutex
);
55 * TODO: This is O(N^2). Turn into a hash table when probe registration
56 * overhead becomes an issue.
58 for (i
= 0; i
< desc
->nr_events
; i
++) {
59 if (find_event(desc
->event_desc
[i
]->name
)) {
64 list_add(&desc
->head
, &probe_list
);
66 mutex_unlock(&probe_mutex
);
69 EXPORT_SYMBOL_GPL(lttng_probe_register
);
71 void lttng_probe_unregister(struct lttng_probe_desc
*desc
)
73 mutex_lock(&probe_mutex
);
74 list_del(&desc
->head
);
75 mutex_unlock(&probe_mutex
);
77 EXPORT_SYMBOL_GPL(lttng_probe_unregister
);
79 const struct lttng_event_desc
*lttng_event_get(const char *name
)
81 const struct lttng_event_desc
*event
;
84 mutex_lock(&probe_mutex
);
85 event
= find_event(name
);
86 mutex_unlock(&probe_mutex
);
89 ret
= try_module_get(event
->owner
);
93 EXPORT_SYMBOL_GPL(lttng_event_get
);
95 void lttng_event_put(const struct lttng_event_desc
*event
)
97 module_put(event
->owner
);
99 EXPORT_SYMBOL_GPL(lttng_event_put
);
102 void *tp_list_start(struct seq_file
*m
, loff_t
*pos
)
104 struct lttng_probe_desc
*probe_desc
;
107 mutex_lock(&probe_mutex
);
108 list_for_each_entry(probe_desc
, &probe_list
, head
) {
109 for (i
= 0; i
< probe_desc
->nr_events
; i
++) {
111 return (void *) probe_desc
->event_desc
[i
];
119 void *tp_list_next(struct seq_file
*m
, void *p
, loff_t
*ppos
)
121 struct lttng_probe_desc
*probe_desc
;
125 list_for_each_entry(probe_desc
, &probe_list
, head
) {
126 for (i
= 0; i
< probe_desc
->nr_events
; i
++) {
128 return (void *) probe_desc
->event_desc
[i
];
136 void tp_list_stop(struct seq_file
*m
, void *p
)
138 mutex_unlock(&probe_mutex
);
142 int tp_list_show(struct seq_file
*m
, void *p
)
144 const struct lttng_event_desc
*probe_desc
= p
;
147 * Don't export lttng internal event: lttng_metadata.
149 if (!strcmp(probe_desc
->name
, "lttng_metadata"))
151 seq_printf(m
, "event { name = %s; };\n",
157 const struct seq_operations lttng_tracepoint_list_seq_ops
= {
158 .start
= tp_list_start
,
159 .next
= tp_list_next
,
160 .stop
= tp_list_stop
,
161 .show
= tp_list_show
,
165 int lttng_tracepoint_list_open(struct inode
*inode
, struct file
*file
)
167 return seq_open(file
, <tng_tracepoint_list_seq_ops
);
170 const struct file_operations lttng_tracepoint_list_fops
= {
171 .owner
= THIS_MODULE
,
172 .open
= lttng_tracepoint_list_open
,
175 .release
= seq_release
,