Commit | Line | Data |
---|---|---|
b7cdc182 | 1 | /* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only) |
9f36eaed | 2 | * |
7a09dcb7 MD |
3 | * wrapper/rcu.h |
4 | * | |
5 | * wrapper around linux/rcupdate.h and linux/rculist.h. | |
6 | * | |
7 | * Copyright (C) 2014 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | |
7a09dcb7 MD |
8 | */ |
9 | ||
9f36eaed MJ |
10 | #ifndef _LTTNG_WRAPPER_RCU_H |
11 | #define _LTTNG_WRAPPER_RCU_H | |
12 | ||
7a09dcb7 MD |
13 | #include <linux/version.h> |
14 | #include <linux/rculist.h> | |
15 | #include <linux/rcupdate.h> | |
5a2f5e92 | 16 | #include <wrapper/list.h> |
7a09dcb7 MD |
17 | |
18 | #ifndef rcu_dereference_raw_notrace | |
19 | #define rcu_dereference_raw_notrace(p) rcu_dereference_raw(p) | |
20 | #endif | |
21 | ||
22 | #define lttng_rcu_dereference(p) rcu_dereference_raw_notrace(p) | |
23 | ||
24 | /** | |
25 | * lttng_list_entry_rcu - get the struct for this entry | |
26 | * @ptr: the &struct list_head pointer. | |
27 | * @type: the type of the struct this is embedded in. | |
28 | * @member: the name of the list_head within the struct. | |
29 | * | |
30 | * This primitive may safely run concurrently with the _rcu list-mutation | |
31 | * primitives such as list_add_rcu() as long as it's guarded by | |
32 | * rcu_read_lock_sched(). | |
33 | * Can be used while tracing RCU. | |
34 | */ | |
35 | #define lttng_list_entry_rcu(ptr, type, member) \ | |
36 | ({ \ | |
37 | typeof(*ptr) __rcu *__ptr = (typeof(*ptr) __rcu __force *)ptr; \ | |
38 | container_of((typeof(ptr))lttng_rcu_dereference(__ptr), type, member); \ | |
39 | }) | |
40 | ||
41 | /** | |
42 | * lttng_list_for_each_entry_rcu - iterate over rcu list of given type | |
43 | * @pos: the type * to use as a loop cursor. | |
44 | * @head: the head for your list. | |
45 | * @member: the name of the list_head within the struct. | |
46 | * | |
47 | * This list-traversal primitive may safely run concurrently with | |
48 | * the _rcu list-mutation primitives such as list_add_rcu() | |
49 | * as long as the traversal is guarded by rcu_read_lock_sched(). | |
50 | * Can be used while tracing RCU. | |
51 | */ | |
52 | #define lttng_list_for_each_entry_rcu(pos, head, member) \ | |
53 | for (pos = lttng_list_entry_rcu((head)->next, typeof(*pos), member); \ | |
54 | &pos->member != (head); \ | |
55 | pos = lttng_list_entry_rcu(pos->member.next, typeof(*pos), member)) | |
56 | ||
57 | /** | |
58 | * lttng_hlist_for_each_entry_rcu - iterate over rcu list of given type (for tracing) | |
59 | * @pos: the type * to use as a loop cursor. | |
60 | * @head: the head for your list. | |
61 | * @member: the name of the hlist_node within the struct. | |
62 | * | |
63 | * This list-traversal primitive may safely run concurrently with | |
64 | * the _rcu list-mutation primitives such as hlist_add_head_rcu() | |
65 | * as long as the traversal is guarded by rcu_read_lock(). | |
66 | * | |
67 | * This is the same as hlist_for_each_entry_rcu() except that it does | |
68 | * not do any RCU debugging or tracing. | |
69 | */ | |
70 | #define lttng_hlist_for_each_entry_rcu(pos, head, member) \ | |
ac5d8d00 | 71 | for (pos = lttng_hlist_entry_safe (lttng_rcu_dereference(lttng_hlist_first_rcu(head)), \ |
7a09dcb7 MD |
72 | typeof(*(pos)), member); \ |
73 | pos; \ | |
ac5d8d00 | 74 | pos = lttng_hlist_entry_safe(lttng_rcu_dereference(lttng_hlist_next_rcu( \ |
7a09dcb7 MD |
75 | &(pos)->member)), typeof(*(pos)), member)) |
76 | ||
77 | #endif /* _LTTNG_WRAPPER_RCU_H */ |