Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

tracepoint: Remove SRCU protection

With the removal of the trace_*_rcuidle() tracepoints, there is no reason
to protect tracepoints with SRCU. The reason the SRCU protection was
added, was because it can protect tracepoints when RCU is not "watching".
Now that tracepoints are only used when RCU is watching, remove the SRCU
protection. It just made things more complex and confusing anyway.

Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Joel Fernandes <joel@joelfernandes.org>
Link: https://lore.kernel.org/20241003184220.0dc21d35@gandalf.local.home
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>

+1 -54
-4
include/linux/tracepoint.h
··· 32 32 33 33 #define TRACEPOINT_DEFAULT_PRIO 10 34 34 35 - extern struct srcu_struct tracepoint_srcu; 36 - 37 35 extern int 38 36 tracepoint_probe_register(struct tracepoint *tp, void *probe, void *data); 39 37 extern int ··· 107 109 #ifdef CONFIG_TRACEPOINTS 108 110 static inline void tracepoint_synchronize_unregister(void) 109 111 { 110 - synchronize_srcu(&tracepoint_srcu); 111 112 synchronize_rcu(); 112 113 } 113 114 #else ··· 204 207 if (!(cond)) \ 205 208 return; \ 206 209 \ 207 - /* keep srcu and sched-rcu usage consistent */ \ 208 210 preempt_disable_notrace(); \ 209 211 \ 210 212 __DO_TRACE_CALL(name, TP_ARGS(args)); \
+1 -50
kernel/tracepoint.c
··· 25 25 extern tracepoint_ptr_t __start___tracepoints_ptrs[]; 26 26 extern tracepoint_ptr_t __stop___tracepoints_ptrs[]; 27 27 28 - DEFINE_SRCU(tracepoint_srcu); 29 - EXPORT_SYMBOL_GPL(tracepoint_srcu); 30 - 31 28 enum tp_transition_sync { 32 29 TP_TRANSITION_SYNC_1_0_1, 33 30 TP_TRANSITION_SYNC_N_2_1, ··· 34 37 35 38 struct tp_transition_snapshot { 36 39 unsigned long rcu; 37 - unsigned long srcu; 38 40 bool ongoing; 39 41 }; 40 42 ··· 46 50 47 51 /* Keep the latest get_state snapshot. */ 48 52 snapshot->rcu = get_state_synchronize_rcu(); 49 - snapshot->srcu = start_poll_synchronize_srcu(&tracepoint_srcu); 50 53 snapshot->ongoing = true; 51 54 } 52 55 ··· 56 61 if (!snapshot->ongoing) 57 62 return; 58 63 cond_synchronize_rcu(snapshot->rcu); 59 - if (!poll_state_synchronize_srcu(&tracepoint_srcu, snapshot->srcu)) 60 - synchronize_srcu(&tracepoint_srcu); 61 64 snapshot->ongoing = false; 62 65 } 63 66 ··· 77 84 * tracepoints_mutex nests inside tracepoint_module_list_mutex. 78 85 */ 79 86 static DEFINE_MUTEX(tracepoints_mutex); 80 - 81 - static struct rcu_head *early_probes; 82 - static bool ok_to_free_tracepoints; 83 87 84 88 /* 85 89 * Note about RCU : ··· 101 111 return p == NULL ? NULL : p->probes; 102 112 } 103 113 104 - static void srcu_free_old_probes(struct rcu_head *head) 114 + static void rcu_free_old_probes(struct rcu_head *head) 105 115 { 106 116 kfree(container_of(head, struct tp_probes, rcu)); 107 117 } 108 - 109 - static void rcu_free_old_probes(struct rcu_head *head) 110 - { 111 - call_srcu(&tracepoint_srcu, head, srcu_free_old_probes); 112 - } 113 - 114 - static __init int release_early_probes(void) 115 - { 116 - struct rcu_head *tmp; 117 - 118 - ok_to_free_tracepoints = true; 119 - 120 - while (early_probes) { 121 - tmp = early_probes; 122 - early_probes = tmp->next; 123 - call_rcu(tmp, rcu_free_old_probes); 124 - } 125 - 126 - return 0; 127 - } 128 - 129 - /* SRCU is initialized at core_initcall */ 130 - postcore_initcall(release_early_probes); 131 118 132 119 static inline void release_probes(struct tracepoint_func *old) 133 120 { ··· 112 145 struct tp_probes *tp_probes = container_of(old, 113 146 struct tp_probes, probes[0]); 114 147 115 - /* 116 - * We can't free probes if SRCU is not initialized yet. 117 - * Postpone the freeing till after SRCU is initialized. 118 - */ 119 - if (unlikely(!ok_to_free_tracepoints)) { 120 - tp_probes->rcu.next = early_probes; 121 - early_probes = &tp_probes->rcu; 122 - return; 123 - } 124 - 125 - /* 126 - * Tracepoint probes are protected by both sched RCU and SRCU, 127 - * by calling the SRCU callback in the sched RCU callback we 128 - * cover both cases. So let us chain the SRCU and sched RCU 129 - * callbacks to wait for both grace periods. 130 - */ 131 148 call_rcu(&tp_probes->rcu, rcu_free_old_probes); 132 149 } 133 150 }