update ltt-events
[lttng-modules.git] / ltt-events.c
1 /*
2 * ltt-events.c
3 *
4 * Copyright 2010 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
5 *
6 * Holds LTTng per-session event registry.
7 */
8
9 #include <linux/module.h>
10 #include "ltt-events.h"
11
12 static LIST_HEAD(sessions);
13 static DEFINE_MUTEX(sessions_mutex);
14 static struct kmem_cache *event_cache;
15
16 struct ltt_session *ltt_session_create(char *name)
17 {
18 struct ltt_session *session;
19
20 mutex_lock(&sessions_mutex);
21 list_for_each_entry(session, &sessions, list)
22 if (!strcmp(session->name, name))
23 goto exist;
24 session = kmalloc(sizeof(struct ltt_session) + strlen(name) + 1);
25 if (!session)
26 return NULL;
27 strcpy(session->name, name);
28 INIT_LIST_HEAD(&session->chan);
29 list_add(&session->list, &sessions);
30 mutex_unlock(&sessions_mutex);
31 return session;
32
33 exist:
34 mutex_unlock(&sessions_mutex);
35 return NULL;
36 }
37
38 int ltt_session_destroy(struct ltt_session *session)
39 {
40 struct ltt_channel *chan, *tmpchan;
41 struct ltt_event *event, *tmpevent;
42
43 mutex_lock(&sessions_mutex);
44 list_for_each_entry_safe(event, tmpevent, &session->events, list)
45 _ltt_event_destroy(event);
46 list_for_each_entry_safe(chan, tmpchan, &session->chan, list)
47 _ltt_channel_destroy(chan);
48 list_del(&session->list);
49 mutex_unlock(&sessions_mutex);
50 kfree(session);
51 }
52
53 struct ltt_channel *ltt_channel_create(struct ltt_session *session, char *name,
54 int overwrite, void *buf_addr,
55 size_t subbuf_size, size_t num_subbuf,
56 unsigned int switch_timer_interval,
57 unsigned int read_timer_interval)
58 {
59 struct ltt_channel *chan;
60
61 mutex_lock(&sessions_mutex);
62 if (session->active)
63 goto active; /* Refuse to add channel to active session */
64 list_for_each_entry(chan, &session->chan, list)
65 if (!strcmp(chan->name, name))
66 goto exist;
67 chan = kmalloc(sizeof(struct ltt_channel) + strlen(name) + 1, GFP_KERNEL);
68 if (!chan)
69 return NULL;
70 strcpy(chan->name, name);
71 chan->session = session;
72
73 /* TODO: create rb channel */
74 list_add(&chan->list, &session->chan);
75 mutex_unlock(&sessions_mutex);
76 return chan;
77
78 exist:
79 active:
80 mutex_unlock(&sessions_mutex);
81 return NULL;
82 }
83
84 /*
85 * Only used internally at session destruction.
86 */
87 int _ltt_channel_destroy(struct ltt_channel *chan)
88 {
89 list_del(&chan->list);
90 kfree(chan);
91 }
92
93 /*
94 * Supports event creation while tracing session is active.
95 */
96 struct ltt_event *ltt_event_create(struct ltt_channel *chan, char *name,
97 void *filter)
98 {
99 struct ltt_event *event;
100
101 mutex_lock(&sessions_mutex);
102 if (chan->free_event_id == -1UL)
103 goto full;
104 /*
105 * This is O(n^2) (for each event loop called at event creation).
106 * Might require a hash if we have lots of events.
107 */
108 list_for_each_entry(event, &chan->session->events, list)
109 if (!strcmp(event->name, name))
110 goto exist;
111 event = kmem_cache_zalloc(events_cache, GFP_KERNEL);
112 if (!event)
113 goto cache_error;
114 event->name = kmalloc(strlen(name) + 1, GFP_KERNEL);
115 if (!event->name)
116 goto error;
117 strcpy(event->name, name);
118 event->chan = chan;
119 event->filter = filter;
120 event->id = chan->free_event_id++;
121 mutex_unlock(&sessions_mutex);
122 /* Populate ltt_event structure before tracepoint registration. */
123 smp_wmb();
124 /* TODO register to tracepoint */
125 return event;
126
127 error:
128 kmem_cache_free(event);
129 cache_error:
130 exist:
131 full:
132 mutex_unlock(&sessions_mutex);
133 return NULL;
134 }
135
136 /*
137 * Only used internally at session destruction.
138 */
139 int _ltt_event_destroy(struct ltt_event *event)
140 {
141 /* TODO unregister from tracepoint */
142 kfree(event->name);
143 kmem_cache_free(event);
144 }
145
146 static int __init ltt_events_init(void)
147 {
148 int ret;
149
150 events_cache = KMEM_CACHE(ltt_event, 0);
151 if (!events_cache)
152 return -ENOMEM;
153
154 /* TODO: show ABI to userspace */
155
156 return 0;
157 }
158
159 static void __exit ltt_events_exit(void)
160 {
161 struct ltt_session *session, *tmpsession;
162
163 /* TODO: hide ABI from userspace, wait for callers to release refs. */
164
165 list_for_each_entry_safe(session, tmpsession, &sessions, list)
166 ltt_session_destroy(session);
167 kmem_cache_destroy(events_cache);
168 }
169
170 MODULE_LICENSE("GPL and additional rights");
171 MODULE_AUTHOR("Mathieu Desnoyers <mathieu.desnoyers@efficios.com>");
172 MODULE_DESCRIPTION("LTTng Events");
This page took 0.036945 seconds and 5 git commands to generate.