]>
Commit | Line | Data |
---|---|---|
f9dfa750 JR |
1 | diff --git a/Kconfig b/Kconfig |
2 | index acdab73..10eccff 100644 | |
3 | --- a/Kconfig | |
4 | +++ b/Kconfig | |
5 | @@ -2,7 +2,7 @@ | |
6 | ||
7 | config LTTNG | |
8 | tristate "LTTng support" | |
9 | - select TRACEPOINTS | |
10 | + select TRACING | |
11 | help | |
12 | LTTng is an open source tracing framework for Linux. | |
13 | ||
14 | diff --git a/instrumentation/events/lttng-module/arch/x86/kvm/mmutrace.h b/instrumentation/events/lttng-module/arch/x86/kvm/mmutrace.h | |
15 | index 73463d5..e547040 100644 | |
16 | --- a/instrumentation/events/lttng-module/arch/x86/kvm/mmutrace.h | |
17 | +++ b/instrumentation/events/lttng-module/arch/x86/kvm/mmutrace.h | |
18 | @@ -220,6 +220,7 @@ LTTNG_TRACEPOINT_EVENT_MAP( | |
19 | LTTNG_KERNEL_RANGE(5,4,19, 5,5,0) || \ | |
20 | LTTNG_KERNEL_RANGE(5,5,3, 5,6,0) || \ | |
21 | LTTNG_UBUNTU_KERNEL_RANGE(4,15,18,92, 4,16,0,0) || \ | |
22 | + LTTNG_UBUNTU_KERNEL_RANGE(5,0,21,44, 5,1,0,0) || \ | |
23 | LTTNG_UBUNTU_KERNEL_RANGE(5,3,18,43, 5,3,18,45) || \ | |
24 | LTTNG_UBUNTU_KERNEL_RANGE(5,3,18,46, 5,4,0,0)) | |
25 | LTTNG_TRACEPOINT_EVENT_MAP( | |
26 | diff --git a/instrumentation/events/lttng-module/ext4.h b/instrumentation/events/lttng-module/ext4.h | |
27 | index 5f7ab28..b172c8d 100644 | |
28 | --- a/instrumentation/events/lttng-module/ext4.h | |
29 | +++ b/instrumentation/events/lttng-module/ext4.h | |
30 | @@ -460,6 +460,21 @@ LTTNG_TRACEPOINT_EVENT(ext4_mb_release_group_pa, | |
31 | ) | |
32 | #endif | |
33 | ||
34 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,9,0) || \ | |
35 | + LTTNG_KERNEL_RANGE(5,8,6, 5,9,0)) | |
36 | +LTTNG_TRACEPOINT_EVENT(ext4_discard_preallocations, | |
37 | + TP_PROTO(struct inode *inode, unsigned int len, unsigned int needed), | |
38 | + | |
39 | + TP_ARGS(inode, len, needed), | |
40 | + | |
41 | + TP_FIELDS( | |
42 | + ctf_integer(dev_t, dev, inode->i_sb->s_dev) | |
43 | + ctf_integer(ino_t, ino, inode->i_ino) | |
44 | + ctf_integer(unsigned int, len, len) | |
45 | + ctf_integer(unsigned int, needed, needed) | |
46 | + ) | |
47 | +) | |
48 | +#else | |
49 | LTTNG_TRACEPOINT_EVENT(ext4_discard_preallocations, | |
50 | TP_PROTO(struct inode *inode), | |
51 | ||
52 | @@ -470,6 +485,7 @@ LTTNG_TRACEPOINT_EVENT(ext4_discard_preallocations, | |
53 | ctf_integer(ino_t, ino, inode->i_ino) | |
54 | ) | |
55 | ) | |
56 | +#endif | |
57 | ||
58 | LTTNG_TRACEPOINT_EVENT(ext4_mb_discard_preallocations, | |
59 | TP_PROTO(struct super_block *sb, int needed), | |
60 | @@ -878,12 +894,26 @@ LTTNG_TRACEPOINT_EVENT_INSTANCE(ext4__bitmap_load, ext4_mb_buddy_bitmap_load, | |
61 | TP_ARGS(sb, group) | |
62 | ) | |
63 | ||
64 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,9,0)) | |
65 | +LTTNG_TRACEPOINT_EVENT(ext4_read_block_bitmap_load, | |
66 | + TP_PROTO(struct super_block *sb, unsigned long group, bool prefetch), | |
67 | + | |
68 | + TP_ARGS(sb, group, prefetch), | |
69 | + | |
70 | + TP_FIELDS( | |
71 | + ctf_integer(dev_t, dev, sb->s_dev) | |
72 | + ctf_integer(__u32, group, group) | |
73 | + ctf_integer(bool, prefetch, prefetch) | |
74 | + ) | |
75 | +) | |
76 | +#else | |
77 | LTTNG_TRACEPOINT_EVENT_INSTANCE(ext4__bitmap_load, ext4_read_block_bitmap_load, | |
78 | ||
79 | TP_PROTO(struct super_block *sb, unsigned long group), | |
80 | ||
81 | TP_ARGS(sb, group) | |
82 | ) | |
83 | +#endif | |
84 | ||
85 | LTTNG_TRACEPOINT_EVENT_INSTANCE(ext4__bitmap_load, ext4_load_inode_bitmap, | |
86 | ||
87 | diff --git a/instrumentation/events/lttng-module/i2c.h b/instrumentation/events/lttng-module/i2c.h | |
88 | index dcbabf6..131d134 100644 | |
89 | --- a/instrumentation/events/lttng-module/i2c.h | |
90 | +++ b/instrumentation/events/lttng-module/i2c.h | |
91 | @@ -23,7 +23,7 @@ LTTNG_TRACEPOINT_EVENT_CODE(i2c_write, | |
92 | ||
93 | TP_code_pre( | |
94 | tp_locvar->extract_sensitive_payload = | |
95 | - READ_ONCE(extract_sensitive_payload); | |
96 | + LTTNG_READ_ONCE(extract_sensitive_payload); | |
97 | ), | |
98 | ||
99 | TP_FIELDS( | |
100 | @@ -78,7 +78,7 @@ LTTNG_TRACEPOINT_EVENT_CODE(i2c_reply, | |
101 | ||
102 | TP_code_pre( | |
103 | tp_locvar->extract_sensitive_payload = | |
104 | - READ_ONCE(extract_sensitive_payload); | |
105 | + LTTNG_READ_ONCE(extract_sensitive_payload); | |
106 | ), | |
107 | ||
108 | TP_FIELDS( | |
109 | diff --git a/instrumentation/events/lttng-module/rcu.h b/instrumentation/events/lttng-module/rcu.h | |
110 | index 6a0b58d..24bd51d 100644 | |
111 | --- a/instrumentation/events/lttng-module/rcu.h | |
112 | +++ b/instrumentation/events/lttng-module/rcu.h | |
113 | @@ -394,7 +394,8 @@ LTTNG_TRACEPOINT_EVENT(rcu_fqs, | |
114 | */ | |
115 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0)) \ | |
116 | || LTTNG_KERNEL_RANGE(5,5,6, 5,6,0) \ | |
117 | - || LTTNG_KERNEL_RANGE(5,4,22, 5,5,0) | |
118 | + || LTTNG_KERNEL_RANGE(5,4,22, 5,5,0) \ | |
119 | + || LTTNG_UBUNTU_KERNEL_RANGE(5,0,21,46, 5,1,0,0) | |
120 | LTTNG_TRACEPOINT_EVENT(rcu_dyntick, | |
121 | ||
122 | TP_PROTO(const char *polarity, long oldnesting, long newnesting, int dynticks), | |
123 | diff --git a/instrumentation/events/lttng-module/writeback.h b/instrumentation/events/lttng-module/writeback.h | |
124 | index affb4eb..0ce4915 100644 | |
125 | --- a/instrumentation/events/lttng-module/writeback.h | |
126 | +++ b/instrumentation/events/lttng-module/writeback.h | |
127 | @@ -46,7 +46,21 @@ static inline struct backing_dev_info *lttng_inode_to_bdi(struct inode *inode) | |
128 | ||
129 | #endif | |
130 | ||
131 | -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0)) | |
132 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,9,0)) | |
133 | +#define show_inode_state(state) \ | |
134 | + __print_flags(state, "|", \ | |
135 | + {I_DIRTY_SYNC, "I_DIRTY_SYNC"}, \ | |
136 | + {I_DIRTY_DATASYNC, "I_DIRTY_DATASYNC"}, \ | |
137 | + {I_DIRTY_PAGES, "I_DIRTY_PAGES"}, \ | |
138 | + {I_NEW, "I_NEW"}, \ | |
139 | + {I_WILL_FREE, "I_WILL_FREE"}, \ | |
140 | + {I_FREEING, "I_FREEING"}, \ | |
141 | + {I_CLEAR, "I_CLEAR"}, \ | |
142 | + {I_SYNC, "I_SYNC"}, \ | |
143 | + {I_DIRTY_TIME, "I_DIRTY_TIME"}, \ | |
144 | + {I_REFERENCED, "I_REFERENCED"} \ | |
145 | + ) | |
146 | +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0)) | |
147 | #define show_inode_state(state) \ | |
148 | __print_flags(state, "|", \ | |
149 | {I_DIRTY_SYNC, "I_DIRTY_SYNC"}, \ | |
150 | @@ -370,34 +384,55 @@ LTTNG_TRACEPOINT_EVENT_WBC_INSTANCE(wbc_balance_dirty_wait, writeback_wbc_balanc | |
151 | #endif | |
152 | LTTNG_TRACEPOINT_EVENT_WBC_INSTANCE(wbc_writepage, writeback_wbc_writepage) | |
153 | ||
154 | -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)) | |
155 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,9,0) || \ | |
156 | + LTTNG_KERNEL_RANGE(5,8,6, 5,9,0) || \ | |
157 | + LTTNG_KERNEL_RANGE(5,4,62, 5,5,0) || \ | |
158 | + LTTNG_KERNEL_RANGE(4,19,143, 4,20,0) || \ | |
159 | + LTTNG_KERNEL_RANGE(4,14,196, 4,15,0) || \ | |
160 | + LTTNG_KERNEL_RANGE(4,9,235, 4,10,0) || \ | |
161 | + LTTNG_KERNEL_RANGE(4,4,235, 4,5,0) || \ | |
162 | + LTTNG_UBUNTU_KERNEL_RANGE(4,15,18,119, 4,16,0,0)) | |
163 | +LTTNG_TRACEPOINT_EVENT(writeback_queue_io, | |
164 | + TP_PROTO(struct bdi_writeback *wb, | |
165 | + struct wb_writeback_work *work, | |
166 | + unsigned long dirtied_before, | |
167 | + int moved), | |
168 | + TP_ARGS(wb, work, dirtied_before, moved), | |
169 | + TP_FIELDS( | |
170 | + ctf_array_text(char, name, dev_name(wb->bdi->dev), 32) | |
171 | + ctf_integer(unsigned long, older, dirtied_before) | |
172 | + ctf_integer(int, moved, moved) | |
173 | + ) | |
174 | +) | |
175 | +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) | |
176 | LTTNG_TRACEPOINT_EVENT(writeback_queue_io, | |
177 | TP_PROTO(struct bdi_writeback *wb, | |
178 | -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) | |
179 | struct wb_writeback_work *work, | |
180 | -#else | |
181 | - unsigned long *older_than_this, | |
182 | -#endif | |
183 | int moved), | |
184 | -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) | |
185 | TP_ARGS(wb, work, moved), | |
186 | -#else | |
187 | + TP_FIELDS( | |
188 | + ctf_array_text(char, name, dev_name(wb->bdi->dev), 32) | |
189 | + ctf_integer(int, moved, moved) | |
190 | + ) | |
191 | +) | |
192 | +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)) | |
193 | +LTTNG_TRACEPOINT_EVENT(writeback_queue_io, | |
194 | + TP_PROTO(struct bdi_writeback *wb, | |
195 | + unsigned long *older_than_this, | |
196 | + int moved), | |
197 | TP_ARGS(wb, older_than_this, moved), | |
198 | -#endif | |
199 | TP_FIELDS( | |
200 | ctf_array_text(char, name, dev_name(wb->bdi->dev), 32) | |
201 | -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) | |
202 | -#else | |
203 | ctf_integer(unsigned long, older, | |
204 | older_than_this ? *older_than_this : 0) | |
205 | ctf_integer(long, age, | |
206 | older_than_this ? | |
207 | (jiffies - *older_than_this) * 1000 / HZ | |
208 | : -1) | |
209 | -#endif | |
210 | ctf_integer(int, moved, moved) | |
211 | ) | |
212 | ) | |
213 | +#endif | |
214 | ||
215 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,8,0)) | |
216 | LTTNG_TRACEPOINT_EVENT_MAP(global_dirty_state, | |
217 | @@ -446,7 +481,7 @@ LTTNG_TRACEPOINT_EVENT_MAP(global_dirty_state, | |
218 | ctf_integer(unsigned long, dirty_limit, global_dirty_limit) | |
219 | ) | |
220 | ) | |
221 | -#else | |
222 | +#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)) | |
223 | LTTNG_TRACEPOINT_EVENT_MAP(global_dirty_state, | |
224 | ||
225 | writeback_global_dirty_state, | |
226 | @@ -471,7 +506,6 @@ LTTNG_TRACEPOINT_EVENT_MAP(global_dirty_state, | |
227 | ) | |
228 | ) | |
229 | #endif | |
230 | -#endif | |
231 | ||
232 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)) | |
233 | ||
234 | diff --git a/lib/ringbuffer/backend.h b/lib/ringbuffer/backend.h | |
235 | index da937f2..43e1d47 100644 | |
236 | --- a/lib/ringbuffer/backend.h | |
237 | +++ b/lib/ringbuffer/backend.h | |
238 | @@ -156,7 +156,7 @@ size_t lib_ring_buffer_do_strcpy(const struct lib_ring_buffer_config *config, | |
239 | * Only read source character once, in case it is | |
240 | * modified concurrently. | |
241 | */ | |
242 | - c = READ_ONCE(src[count]); | |
243 | + c = LTTNG_READ_ONCE(src[count]); | |
244 | if (!c) | |
245 | break; | |
246 | lib_ring_buffer_do_copy(config, &dest[count], &c, 1); | |
247 | diff --git a/lib/ringbuffer/backend_internal.h b/lib/ringbuffer/backend_internal.h | |
248 | index 2d6a345..1226fd8 100644 | |
249 | --- a/lib/ringbuffer/backend_internal.h | |
250 | +++ b/lib/ringbuffer/backend_internal.h | |
251 | @@ -367,7 +367,7 @@ void lib_ring_buffer_clear_noref(const struct lib_ring_buffer_config *config, | |
252 | * Performing a volatile access to read the sb_pages, because we want to | |
253 | * read a coherent version of the pointer and the associated noref flag. | |
254 | */ | |
255 | - id = READ_ONCE(bufb->buf_wsb[idx].id); | |
256 | + id = LTTNG_READ_ONCE(bufb->buf_wsb[idx].id); | |
257 | for (;;) { | |
258 | /* This check is called on the fast path for each record. */ | |
259 | if (likely(!subbuffer_id_is_noref(config, id))) { | |
260 | diff --git a/lib/ringbuffer/frontend.h b/lib/ringbuffer/frontend.h | |
261 | index 6f516d9..41382fe 100644 | |
262 | --- a/lib/ringbuffer/frontend.h | |
263 | +++ b/lib/ringbuffer/frontend.h | |
264 | @@ -79,7 +79,7 @@ void *channel_destroy(struct channel *chan); | |
265 | #define for_each_channel_cpu(cpu, chan) \ | |
266 | for ((cpu) = -1; \ | |
267 | ({ (cpu) = cpumask_next(cpu, (chan)->backend.cpumask); \ | |
268 | - smp_read_barrier_depends(); (cpu) < nr_cpu_ids; });) | |
269 | + smp_rmb(); (cpu) < nr_cpu_ids; });) | |
270 | ||
271 | extern struct lib_ring_buffer *channel_get_ring_buffer( | |
272 | const struct lib_ring_buffer_config *config, | |
273 | @@ -155,7 +155,7 @@ static inline | |
274 | int lib_ring_buffer_is_finalized(const struct lib_ring_buffer_config *config, | |
275 | struct lib_ring_buffer *buf) | |
276 | { | |
277 | - int finalized = READ_ONCE(buf->finalized); | |
278 | + int finalized = LTTNG_READ_ONCE(buf->finalized); | |
279 | /* | |
280 | * Read finalized before counters. | |
281 | */ | |
282 | diff --git a/lib/ringbuffer/ring_buffer_frontend.c b/lib/ringbuffer/ring_buffer_frontend.c | |
283 | index 3cab365..4980d20 100644 | |
284 | --- a/lib/ringbuffer/ring_buffer_frontend.c | |
285 | +++ b/lib/ringbuffer/ring_buffer_frontend.c | |
286 | @@ -1074,7 +1074,7 @@ int lib_ring_buffer_snapshot(struct lib_ring_buffer *buf, | |
287 | int finalized; | |
288 | ||
289 | retry: | |
290 | - finalized = READ_ONCE(buf->finalized); | |
291 | + finalized = LTTNG_READ_ONCE(buf->finalized); | |
292 | /* | |
293 | * Read finalized before counters. | |
294 | */ | |
295 | @@ -1245,7 +1245,7 @@ int lib_ring_buffer_get_subbuf(struct lib_ring_buffer *buf, | |
296 | return -EBUSY; | |
297 | } | |
298 | retry: | |
299 | - finalized = READ_ONCE(buf->finalized); | |
300 | + finalized = LTTNG_READ_ONCE(buf->finalized); | |
301 | /* | |
302 | * Read finalized before counters. | |
303 | */ | |
304 | diff --git a/lib/ringbuffer/ring_buffer_iterator.c b/lib/ringbuffer/ring_buffer_iterator.c | |
305 | index d25db72..7b4f20a 100644 | |
306 | --- a/lib/ringbuffer/ring_buffer_iterator.c | |
307 | +++ b/lib/ringbuffer/ring_buffer_iterator.c | |
308 | @@ -46,7 +46,7 @@ restart: | |
309 | switch (iter->state) { | |
310 | case ITER_GET_SUBBUF: | |
311 | ret = lib_ring_buffer_get_next_subbuf(buf); | |
312 | - if (ret && !READ_ONCE(buf->finalized) | |
313 | + if (ret && !LTTNG_READ_ONCE(buf->finalized) | |
314 | && config->alloc == RING_BUFFER_ALLOC_GLOBAL) { | |
315 | /* | |
316 | * Use "pull" scheme for global buffers. The reader | |
317 | diff --git a/lttng-abi.c b/lttng-abi.c | |
318 | index 64ea99d..b33879d 100644 | |
319 | --- a/lttng-abi.c | |
320 | +++ b/lttng-abi.c | |
321 | @@ -1264,6 +1264,46 @@ nomem: | |
322 | return ret; | |
323 | } | |
324 | ||
325 | +static | |
326 | +int lttng_abi_validate_event_param(struct lttng_kernel_event *event_param) | |
327 | +{ | |
328 | + /* Limit ABI to implemented features. */ | |
329 | + switch (event_param->instrumentation) { | |
330 | + case LTTNG_KERNEL_SYSCALL: | |
331 | + switch (event_param->u.syscall.entryexit) { | |
332 | + case LTTNG_KERNEL_SYSCALL_ENTRYEXIT: | |
333 | + break; | |
334 | + default: | |
335 | + return -EINVAL; | |
336 | + } | |
337 | + switch (event_param->u.syscall.abi) { | |
338 | + case LTTNG_KERNEL_SYSCALL_ABI_ALL: | |
339 | + break; | |
340 | + default: | |
341 | + return -EINVAL; | |
342 | + } | |
343 | + switch (event_param->u.syscall.match) { | |
344 | + case LTTNG_SYSCALL_MATCH_NAME: | |
345 | + break; | |
346 | + default: | |
347 | + return -EINVAL; | |
348 | + } | |
349 | + break; | |
350 | + | |
351 | + case LTTNG_KERNEL_TRACEPOINT: /* Fallthrough */ | |
352 | + case LTTNG_KERNEL_KPROBE: /* Fallthrough */ | |
353 | + case LTTNG_KERNEL_KRETPROBE: /* Fallthrough */ | |
354 | + case LTTNG_KERNEL_NOOP: /* Fallthrough */ | |
355 | + case LTTNG_KERNEL_UPROBE: | |
356 | + break; | |
357 | + | |
358 | + case LTTNG_KERNEL_FUNCTION: /* Fallthrough */ | |
359 | + default: | |
360 | + return -EINVAL; | |
361 | + } | |
362 | + return 0; | |
363 | +} | |
364 | + | |
365 | static | |
366 | int lttng_abi_create_event(struct file *channel_file, | |
367 | struct lttng_kernel_event *event_param) | |
368 | @@ -1305,6 +1345,9 @@ int lttng_abi_create_event(struct file *channel_file, | |
369 | ret = -EOVERFLOW; | |
370 | goto refcount_error; | |
371 | } | |
372 | + ret = lttng_abi_validate_event_param(event_param); | |
373 | + if (ret) | |
374 | + goto event_error; | |
375 | if (event_param->instrumentation == LTTNG_KERNEL_TRACEPOINT | |
376 | || event_param->instrumentation == LTTNG_KERNEL_SYSCALL) { | |
377 | struct lttng_enabler *enabler; | |
378 | diff --git a/lttng-abi.h b/lttng-abi.h | |
379 | index 1d356ab..51d60e5 100644 | |
380 | --- a/lttng-abi.h | |
381 | +++ b/lttng-abi.h | |
382 | @@ -90,6 +90,31 @@ struct lttng_kernel_event_callsite { | |
383 | } u; | |
384 | } __attribute__((packed)); | |
385 | ||
386 | +enum lttng_kernel_syscall_entryexit { | |
387 | + LTTNG_KERNEL_SYSCALL_ENTRYEXIT = 0, | |
388 | + LTTNG_KERNEL_SYSCALL_ENTRY = 1, /* Not implemented. */ | |
389 | + LTTNG_KERNEL_SYSCALL_EXIT = 2, /* Not implemented. */ | |
390 | +}; | |
391 | + | |
392 | +enum lttng_kernel_syscall_abi { | |
393 | + LTTNG_KERNEL_SYSCALL_ABI_ALL = 0, | |
394 | + LTTNG_KERNEL_SYSCALL_ABI_NATIVE = 1, /* Not implemented. */ | |
395 | + LTTNG_KERNEL_SYSCALL_ABI_COMPAT = 2, /* Not implemented. */ | |
396 | +}; | |
397 | + | |
398 | +enum lttng_kernel_syscall_match { | |
399 | + LTTNG_SYSCALL_MATCH_NAME = 0, | |
400 | + LTTNG_SYSCALL_MATCH_NR = 1, /* Not implemented. */ | |
401 | +}; | |
402 | + | |
403 | +struct lttng_kernel_syscall { | |
404 | + uint8_t entryexit; /* enum lttng_kernel_syscall_entryexit */ | |
405 | + uint8_t abi; /* enum lttng_kernel_syscall_abi */ | |
406 | + uint8_t match; /* enum lttng_kernel_syscall_match */ | |
407 | + uint8_t padding; | |
408 | + uint32_t nr; /* For LTTNG_SYSCALL_MATCH_NR */ | |
409 | +} __attribute__((packed)); | |
410 | + | |
411 | /* | |
412 | * For syscall tracing, name = "*" means "enable all". | |
413 | */ | |
414 | @@ -106,6 +131,7 @@ struct lttng_kernel_event { | |
415 | struct lttng_kernel_kprobe kprobe; | |
416 | struct lttng_kernel_function_tracer ftrace; | |
417 | struct lttng_kernel_uprobe uprobe; | |
418 | + struct lttng_kernel_syscall syscall; | |
419 | char padding[LTTNG_KERNEL_EVENT_PADDING2]; | |
420 | } u; | |
421 | } __attribute__((packed)); | |
422 | diff --git a/lttng-events.c b/lttng-events.c | |
423 | index be7e389..4c0b04a 100644 | |
424 | --- a/lttng-events.c | |
425 | +++ b/lttng-events.c | |
426 | @@ -201,6 +201,10 @@ void lttng_session_destroy(struct lttng_session *session) | |
427 | WARN_ON(ret); | |
428 | } | |
429 | synchronize_trace(); /* Wait for in-flight events to complete */ | |
430 | + list_for_each_entry(chan, &session->chan, list) { | |
431 | + ret = lttng_syscalls_destroy(chan); | |
432 | + WARN_ON(ret); | |
433 | + } | |
434 | list_for_each_entry_safe(enabler, tmpenabler, | |
435 | &session->enablers_head, node) | |
436 | lttng_enabler_destroy(enabler); | |
437 | @@ -740,6 +744,28 @@ struct lttng_event *_lttng_event_create(struct lttng_channel *chan, | |
438 | event->enabled = 0; | |
439 | event->registered = 0; | |
440 | event->desc = event_desc; | |
441 | + switch (event_param->u.syscall.entryexit) { | |
442 | + case LTTNG_KERNEL_SYSCALL_ENTRYEXIT: | |
443 | + ret = -EINVAL; | |
444 | + goto register_error; | |
445 | + case LTTNG_KERNEL_SYSCALL_ENTRY: | |
446 | + event->u.syscall.entryexit = LTTNG_SYSCALL_ENTRY; | |
447 | + break; | |
448 | + case LTTNG_KERNEL_SYSCALL_EXIT: | |
449 | + event->u.syscall.entryexit = LTTNG_SYSCALL_EXIT; | |
450 | + break; | |
451 | + } | |
452 | + switch (event_param->u.syscall.abi) { | |
453 | + case LTTNG_KERNEL_SYSCALL_ABI_ALL: | |
454 | + ret = -EINVAL; | |
455 | + goto register_error; | |
456 | + case LTTNG_KERNEL_SYSCALL_ABI_NATIVE: | |
457 | + event->u.syscall.abi = LTTNG_SYSCALL_ABI_NATIVE; | |
458 | + break; | |
459 | + case LTTNG_KERNEL_SYSCALL_ABI_COMPAT: | |
460 | + event->u.syscall.abi = LTTNG_SYSCALL_ABI_COMPAT; | |
461 | + break; | |
462 | + } | |
463 | if (!event->desc) { | |
464 | ret = -EINVAL; | |
465 | goto register_error; | |
466 | @@ -826,8 +852,7 @@ void register_event(struct lttng_event *event) | |
467 | event); | |
468 | break; | |
469 | case LTTNG_KERNEL_SYSCALL: | |
470 | - ret = lttng_syscall_filter_enable(event->chan, | |
471 | - desc->name); | |
472 | + ret = lttng_syscall_filter_enable(event->chan, event); | |
473 | break; | |
474 | case LTTNG_KERNEL_KPROBE: | |
475 | case LTTNG_KERNEL_UPROBE: | |
476 | @@ -870,8 +895,7 @@ int _lttng_event_unregister(struct lttng_event *event) | |
477 | ret = 0; | |
478 | break; | |
479 | case LTTNG_KERNEL_SYSCALL: | |
480 | - ret = lttng_syscall_filter_disable(event->chan, | |
481 | - desc->name); | |
482 | + ret = lttng_syscall_filter_disable(event->chan, event); | |
483 | break; | |
484 | case LTTNG_KERNEL_NOOP: | |
485 | ret = 0; | |
486 | @@ -1203,39 +1227,87 @@ int lttng_desc_match_enabler(const struct lttng_event_desc *desc, | |
487 | struct lttng_enabler *enabler) | |
488 | { | |
489 | const char *desc_name, *enabler_name; | |
490 | + bool compat = false, entry = false; | |
491 | ||
492 | enabler_name = enabler->event_param.name; | |
493 | switch (enabler->event_param.instrumentation) { | |
494 | case LTTNG_KERNEL_TRACEPOINT: | |
495 | desc_name = desc->name; | |
496 | + switch (enabler->type) { | |
497 | + case LTTNG_ENABLER_STAR_GLOB: | |
498 | + return lttng_match_enabler_star_glob(desc_name, enabler_name); | |
499 | + case LTTNG_ENABLER_NAME: | |
500 | + return lttng_match_enabler_name(desc_name, enabler_name); | |
501 | + default: | |
502 | + return -EINVAL; | |
503 | + } | |
504 | break; | |
505 | case LTTNG_KERNEL_SYSCALL: | |
506 | desc_name = desc->name; | |
507 | - if (!strncmp(desc_name, "compat_", strlen("compat_"))) | |
508 | + if (!strncmp(desc_name, "compat_", strlen("compat_"))) { | |
509 | desc_name += strlen("compat_"); | |
510 | + compat = true; | |
511 | + } | |
512 | if (!strncmp(desc_name, "syscall_exit_", | |
513 | strlen("syscall_exit_"))) { | |
514 | desc_name += strlen("syscall_exit_"); | |
515 | } else if (!strncmp(desc_name, "syscall_entry_", | |
516 | strlen("syscall_entry_"))) { | |
517 | desc_name += strlen("syscall_entry_"); | |
518 | + entry = true; | |
519 | } else { | |
520 | WARN_ON_ONCE(1); | |
521 | return -EINVAL; | |
522 | } | |
523 | + switch (enabler->event_param.u.syscall.entryexit) { | |
524 | + case LTTNG_KERNEL_SYSCALL_ENTRYEXIT: | |
525 | + break; | |
526 | + case LTTNG_KERNEL_SYSCALL_ENTRY: | |
527 | + if (!entry) | |
528 | + return 0; | |
529 | + break; | |
530 | + case LTTNG_KERNEL_SYSCALL_EXIT: | |
531 | + if (entry) | |
532 | + return 0; | |
533 | + break; | |
534 | + default: | |
535 | + return -EINVAL; | |
536 | + } | |
537 | + switch (enabler->event_param.u.syscall.abi) { | |
538 | + case LTTNG_KERNEL_SYSCALL_ABI_ALL: | |
539 | + break; | |
540 | + case LTTNG_KERNEL_SYSCALL_ABI_NATIVE: | |
541 | + if (compat) | |
542 | + return 0; | |
543 | + break; | |
544 | + case LTTNG_KERNEL_SYSCALL_ABI_COMPAT: | |
545 | + if (!compat) | |
546 | + return 0; | |
547 | + break; | |
548 | + default: | |
549 | + return -EINVAL; | |
550 | + } | |
551 | + switch (enabler->event_param.u.syscall.match) { | |
552 | + case LTTNG_SYSCALL_MATCH_NAME: | |
553 | + switch (enabler->type) { | |
554 | + case LTTNG_ENABLER_STAR_GLOB: | |
555 | + return lttng_match_enabler_star_glob(desc_name, enabler_name); | |
556 | + case LTTNG_ENABLER_NAME: | |
557 | + return lttng_match_enabler_name(desc_name, enabler_name); | |
558 | + default: | |
559 | + return -EINVAL; | |
560 | + } | |
561 | + break; | |
562 | + case LTTNG_SYSCALL_MATCH_NR: | |
563 | + return -EINVAL; /* Not implemented. */ | |
564 | + default: | |
565 | + return -EINVAL; | |
566 | + } | |
567 | break; | |
568 | default: | |
569 | WARN_ON_ONCE(1); | |
570 | return -EINVAL; | |
571 | } | |
572 | - switch (enabler->type) { | |
573 | - case LTTNG_ENABLER_STAR_GLOB: | |
574 | - return lttng_match_enabler_star_glob(desc_name, enabler_name); | |
575 | - case LTTNG_ENABLER_NAME: | |
576 | - return lttng_match_enabler_name(desc_name, enabler_name); | |
577 | - default: | |
578 | - return -EINVAL; | |
579 | - } | |
580 | } | |
581 | ||
582 | static | |
583 | @@ -1361,9 +1433,21 @@ void lttng_create_event_if_missing(struct lttng_enabler *enabler) | |
584 | static | |
585 | int lttng_enabler_ref_events(struct lttng_enabler *enabler) | |
586 | { | |
587 | - struct lttng_session *session = enabler->chan->session; | |
588 | + struct lttng_channel *chan = enabler->chan; | |
589 | + struct lttng_session *session = chan->session; | |
590 | struct lttng_event *event; | |
591 | ||
592 | + if (enabler->event_param.instrumentation == LTTNG_KERNEL_SYSCALL && | |
593 | + enabler->event_param.u.syscall.entryexit == LTTNG_KERNEL_SYSCALL_ENTRYEXIT && | |
594 | + enabler->event_param.u.syscall.abi == LTTNG_KERNEL_SYSCALL_ABI_ALL && | |
595 | + enabler->event_param.u.syscall.match == LTTNG_SYSCALL_MATCH_NAME && | |
596 | + !strcmp(enabler->event_param.name, "*")) { | |
597 | + if (enabler->enabled) | |
598 | + WRITE_ONCE(chan->syscall_all, 1); | |
599 | + else | |
600 | + WRITE_ONCE(chan->syscall_all, 0); | |
601 | + } | |
602 | + | |
603 | /* First ensure that probe events are created for this enabler. */ | |
604 | lttng_create_event_if_missing(enabler); | |
605 | ||
606 | @@ -1719,7 +1803,7 @@ int lttng_metadata_printf(struct lttng_session *session, | |
607 | size_t len; | |
608 | va_list ap; | |
609 | ||
610 | - WARN_ON_ONCE(!READ_ONCE(session->active)); | |
611 | + WARN_ON_ONCE(!LTTNG_READ_ONCE(session->active)); | |
612 | ||
613 | va_start(ap, fmt); | |
614 | str = kvasprintf(GFP_KERNEL, fmt, ap); | |
615 | @@ -2305,7 +2389,7 @@ int _lttng_event_metadata_statedump(struct lttng_session *session, | |
616 | { | |
617 | int ret = 0; | |
618 | ||
619 | - if (event->metadata_dumped || !READ_ONCE(session->active)) | |
620 | + if (event->metadata_dumped || !LTTNG_READ_ONCE(session->active)) | |
621 | return 0; | |
622 | if (chan->channel_type == METADATA_CHANNEL) | |
623 | return 0; | |
624 | @@ -2377,7 +2461,7 @@ int _lttng_channel_metadata_statedump(struct lttng_session *session, | |
625 | { | |
626 | int ret = 0; | |
627 | ||
628 | - if (chan->metadata_dumped || !READ_ONCE(session->active)) | |
629 | + if (chan->metadata_dumped || !LTTNG_READ_ONCE(session->active)) | |
630 | return 0; | |
631 | ||
632 | if (chan->channel_type == METADATA_CHANNEL) | |
633 | @@ -2604,7 +2688,7 @@ int _lttng_session_metadata_statedump(struct lttng_session *session) | |
634 | struct lttng_event *event; | |
635 | int ret = 0; | |
636 | ||
637 | - if (!READ_ONCE(session->active)) | |
638 | + if (!LTTNG_READ_ONCE(session->active)) | |
639 | return 0; | |
640 | ||
641 | lttng_metadata_begin(session); | |
642 | diff --git a/lttng-events.h b/lttng-events.h | |
643 | index a36a312..d4d9976 100644 | |
644 | --- a/lttng-events.h | |
645 | +++ b/lttng-events.h | |
646 | @@ -292,6 +292,16 @@ struct lttng_uprobe_handler { | |
647 | struct list_head node; | |
648 | }; | |
649 | ||
650 | +enum lttng_syscall_entryexit { | |
651 | + LTTNG_SYSCALL_ENTRY, | |
652 | + LTTNG_SYSCALL_EXIT, | |
653 | +}; | |
654 | + | |
655 | +enum lttng_syscall_abi { | |
656 | + LTTNG_SYSCALL_ABI_NATIVE, | |
657 | + LTTNG_SYSCALL_ABI_COMPAT, | |
658 | +}; | |
659 | + | |
660 | /* | |
661 | * lttng_event structure is referred to by the tracing fast path. It must be | |
662 | * kept small. | |
663 | @@ -318,6 +328,11 @@ struct lttng_event { | |
664 | struct inode *inode; | |
665 | struct list_head head; | |
666 | } uprobe; | |
667 | + struct { | |
668 | + char *syscall_name; | |
669 | + enum lttng_syscall_entryexit entryexit; | |
670 | + enum lttng_syscall_abi abi; | |
671 | + } syscall; | |
672 | } u; | |
673 | struct list_head list; /* Event list in session */ | |
674 | unsigned int metadata_dumped:1; | |
675 | @@ -457,10 +472,10 @@ struct lttng_channel { | |
676 | struct lttng_syscall_filter *sc_filter; | |
677 | int header_type; /* 0: unset, 1: compact, 2: large */ | |
678 | enum channel_type channel_type; | |
679 | + int syscall_all; | |
680 | unsigned int metadata_dumped:1, | |
681 | sys_enter_registered:1, | |
682 | sys_exit_registered:1, | |
683 | - syscall_all:1, | |
684 | tstate:1; /* Transient enable state */ | |
685 | }; | |
686 | ||
687 | @@ -653,10 +668,11 @@ void lttng_clock_unref(void); | |
688 | #if defined(CONFIG_HAVE_SYSCALL_TRACEPOINTS) | |
689 | int lttng_syscalls_register(struct lttng_channel *chan, void *filter); | |
690 | int lttng_syscalls_unregister(struct lttng_channel *chan); | |
691 | +int lttng_syscalls_destroy(struct lttng_channel *chan); | |
692 | int lttng_syscall_filter_enable(struct lttng_channel *chan, | |
693 | - const char *name); | |
694 | + struct lttng_event *event); | |
695 | int lttng_syscall_filter_disable(struct lttng_channel *chan, | |
696 | - const char *name); | |
697 | + struct lttng_event *event); | |
698 | long lttng_channel_syscall_mask(struct lttng_channel *channel, | |
699 | struct lttng_kernel_syscall_mask __user *usyscall_mask); | |
700 | #else | |
701 | @@ -670,14 +686,19 @@ static inline int lttng_syscalls_unregister(struct lttng_channel *chan) | |
702 | return 0; | |
703 | } | |
704 | ||
705 | +static inline int lttng_syscalls_destroy(struct lttng_channel *chan) | |
706 | +{ | |
707 | + return 0; | |
708 | +} | |
709 | + | |
710 | static inline int lttng_syscall_filter_enable(struct lttng_channel *chan, | |
711 | - const char *name) | |
712 | + struct lttng_event *event); | |
713 | { | |
714 | return -ENOSYS; | |
715 | } | |
716 | ||
717 | static inline int lttng_syscall_filter_disable(struct lttng_channel *chan, | |
718 | - const char *name) | |
719 | + struct lttng_event *event); | |
720 | { | |
721 | return -ENOSYS; | |
722 | } | |
723 | diff --git a/lttng-syscalls.c b/lttng-syscalls.c | |
724 | index 97f1ba9..26cead6 100644 | |
725 | --- a/lttng-syscalls.c | |
726 | +++ b/lttng-syscalls.c | |
727 | @@ -367,8 +367,10 @@ const struct trace_syscall_entry compat_sc_exit_table[] = { | |
728 | #undef CREATE_SYSCALL_TABLE | |
729 | ||
730 | struct lttng_syscall_filter { | |
731 | - DECLARE_BITMAP(sc, NR_syscalls); | |
732 | - DECLARE_BITMAP(sc_compat, NR_compat_syscalls); | |
733 | + DECLARE_BITMAP(sc_entry, NR_syscalls); | |
734 | + DECLARE_BITMAP(sc_exit, NR_syscalls); | |
735 | + DECLARE_BITMAP(sc_compat_entry, NR_compat_syscalls); | |
736 | + DECLARE_BITMAP(sc_compat_exit, NR_compat_syscalls); | |
737 | }; | |
738 | ||
739 | static void syscall_entry_unknown(struct lttng_event *event, | |
740 | @@ -391,29 +393,23 @@ void syscall_entry_probe(void *__data, struct pt_regs *regs, long id) | |
741 | size_t table_len; | |
742 | ||
743 | if (unlikely(in_compat_syscall())) { | |
744 | - struct lttng_syscall_filter *filter; | |
745 | - | |
746 | - filter = lttng_rcu_dereference(chan->sc_filter); | |
747 | - if (filter) { | |
748 | - if (id < 0 || id >= NR_compat_syscalls | |
749 | - || !test_bit(id, filter->sc_compat)) { | |
750 | - /* System call filtered out. */ | |
751 | - return; | |
752 | - } | |
753 | + struct lttng_syscall_filter *filter = chan->sc_filter; | |
754 | + | |
755 | + if (id < 0 || id >= NR_compat_syscalls | |
756 | + || (!READ_ONCE(chan->syscall_all) && !test_bit(id, filter->sc_compat_entry))) { | |
757 | + /* System call filtered out. */ | |
758 | + return; | |
759 | } | |
760 | table = compat_sc_table; | |
761 | table_len = ARRAY_SIZE(compat_sc_table); | |
762 | unknown_event = chan->sc_compat_unknown; | |
763 | } else { | |
764 | - struct lttng_syscall_filter *filter; | |
765 | - | |
766 | - filter = lttng_rcu_dereference(chan->sc_filter); | |
767 | - if (filter) { | |
768 | - if (id < 0 || id >= NR_syscalls | |
769 | - || !test_bit(id, filter->sc)) { | |
770 | - /* System call filtered out. */ | |
771 | - return; | |
772 | - } | |
773 | + struct lttng_syscall_filter *filter = chan->sc_filter; | |
774 | + | |
775 | + if (id < 0 || id >= NR_syscalls | |
776 | + || (!READ_ONCE(chan->syscall_all) && !test_bit(id, filter->sc_entry))) { | |
777 | + /* System call filtered out. */ | |
778 | + return; | |
779 | } | |
780 | table = sc_table; | |
781 | table_len = ARRAY_SIZE(sc_table); | |
782 | @@ -545,29 +541,23 @@ void syscall_exit_probe(void *__data, struct pt_regs *regs, long ret) | |
783 | ||
784 | id = syscall_get_nr(current, regs); | |
785 | if (unlikely(in_compat_syscall())) { | |
786 | - struct lttng_syscall_filter *filter; | |
787 | - | |
788 | - filter = lttng_rcu_dereference(chan->sc_filter); | |
789 | - if (filter) { | |
790 | - if (id < 0 || id >= NR_compat_syscalls | |
791 | - || !test_bit(id, filter->sc_compat)) { | |
792 | - /* System call filtered out. */ | |
793 | - return; | |
794 | - } | |
795 | + struct lttng_syscall_filter *filter = chan->sc_filter; | |
796 | + | |
797 | + if (id < 0 || id >= NR_compat_syscalls | |
798 | + || (!READ_ONCE(chan->syscall_all) && !test_bit(id, filter->sc_compat_exit))) { | |
799 | + /* System call filtered out. */ | |
800 | + return; | |
801 | } | |
802 | table = compat_sc_exit_table; | |
803 | table_len = ARRAY_SIZE(compat_sc_exit_table); | |
804 | unknown_event = chan->compat_sc_exit_unknown; | |
805 | } else { | |
806 | - struct lttng_syscall_filter *filter; | |
807 | - | |
808 | - filter = lttng_rcu_dereference(chan->sc_filter); | |
809 | - if (filter) { | |
810 | - if (id < 0 || id >= NR_syscalls | |
811 | - || !test_bit(id, filter->sc)) { | |
812 | - /* System call filtered out. */ | |
813 | - return; | |
814 | - } | |
815 | + struct lttng_syscall_filter *filter = chan->sc_filter; | |
816 | + | |
817 | + if (id < 0 || id >= NR_syscalls | |
818 | + || (!READ_ONCE(chan->syscall_all) && !test_bit(id, filter->sc_exit))) { | |
819 | + /* System call filtered out. */ | |
820 | + return; | |
821 | } | |
822 | table = sc_exit_table; | |
823 | table_len = ARRAY_SIZE(sc_exit_table); | |
824 | @@ -713,27 +703,23 @@ int fill_table(const struct trace_syscall_entry *table, size_t table_len, | |
825 | memset(&ev, 0, sizeof(ev)); | |
826 | switch (type) { | |
827 | case SC_TYPE_ENTRY: | |
828 | - strncpy(ev.name, SYSCALL_ENTRY_STR, | |
829 | - LTTNG_KERNEL_SYM_NAME_LEN); | |
830 | + ev.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_ENTRY; | |
831 | + ev.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_NATIVE; | |
832 | break; | |
833 | case SC_TYPE_EXIT: | |
834 | - strncpy(ev.name, SYSCALL_EXIT_STR, | |
835 | - LTTNG_KERNEL_SYM_NAME_LEN); | |
836 | + ev.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_EXIT; | |
837 | + ev.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_NATIVE; | |
838 | break; | |
839 | case SC_TYPE_COMPAT_ENTRY: | |
840 | - strncpy(ev.name, COMPAT_SYSCALL_ENTRY_STR, | |
841 | - LTTNG_KERNEL_SYM_NAME_LEN); | |
842 | + ev.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_ENTRY; | |
843 | + ev.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_COMPAT; | |
844 | break; | |
845 | case SC_TYPE_COMPAT_EXIT: | |
846 | - strncpy(ev.name, COMPAT_SYSCALL_EXIT_STR, | |
847 | - LTTNG_KERNEL_SYM_NAME_LEN); | |
848 | - break; | |
849 | - default: | |
850 | - BUG_ON(1); | |
851 | + ev.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_EXIT; | |
852 | + ev.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_COMPAT; | |
853 | break; | |
854 | } | |
855 | - strncat(ev.name, desc->name, | |
856 | - LTTNG_KERNEL_SYM_NAME_LEN - strlen(ev.name) - 1); | |
857 | + strncpy(ev.name, desc->name, LTTNG_KERNEL_SYM_NAME_LEN); | |
858 | ev.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0'; | |
859 | ev.instrumentation = LTTNG_KERNEL_SYSCALL; | |
860 | chan_table[i] = _lttng_event_create(chan, &ev, filter, | |
861 | @@ -803,6 +789,8 @@ int lttng_syscalls_register(struct lttng_channel *chan, void *filter) | |
862 | strncpy(ev.name, desc->name, LTTNG_KERNEL_SYM_NAME_LEN); | |
863 | ev.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0'; | |
864 | ev.instrumentation = LTTNG_KERNEL_SYSCALL; | |
865 | + ev.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_ENTRY; | |
866 | + ev.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_NATIVE; | |
867 | chan->sc_unknown = _lttng_event_create(chan, &ev, filter, | |
868 | desc, | |
869 | ev.instrumentation); | |
870 | @@ -820,6 +808,8 @@ int lttng_syscalls_register(struct lttng_channel *chan, void *filter) | |
871 | strncpy(ev.name, desc->name, LTTNG_KERNEL_SYM_NAME_LEN); | |
872 | ev.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0'; | |
873 | ev.instrumentation = LTTNG_KERNEL_SYSCALL; | |
874 | + ev.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_ENTRY; | |
875 | + ev.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_COMPAT; | |
876 | chan->sc_compat_unknown = _lttng_event_create(chan, &ev, filter, | |
877 | desc, | |
878 | ev.instrumentation); | |
879 | @@ -837,6 +827,8 @@ int lttng_syscalls_register(struct lttng_channel *chan, void *filter) | |
880 | strncpy(ev.name, desc->name, LTTNG_KERNEL_SYM_NAME_LEN); | |
881 | ev.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0'; | |
882 | ev.instrumentation = LTTNG_KERNEL_SYSCALL; | |
883 | + ev.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_EXIT; | |
884 | + ev.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_COMPAT; | |
885 | chan->compat_sc_exit_unknown = _lttng_event_create(chan, &ev, | |
886 | filter, desc, | |
887 | ev.instrumentation); | |
888 | @@ -854,6 +846,8 @@ int lttng_syscalls_register(struct lttng_channel *chan, void *filter) | |
889 | strncpy(ev.name, desc->name, LTTNG_KERNEL_SYM_NAME_LEN); | |
890 | ev.name[LTTNG_KERNEL_SYM_NAME_LEN - 1] = '\0'; | |
891 | ev.instrumentation = LTTNG_KERNEL_SYSCALL; | |
892 | + ev.u.syscall.entryexit = LTTNG_KERNEL_SYSCALL_EXIT; | |
893 | + ev.u.syscall.abi = LTTNG_KERNEL_SYSCALL_ABI_NATIVE; | |
894 | chan->sc_exit_unknown = _lttng_event_create(chan, &ev, filter, | |
895 | desc, ev.instrumentation); | |
896 | WARN_ON_ONCE(!chan->sc_exit_unknown); | |
897 | @@ -883,6 +877,14 @@ int lttng_syscalls_register(struct lttng_channel *chan, void *filter) | |
898 | if (ret) | |
899 | return ret; | |
900 | #endif | |
901 | + | |
902 | + if (!chan->sc_filter) { | |
903 | + chan->sc_filter = kzalloc(sizeof(struct lttng_syscall_filter), | |
904 | + GFP_KERNEL); | |
905 | + if (!chan->sc_filter) | |
906 | + return -ENOMEM; | |
907 | + } | |
908 | + | |
909 | if (!chan->sys_enter_registered) { | |
910 | ret = lttng_wrapper_tracepoint_probe_register("sys_enter", | |
911 | (void *) syscall_entry_probe, chan); | |
912 | @@ -930,7 +932,11 @@ int lttng_syscalls_unregister(struct lttng_channel *chan) | |
913 | return ret; | |
914 | chan->sys_exit_registered = 0; | |
915 | } | |
916 | - /* lttng_event destroy will be performed by lttng_session_destroy() */ | |
917 | + return 0; | |
918 | +} | |
919 | + | |
920 | +int lttng_syscalls_destroy(struct lttng_channel *chan) | |
921 | +{ | |
922 | kfree(chan->sc_table); | |
923 | kfree(chan->sc_exit_table); | |
924 | #ifdef CONFIG_COMPAT | |
925 | @@ -993,136 +999,150 @@ uint32_t get_sc_tables_len(void) | |
926 | return ARRAY_SIZE(sc_table) + ARRAY_SIZE(compat_sc_table); | |
927 | } | |
928 | ||
929 | -int lttng_syscall_filter_enable(struct lttng_channel *chan, | |
930 | - const char *name) | |
931 | +static | |
932 | +const char *get_syscall_name(struct lttng_event *event) | |
933 | { | |
934 | - int syscall_nr, compat_syscall_nr, ret; | |
935 | - struct lttng_syscall_filter *filter; | |
936 | + size_t prefix_len = 0; | |
937 | ||
938 | - WARN_ON_ONCE(!chan->sc_table); | |
939 | + WARN_ON_ONCE(event->instrumentation != LTTNG_KERNEL_SYSCALL); | |
940 | ||
941 | - if (!name) { | |
942 | - /* Enable all system calls by removing filter */ | |
943 | - if (chan->sc_filter) { | |
944 | - filter = chan->sc_filter; | |
945 | - rcu_assign_pointer(chan->sc_filter, NULL); | |
946 | - synchronize_trace(); | |
947 | - kfree(filter); | |
948 | + switch (event->u.syscall.entryexit) { | |
949 | + case LTTNG_SYSCALL_ENTRY: | |
950 | + switch (event->u.syscall.abi) { | |
951 | + case LTTNG_SYSCALL_ABI_NATIVE: | |
952 | + prefix_len = strlen(SYSCALL_ENTRY_STR); | |
953 | + break; | |
954 | + case LTTNG_SYSCALL_ABI_COMPAT: | |
955 | + prefix_len = strlen(COMPAT_SYSCALL_ENTRY_STR); | |
956 | + break; | |
957 | } | |
958 | - chan->syscall_all = 1; | |
959 | - return 0; | |
960 | - } | |
961 | - | |
962 | - if (!chan->sc_filter) { | |
963 | - if (chan->syscall_all) { | |
964 | - /* | |
965 | - * All syscalls are already enabled. | |
966 | - */ | |
967 | - return -EEXIST; | |
968 | + break; | |
969 | + case LTTNG_SYSCALL_EXIT: | |
970 | + switch (event->u.syscall.abi) { | |
971 | + case LTTNG_SYSCALL_ABI_NATIVE: | |
972 | + prefix_len = strlen(SYSCALL_EXIT_STR); | |
973 | + break; | |
974 | + case LTTNG_SYSCALL_ABI_COMPAT: | |
975 | + prefix_len = strlen(COMPAT_SYSCALL_EXIT_STR); | |
976 | + break; | |
977 | } | |
978 | - filter = kzalloc(sizeof(struct lttng_syscall_filter), | |
979 | - GFP_KERNEL); | |
980 | - if (!filter) | |
981 | - return -ENOMEM; | |
982 | - } else { | |
983 | - filter = chan->sc_filter; | |
984 | + break; | |
985 | } | |
986 | - syscall_nr = get_syscall_nr(name); | |
987 | - compat_syscall_nr = get_compat_syscall_nr(name); | |
988 | - if (syscall_nr < 0 && compat_syscall_nr < 0) { | |
989 | - ret = -ENOENT; | |
990 | - goto error; | |
991 | + WARN_ON_ONCE(prefix_len == 0); | |
992 | + return event->desc->name + prefix_len; | |
993 | +} | |
994 | + | |
995 | +int lttng_syscall_filter_enable(struct lttng_channel *chan, | |
996 | + struct lttng_event *event) | |
997 | +{ | |
998 | + struct lttng_syscall_filter *filter = chan->sc_filter; | |
999 | + const char *syscall_name; | |
1000 | + unsigned long *bitmap; | |
1001 | + int syscall_nr; | |
1002 | + | |
1003 | + WARN_ON_ONCE(!chan->sc_table); | |
1004 | + | |
1005 | + syscall_name = get_syscall_name(event); | |
1006 | + | |
1007 | + switch (event->u.syscall.abi) { | |
1008 | + case LTTNG_SYSCALL_ABI_NATIVE: | |
1009 | + syscall_nr = get_syscall_nr(syscall_name); | |
1010 | + break; | |
1011 | + case LTTNG_SYSCALL_ABI_COMPAT: | |
1012 | + syscall_nr = get_compat_syscall_nr(syscall_name); | |
1013 | + break; | |
1014 | + default: | |
1015 | + return -EINVAL; | |
1016 | } | |
1017 | - if (syscall_nr >= 0) { | |
1018 | - if (test_bit(syscall_nr, filter->sc)) { | |
1019 | - ret = -EEXIST; | |
1020 | - goto error; | |
1021 | + if (syscall_nr < 0) | |
1022 | + return -ENOENT; | |
1023 | + | |
1024 | + | |
1025 | + switch (event->u.syscall.entryexit) { | |
1026 | + case LTTNG_SYSCALL_ENTRY: | |
1027 | + switch (event->u.syscall.abi) { | |
1028 | + case LTTNG_SYSCALL_ABI_NATIVE: | |
1029 | + bitmap = filter->sc_entry; | |
1030 | + break; | |
1031 | + case LTTNG_SYSCALL_ABI_COMPAT: | |
1032 | + bitmap = filter->sc_compat_entry; | |
1033 | + break; | |
1034 | } | |
1035 | - bitmap_set(filter->sc, syscall_nr, 1); | |
1036 | - } | |
1037 | - if (compat_syscall_nr >= 0) { | |
1038 | - if (test_bit(compat_syscall_nr, filter->sc_compat)) { | |
1039 | - ret = -EEXIST; | |
1040 | - goto error; | |
1041 | + break; | |
1042 | + case LTTNG_SYSCALL_EXIT: | |
1043 | + switch (event->u.syscall.abi) { | |
1044 | + case LTTNG_SYSCALL_ABI_NATIVE: | |
1045 | + bitmap = filter->sc_exit; | |
1046 | + break; | |
1047 | + case LTTNG_SYSCALL_ABI_COMPAT: | |
1048 | + bitmap = filter->sc_compat_exit; | |
1049 | + break; | |
1050 | } | |
1051 | - bitmap_set(filter->sc_compat, compat_syscall_nr, 1); | |
1052 | + break; | |
1053 | + default: | |
1054 | + return -EINVAL; | |
1055 | } | |
1056 | - if (!chan->sc_filter) | |
1057 | - rcu_assign_pointer(chan->sc_filter, filter); | |
1058 | + if (test_bit(syscall_nr, bitmap)) | |
1059 | + return -EEXIST; | |
1060 | + bitmap_set(bitmap, syscall_nr, 1); | |
1061 | return 0; | |
1062 | - | |
1063 | -error: | |
1064 | - if (!chan->sc_filter) | |
1065 | - kfree(filter); | |
1066 | - return ret; | |
1067 | } | |
1068 | ||
1069 | int lttng_syscall_filter_disable(struct lttng_channel *chan, | |
1070 | - const char *name) | |
1071 | + struct lttng_event *event) | |
1072 | { | |
1073 | - int syscall_nr, compat_syscall_nr, ret; | |
1074 | - struct lttng_syscall_filter *filter; | |
1075 | + struct lttng_syscall_filter *filter = chan->sc_filter; | |
1076 | + const char *syscall_name; | |
1077 | + unsigned long *bitmap; | |
1078 | + int syscall_nr; | |
1079 | ||
1080 | WARN_ON_ONCE(!chan->sc_table); | |
1081 | ||
1082 | - if (!chan->sc_filter) { | |
1083 | - if (!chan->syscall_all) | |
1084 | - return -EEXIST; | |
1085 | - filter = kzalloc(sizeof(struct lttng_syscall_filter), | |
1086 | - GFP_KERNEL); | |
1087 | - if (!filter) | |
1088 | - return -ENOMEM; | |
1089 | - /* Trace all system calls, then apply disable. */ | |
1090 | - bitmap_set(filter->sc, 0, NR_syscalls); | |
1091 | - bitmap_set(filter->sc_compat, 0, NR_compat_syscalls); | |
1092 | - } else { | |
1093 | - filter = chan->sc_filter; | |
1094 | + syscall_name = get_syscall_name(event); | |
1095 | + | |
1096 | + switch (event->u.syscall.abi) { | |
1097 | + case LTTNG_SYSCALL_ABI_NATIVE: | |
1098 | + syscall_nr = get_syscall_nr(syscall_name); | |
1099 | + break; | |
1100 | + case LTTNG_SYSCALL_ABI_COMPAT: | |
1101 | + syscall_nr = get_compat_syscall_nr(syscall_name); | |
1102 | + break; | |
1103 | + default: | |
1104 | + return -EINVAL; | |
1105 | } | |
1106 | + if (syscall_nr < 0) | |
1107 | + return -ENOENT; | |
1108 | ||
1109 | - if (!name) { | |
1110 | - /* Fail if all syscalls are already disabled. */ | |
1111 | - if (bitmap_empty(filter->sc, NR_syscalls) | |
1112 | - && bitmap_empty(filter->sc_compat, | |
1113 | - NR_compat_syscalls)) { | |
1114 | - ret = -EEXIST; | |
1115 | - goto error; | |
1116 | - } | |
1117 | ||
1118 | - /* Disable all system calls */ | |
1119 | - bitmap_clear(filter->sc, 0, NR_syscalls); | |
1120 | - bitmap_clear(filter->sc_compat, 0, NR_compat_syscalls); | |
1121 | - goto apply_filter; | |
1122 | - } | |
1123 | - syscall_nr = get_syscall_nr(name); | |
1124 | - compat_syscall_nr = get_compat_syscall_nr(name); | |
1125 | - if (syscall_nr < 0 && compat_syscall_nr < 0) { | |
1126 | - ret = -ENOENT; | |
1127 | - goto error; | |
1128 | - } | |
1129 | - if (syscall_nr >= 0) { | |
1130 | - if (!test_bit(syscall_nr, filter->sc)) { | |
1131 | - ret = -EEXIST; | |
1132 | - goto error; | |
1133 | + switch (event->u.syscall.entryexit) { | |
1134 | + case LTTNG_SYSCALL_ENTRY: | |
1135 | + switch (event->u.syscall.abi) { | |
1136 | + case LTTNG_SYSCALL_ABI_NATIVE: | |
1137 | + bitmap = filter->sc_entry; | |
1138 | + break; | |
1139 | + case LTTNG_SYSCALL_ABI_COMPAT: | |
1140 | + bitmap = filter->sc_compat_entry; | |
1141 | + break; | |
1142 | } | |
1143 | - bitmap_clear(filter->sc, syscall_nr, 1); | |
1144 | - } | |
1145 | - if (compat_syscall_nr >= 0) { | |
1146 | - if (!test_bit(compat_syscall_nr, filter->sc_compat)) { | |
1147 | - ret = -EEXIST; | |
1148 | - goto error; | |
1149 | + break; | |
1150 | + case LTTNG_SYSCALL_EXIT: | |
1151 | + switch (event->u.syscall.abi) { | |
1152 | + case LTTNG_SYSCALL_ABI_NATIVE: | |
1153 | + bitmap = filter->sc_exit; | |
1154 | + break; | |
1155 | + case LTTNG_SYSCALL_ABI_COMPAT: | |
1156 | + bitmap = filter->sc_compat_exit; | |
1157 | + break; | |
1158 | } | |
1159 | - bitmap_clear(filter->sc_compat, compat_syscall_nr, 1); | |
1160 | + break; | |
1161 | + default: | |
1162 | + return -EINVAL; | |
1163 | } | |
1164 | -apply_filter: | |
1165 | - if (!chan->sc_filter) | |
1166 | - rcu_assign_pointer(chan->sc_filter, filter); | |
1167 | - chan->syscall_all = 0; | |
1168 | - return 0; | |
1169 | + if (!test_bit(syscall_nr, bitmap)) | |
1170 | + return -EEXIST; | |
1171 | + bitmap_clear(bitmap, syscall_nr, 1); | |
1172 | ||
1173 | -error: | |
1174 | - if (!chan->sc_filter) | |
1175 | - kfree(filter); | |
1176 | - return ret; | |
1177 | + return 0; | |
1178 | } | |
1179 | ||
1180 | static | |
1181 | @@ -1236,6 +1256,9 @@ const struct file_operations lttng_syscall_list_fops = { | |
1182 | .release = seq_release, | |
1183 | }; | |
1184 | ||
1185 | +/* | |
1186 | + * A syscall is enabled if it is traced for either entry or exit. | |
1187 | + */ | |
1188 | long lttng_channel_syscall_mask(struct lttng_channel *channel, | |
1189 | struct lttng_kernel_syscall_mask __user *usyscall_mask) | |
1190 | { | |
1191 | @@ -1262,8 +1285,9 @@ long lttng_channel_syscall_mask(struct lttng_channel *channel, | |
1192 | char state; | |
1193 | ||
1194 | if (channel->sc_table) { | |
1195 | - if (filter) | |
1196 | - state = test_bit(bit, filter->sc); | |
1197 | + if (!READ_ONCE(channel->syscall_all) && filter) | |
1198 | + state = test_bit(bit, filter->sc_entry) | |
1199 | + || test_bit(bit, filter->sc_exit); | |
1200 | else | |
1201 | state = 1; | |
1202 | } else { | |
1203 | @@ -1275,9 +1299,11 @@ long lttng_channel_syscall_mask(struct lttng_channel *channel, | |
1204 | char state; | |
1205 | ||
1206 | if (channel->compat_sc_table) { | |
1207 | - if (filter) | |
1208 | + if (!READ_ONCE(channel->syscall_all) && filter) | |
1209 | state = test_bit(bit - ARRAY_SIZE(sc_table), | |
1210 | - filter->sc_compat); | |
1211 | + filter->sc_compat_entry) | |
1212 | + || test_bit(bit - ARRAY_SIZE(sc_table), | |
1213 | + filter->sc_compat_exit); | |
1214 | else | |
1215 | state = 1; | |
1216 | } else { | |
1217 | diff --git a/probes/lttng-kprobes.c b/probes/lttng-kprobes.c | |
1218 | index a44eaa1..38fb72e 100644 | |
1219 | --- a/probes/lttng-kprobes.c | |
1220 | +++ b/probes/lttng-kprobes.c | |
1221 | @@ -31,11 +31,11 @@ int lttng_kprobes_handler_pre(struct kprobe *p, struct pt_regs *regs) | |
1222 | int ret; | |
1223 | unsigned long data = (unsigned long) p->addr; | |
1224 | ||
1225 | - if (unlikely(!READ_ONCE(chan->session->active))) | |
1226 | + if (unlikely(!LTTNG_READ_ONCE(chan->session->active))) | |
1227 | return 0; | |
1228 | - if (unlikely(!READ_ONCE(chan->enabled))) | |
1229 | + if (unlikely(!LTTNG_READ_ONCE(chan->enabled))) | |
1230 | return 0; | |
1231 | - if (unlikely(!READ_ONCE(event->enabled))) | |
1232 | + if (unlikely(!LTTNG_READ_ONCE(event->enabled))) | |
1233 | return 0; | |
1234 | ||
1235 | lib_ring_buffer_ctx_init(&ctx, chan->chan, <tng_probe_ctx, sizeof(data), | |
1236 | diff --git a/probes/lttng-kretprobes.c b/probes/lttng-kretprobes.c | |
1237 | index ab98ff2..a6bcd21 100644 | |
1238 | --- a/probes/lttng-kretprobes.c | |
1239 | +++ b/probes/lttng-kretprobes.c | |
1240 | @@ -51,11 +51,11 @@ int _lttng_kretprobes_handler(struct kretprobe_instance *krpi, | |
1241 | unsigned long parent_ip; | |
1242 | } payload; | |
1243 | ||
1244 | - if (unlikely(!READ_ONCE(chan->session->active))) | |
1245 | + if (unlikely(!LTTNG_READ_ONCE(chan->session->active))) | |
1246 | return 0; | |
1247 | - if (unlikely(!READ_ONCE(chan->enabled))) | |
1248 | + if (unlikely(!LTTNG_READ_ONCE(chan->enabled))) | |
1249 | return 0; | |
1250 | - if (unlikely(!READ_ONCE(event->enabled))) | |
1251 | + if (unlikely(!LTTNG_READ_ONCE(event->enabled))) | |
1252 | return 0; | |
1253 | ||
1254 | payload.ip = (unsigned long) krpi->rp->kp.addr; | |
1255 | diff --git a/probes/lttng-probe-kvm-x86-mmu.c b/probes/lttng-probe-kvm-x86-mmu.c | |
1256 | index 37384a2..8f98186 100644 | |
1257 | --- a/probes/lttng-probe-kvm-x86-mmu.c | |
1258 | +++ b/probes/lttng-probe-kvm-x86-mmu.c | |
1259 | @@ -24,7 +24,12 @@ | |
1260 | */ | |
1261 | #include <wrapper/tracepoint.h> | |
1262 | ||
1263 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,9,0)) | |
1264 | +#include <../../arch/x86/kvm/mmu/mmu_internal.h> | |
1265 | +#include <../../arch/x86/kvm/mmu/mmutrace.h> | |
1266 | +#else | |
1267 | #include <../../arch/x86/kvm/mmutrace.h> | |
1268 | +#endif | |
1269 | ||
1270 | #undef TRACE_INCLUDE_PATH | |
1271 | #undef TRACE_INCLUDE_FILE | |
1272 | diff --git a/probes/lttng-tracepoint-event-impl.h b/probes/lttng-tracepoint-event-impl.h | |
1273 | index 77b8638..72a669e 100644 | |
1274 | --- a/probes/lttng-tracepoint-event-impl.h | |
1275 | +++ b/probes/lttng-tracepoint-event-impl.h | |
1276 | @@ -1132,11 +1132,11 @@ static void __event_probe__##_name(void *__data, _proto) \ | |
1277 | \ | |
1278 | if (!_TP_SESSION_CHECK(session, __session)) \ | |
1279 | return; \ | |
1280 | - if (unlikely(!READ_ONCE(__session->active))) \ | |
1281 | + if (unlikely(!LTTNG_READ_ONCE(__session->active))) \ | |
1282 | return; \ | |
1283 | - if (unlikely(!READ_ONCE(__chan->enabled))) \ | |
1284 | + if (unlikely(!LTTNG_READ_ONCE(__chan->enabled))) \ | |
1285 | return; \ | |
1286 | - if (unlikely(!READ_ONCE(__event->enabled))) \ | |
1287 | + if (unlikely(!LTTNG_READ_ONCE(__event->enabled))) \ | |
1288 | return; \ | |
1289 | __lf = lttng_rcu_dereference(__session->pid_tracker.p); \ | |
1290 | if (__lf && likely(!lttng_id_tracker_lookup(__lf, current->tgid))) \ | |
1291 | @@ -1225,11 +1225,11 @@ static void __event_probe__##_name(void *__data) \ | |
1292 | \ | |
1293 | if (!_TP_SESSION_CHECK(session, __session)) \ | |
1294 | return; \ | |
1295 | - if (unlikely(!READ_ONCE(__session->active))) \ | |
1296 | + if (unlikely(!LTTNG_READ_ONCE(__session->active))) \ | |
1297 | return; \ | |
1298 | - if (unlikely(!READ_ONCE(__chan->enabled))) \ | |
1299 | + if (unlikely(!LTTNG_READ_ONCE(__chan->enabled))) \ | |
1300 | return; \ | |
1301 | - if (unlikely(!READ_ONCE(__event->enabled))) \ | |
1302 | + if (unlikely(!LTTNG_READ_ONCE(__event->enabled))) \ | |
1303 | return; \ | |
1304 | __lf = lttng_rcu_dereference(__session->pid_tracker.p); \ | |
1305 | if (__lf && likely(!lttng_id_tracker_lookup(__lf, current->tgid))) \ | |
1306 | diff --git a/probes/lttng-uprobes.c b/probes/lttng-uprobes.c | |
1307 | index bc10128..bda1d9b 100644 | |
1308 | --- a/probes/lttng-uprobes.c | |
1309 | +++ b/probes/lttng-uprobes.c | |
1310 | @@ -40,11 +40,11 @@ int lttng_uprobes_handler_pre(struct uprobe_consumer *uc, struct pt_regs *regs) | |
1311 | unsigned long ip; | |
1312 | } payload; | |
1313 | ||
1314 | - if (unlikely(!READ_ONCE(chan->session->active))) | |
1315 | + if (unlikely(!LTTNG_READ_ONCE(chan->session->active))) | |
1316 | return 0; | |
1317 | - if (unlikely(!READ_ONCE(chan->enabled))) | |
1318 | + if (unlikely(!LTTNG_READ_ONCE(chan->enabled))) | |
1319 | return 0; | |
1320 | - if (unlikely(!READ_ONCE(event->enabled))) | |
1321 | + if (unlikely(!LTTNG_READ_ONCE(event->enabled))) | |
1322 | return 0; | |
1323 | ||
1324 | lib_ring_buffer_ctx_init(&ctx, chan->chan, <tng_probe_ctx, | |
1325 | diff --git a/wrapper/compiler.h b/wrapper/compiler.h | |
1326 | index 1496f33..b9f8c51 100644 | |
1327 | --- a/wrapper/compiler.h | |
1328 | +++ b/wrapper/compiler.h | |
1329 | @@ -9,6 +9,7 @@ | |
1330 | #define _LTTNG_WRAPPER_COMPILER_H | |
1331 | ||
1332 | #include <linux/compiler.h> | |
1333 | +#include <linux/version.h> | |
1334 | ||
1335 | /* | |
1336 | * Don't allow compiling with buggy compiler. | |
1337 | @@ -39,4 +40,21 @@ | |
1338 | # define WRITE_ONCE(x, val) ({ ACCESS_ONCE(x) = val; }) | |
1339 | #endif | |
1340 | ||
1341 | +/* | |
1342 | + * In v4.15 a smp read barrier was added to READ_ONCE to replace | |
1343 | + * lockless_dereference(), replicate this behavior on prior kernels | |
1344 | + * and remove calls to smp_read_barrier_depends which was dropped | |
1345 | + * in v5.9. | |
1346 | + */ | |
1347 | +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,15,0)) | |
1348 | +#define LTTNG_READ_ONCE(x) READ_ONCE(x) | |
1349 | +#else | |
1350 | +#define LTTNG_READ_ONCE(x) \ | |
1351 | +({ \ | |
1352 | + typeof(x) __val = READ_ONCE(x); \ | |
1353 | + smp_read_barrier_depends(); \ | |
1354 | + __val; \ | |
1355 | +}) | |
1356 | +#endif | |
1357 | + | |
1358 | #endif /* _LTTNG_WRAPPER_COMPILER_H */ | |
1359 | diff --git a/wrapper/trace-clock.h b/wrapper/trace-clock.h | |
1360 | index 9f4e366..187fc82 100644 | |
1361 | --- a/wrapper/trace-clock.h | |
1362 | +++ b/wrapper/trace-clock.h | |
1363 | @@ -160,33 +160,30 @@ static inline void put_trace_clock(void) | |
1364 | ||
1365 | static inline u64 trace_clock_read64(void) | |
1366 | { | |
1367 | - struct lttng_trace_clock *ltc = READ_ONCE(lttng_trace_clock); | |
1368 | + struct lttng_trace_clock *ltc = LTTNG_READ_ONCE(lttng_trace_clock); | |
1369 | ||
1370 | if (likely(!ltc)) { | |
1371 | return trace_clock_read64_monotonic(); | |
1372 | } else { | |
1373 | - read_barrier_depends(); /* load ltc before content */ | |
1374 | return ltc->read64(); | |
1375 | } | |
1376 | } | |
1377 | ||
1378 | static inline u64 trace_clock_freq(void) | |
1379 | { | |
1380 | - struct lttng_trace_clock *ltc = READ_ONCE(lttng_trace_clock); | |
1381 | + struct lttng_trace_clock *ltc = LTTNG_READ_ONCE(lttng_trace_clock); | |
1382 | ||
1383 | if (!ltc) { | |
1384 | return trace_clock_freq_monotonic(); | |
1385 | } else { | |
1386 | - read_barrier_depends(); /* load ltc before content */ | |
1387 | return ltc->freq(); | |
1388 | } | |
1389 | } | |
1390 | ||
1391 | static inline int trace_clock_uuid(char *uuid) | |
1392 | { | |
1393 | - struct lttng_trace_clock *ltc = READ_ONCE(lttng_trace_clock); | |
1394 | + struct lttng_trace_clock *ltc = LTTNG_READ_ONCE(lttng_trace_clock); | |
1395 | ||
1396 | - read_barrier_depends(); /* load ltc before content */ | |
1397 | /* Use default UUID cb when NULL */ | |
1398 | if (!ltc || !ltc->uuid) { | |
1399 | return trace_clock_uuid_monotonic(uuid); | |
1400 | @@ -197,24 +194,22 @@ static inline int trace_clock_uuid(char *uuid) | |
1401 | ||
1402 | static inline const char *trace_clock_name(void) | |
1403 | { | |
1404 | - struct lttng_trace_clock *ltc = READ_ONCE(lttng_trace_clock); | |
1405 | + struct lttng_trace_clock *ltc = LTTNG_READ_ONCE(lttng_trace_clock); | |
1406 | ||
1407 | if (!ltc) { | |
1408 | return trace_clock_name_monotonic(); | |
1409 | } else { | |
1410 | - read_barrier_depends(); /* load ltc before content */ | |
1411 | return ltc->name(); | |
1412 | } | |
1413 | } | |
1414 | ||
1415 | static inline const char *trace_clock_description(void) | |
1416 | { | |
1417 | - struct lttng_trace_clock *ltc = READ_ONCE(lttng_trace_clock); | |
1418 | + struct lttng_trace_clock *ltc = LTTNG_READ_ONCE(lttng_trace_clock); | |
1419 | ||
1420 | if (!ltc) { | |
1421 | return trace_clock_description_monotonic(); | |
1422 | } else { | |
1423 | - read_barrier_depends(); /* load ltc before content */ | |
1424 | return ltc->description(); | |
1425 | } | |
1426 | } |