xref: /linux-6.15/kernel/rcu/srcutree.c (revision dad81a20)
1*dad81a20SPaul E. McKenney /*
2*dad81a20SPaul E. McKenney  * Sleepable Read-Copy Update mechanism for mutual exclusion.
3*dad81a20SPaul E. McKenney  *
4*dad81a20SPaul E. McKenney  * This program is free software; you can redistribute it and/or modify
5*dad81a20SPaul E. McKenney  * it under the terms of the GNU General Public License as published by
6*dad81a20SPaul E. McKenney  * the Free Software Foundation; either version 2 of the License, or
7*dad81a20SPaul E. McKenney  * (at your option) any later version.
8*dad81a20SPaul E. McKenney  *
9*dad81a20SPaul E. McKenney  * This program is distributed in the hope that it will be useful,
10*dad81a20SPaul E. McKenney  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11*dad81a20SPaul E. McKenney  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12*dad81a20SPaul E. McKenney  * GNU General Public License for more details.
13*dad81a20SPaul E. McKenney  *
14*dad81a20SPaul E. McKenney  * You should have received a copy of the GNU General Public License
15*dad81a20SPaul E. McKenney  * along with this program; if not, you can access it online at
16*dad81a20SPaul E. McKenney  * http://www.gnu.org/licenses/gpl-2.0.html.
17*dad81a20SPaul E. McKenney  *
18*dad81a20SPaul E. McKenney  * Copyright (C) IBM Corporation, 2006
19*dad81a20SPaul E. McKenney  * Copyright (C) Fujitsu, 2012
20*dad81a20SPaul E. McKenney  *
21*dad81a20SPaul E. McKenney  * Author: Paul McKenney <[email protected]>
22*dad81a20SPaul E. McKenney  *	   Lai Jiangshan <[email protected]>
23*dad81a20SPaul E. McKenney  *
24*dad81a20SPaul E. McKenney  * For detailed explanation of Read-Copy Update mechanism see -
25*dad81a20SPaul E. McKenney  *		Documentation/RCU/ *.txt
26*dad81a20SPaul E. McKenney  *
27*dad81a20SPaul E. McKenney  */
28*dad81a20SPaul E. McKenney 
29*dad81a20SPaul E. McKenney #include <linux/export.h>
30*dad81a20SPaul E. McKenney #include <linux/mutex.h>
31*dad81a20SPaul E. McKenney #include <linux/percpu.h>
32*dad81a20SPaul E. McKenney #include <linux/preempt.h>
33*dad81a20SPaul E. McKenney #include <linux/rcupdate_wait.h>
34*dad81a20SPaul E. McKenney #include <linux/sched.h>
35*dad81a20SPaul E. McKenney #include <linux/smp.h>
36*dad81a20SPaul E. McKenney #include <linux/delay.h>
37*dad81a20SPaul E. McKenney #include <linux/srcu.h>
38*dad81a20SPaul E. McKenney 
39*dad81a20SPaul E. McKenney #include <linux/rcu_node_tree.h>
40*dad81a20SPaul E. McKenney #include "rcu.h"
41*dad81a20SPaul E. McKenney 
42*dad81a20SPaul E. McKenney static int init_srcu_struct_fields(struct srcu_struct *sp)
43*dad81a20SPaul E. McKenney {
44*dad81a20SPaul E. McKenney 	sp->completed = 0;
45*dad81a20SPaul E. McKenney 	sp->srcu_gp_seq = 0;
46*dad81a20SPaul E. McKenney 	atomic_set(&sp->srcu_exp_cnt, 0);
47*dad81a20SPaul E. McKenney 	spin_lock_init(&sp->queue_lock);
48*dad81a20SPaul E. McKenney 	rcu_segcblist_init(&sp->srcu_cblist);
49*dad81a20SPaul E. McKenney 	INIT_DELAYED_WORK(&sp->work, process_srcu);
50*dad81a20SPaul E. McKenney 	sp->per_cpu_ref = alloc_percpu(struct srcu_array);
51*dad81a20SPaul E. McKenney 	return sp->per_cpu_ref ? 0 : -ENOMEM;
52*dad81a20SPaul E. McKenney }
53*dad81a20SPaul E. McKenney 
54*dad81a20SPaul E. McKenney #ifdef CONFIG_DEBUG_LOCK_ALLOC
55*dad81a20SPaul E. McKenney 
56*dad81a20SPaul E. McKenney int __init_srcu_struct(struct srcu_struct *sp, const char *name,
57*dad81a20SPaul E. McKenney 		       struct lock_class_key *key)
58*dad81a20SPaul E. McKenney {
59*dad81a20SPaul E. McKenney 	/* Don't re-initialize a lock while it is held. */
60*dad81a20SPaul E. McKenney 	debug_check_no_locks_freed((void *)sp, sizeof(*sp));
61*dad81a20SPaul E. McKenney 	lockdep_init_map(&sp->dep_map, name, key, 0);
62*dad81a20SPaul E. McKenney 	return init_srcu_struct_fields(sp);
63*dad81a20SPaul E. McKenney }
64*dad81a20SPaul E. McKenney EXPORT_SYMBOL_GPL(__init_srcu_struct);
65*dad81a20SPaul E. McKenney 
66*dad81a20SPaul E. McKenney #else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
67*dad81a20SPaul E. McKenney 
68*dad81a20SPaul E. McKenney /**
69*dad81a20SPaul E. McKenney  * init_srcu_struct - initialize a sleep-RCU structure
70*dad81a20SPaul E. McKenney  * @sp: structure to initialize.
71*dad81a20SPaul E. McKenney  *
72*dad81a20SPaul E. McKenney  * Must invoke this on a given srcu_struct before passing that srcu_struct
73*dad81a20SPaul E. McKenney  * to any other function.  Each srcu_struct represents a separate domain
74*dad81a20SPaul E. McKenney  * of SRCU protection.
75*dad81a20SPaul E. McKenney  */
76*dad81a20SPaul E. McKenney int init_srcu_struct(struct srcu_struct *sp)
77*dad81a20SPaul E. McKenney {
78*dad81a20SPaul E. McKenney 	return init_srcu_struct_fields(sp);
79*dad81a20SPaul E. McKenney }
80*dad81a20SPaul E. McKenney EXPORT_SYMBOL_GPL(init_srcu_struct);
81*dad81a20SPaul E. McKenney 
82*dad81a20SPaul E. McKenney #endif /* #else #ifdef CONFIG_DEBUG_LOCK_ALLOC */
83*dad81a20SPaul E. McKenney 
84*dad81a20SPaul E. McKenney /*
85*dad81a20SPaul E. McKenney  * Returns approximate total of the readers' ->lock_count[] values for the
86*dad81a20SPaul E. McKenney  * rank of per-CPU counters specified by idx.
87*dad81a20SPaul E. McKenney  */
88*dad81a20SPaul E. McKenney static unsigned long srcu_readers_lock_idx(struct srcu_struct *sp, int idx)
89*dad81a20SPaul E. McKenney {
90*dad81a20SPaul E. McKenney 	int cpu;
91*dad81a20SPaul E. McKenney 	unsigned long sum = 0;
92*dad81a20SPaul E. McKenney 
93*dad81a20SPaul E. McKenney 	for_each_possible_cpu(cpu) {
94*dad81a20SPaul E. McKenney 		struct srcu_array *cpuc = per_cpu_ptr(sp->per_cpu_ref, cpu);
95*dad81a20SPaul E. McKenney 
96*dad81a20SPaul E. McKenney 		sum += READ_ONCE(cpuc->lock_count[idx]);
97*dad81a20SPaul E. McKenney 	}
98*dad81a20SPaul E. McKenney 	return sum;
99*dad81a20SPaul E. McKenney }
100*dad81a20SPaul E. McKenney 
101*dad81a20SPaul E. McKenney /*
102*dad81a20SPaul E. McKenney  * Returns approximate total of the readers' ->unlock_count[] values for the
103*dad81a20SPaul E. McKenney  * rank of per-CPU counters specified by idx.
104*dad81a20SPaul E. McKenney  */
105*dad81a20SPaul E. McKenney static unsigned long srcu_readers_unlock_idx(struct srcu_struct *sp, int idx)
106*dad81a20SPaul E. McKenney {
107*dad81a20SPaul E. McKenney 	int cpu;
108*dad81a20SPaul E. McKenney 	unsigned long sum = 0;
109*dad81a20SPaul E. McKenney 
110*dad81a20SPaul E. McKenney 	for_each_possible_cpu(cpu) {
111*dad81a20SPaul E. McKenney 		struct srcu_array *cpuc = per_cpu_ptr(sp->per_cpu_ref, cpu);
112*dad81a20SPaul E. McKenney 
113*dad81a20SPaul E. McKenney 		sum += READ_ONCE(cpuc->unlock_count[idx]);
114*dad81a20SPaul E. McKenney 	}
115*dad81a20SPaul E. McKenney 	return sum;
116*dad81a20SPaul E. McKenney }
117*dad81a20SPaul E. McKenney 
118*dad81a20SPaul E. McKenney /*
119*dad81a20SPaul E. McKenney  * Return true if the number of pre-existing readers is determined to
120*dad81a20SPaul E. McKenney  * be zero.
121*dad81a20SPaul E. McKenney  */
122*dad81a20SPaul E. McKenney static bool srcu_readers_active_idx_check(struct srcu_struct *sp, int idx)
123*dad81a20SPaul E. McKenney {
124*dad81a20SPaul E. McKenney 	unsigned long unlocks;
125*dad81a20SPaul E. McKenney 
126*dad81a20SPaul E. McKenney 	unlocks = srcu_readers_unlock_idx(sp, idx);
127*dad81a20SPaul E. McKenney 
128*dad81a20SPaul E. McKenney 	/*
129*dad81a20SPaul E. McKenney 	 * Make sure that a lock is always counted if the corresponding
130*dad81a20SPaul E. McKenney 	 * unlock is counted. Needs to be a smp_mb() as the read side may
131*dad81a20SPaul E. McKenney 	 * contain a read from a variable that is written to before the
132*dad81a20SPaul E. McKenney 	 * synchronize_srcu() in the write side. In this case smp_mb()s
133*dad81a20SPaul E. McKenney 	 * A and B act like the store buffering pattern.
134*dad81a20SPaul E. McKenney 	 *
135*dad81a20SPaul E. McKenney 	 * This smp_mb() also pairs with smp_mb() C to prevent accesses
136*dad81a20SPaul E. McKenney 	 * after the synchronize_srcu() from being executed before the
137*dad81a20SPaul E. McKenney 	 * grace period ends.
138*dad81a20SPaul E. McKenney 	 */
139*dad81a20SPaul E. McKenney 	smp_mb(); /* A */
140*dad81a20SPaul E. McKenney 
141*dad81a20SPaul E. McKenney 	/*
142*dad81a20SPaul E. McKenney 	 * If the locks are the same as the unlocks, then there must have
143*dad81a20SPaul E. McKenney 	 * been no readers on this index at some time in between. This does
144*dad81a20SPaul E. McKenney 	 * not mean that there are no more readers, as one could have read
145*dad81a20SPaul E. McKenney 	 * the current index but not have incremented the lock counter yet.
146*dad81a20SPaul E. McKenney 	 *
147*dad81a20SPaul E. McKenney 	 * Possible bug: There is no guarantee that there haven't been
148*dad81a20SPaul E. McKenney 	 * ULONG_MAX increments of ->lock_count[] since the unlocks were
149*dad81a20SPaul E. McKenney 	 * counted, meaning that this could return true even if there are
150*dad81a20SPaul E. McKenney 	 * still active readers.  Since there are no memory barriers around
151*dad81a20SPaul E. McKenney 	 * srcu_flip(), the CPU is not required to increment ->completed
152*dad81a20SPaul E. McKenney 	 * before running srcu_readers_unlock_idx(), which means that there
153*dad81a20SPaul E. McKenney 	 * could be an arbitrarily large number of critical sections that
154*dad81a20SPaul E. McKenney 	 * execute after srcu_readers_unlock_idx() but use the old value
155*dad81a20SPaul E. McKenney 	 * of ->completed.
156*dad81a20SPaul E. McKenney 	 */
157*dad81a20SPaul E. McKenney 	return srcu_readers_lock_idx(sp, idx) == unlocks;
158*dad81a20SPaul E. McKenney }
159*dad81a20SPaul E. McKenney 
160*dad81a20SPaul E. McKenney /**
161*dad81a20SPaul E. McKenney  * srcu_readers_active - returns true if there are readers. and false
162*dad81a20SPaul E. McKenney  *                       otherwise
163*dad81a20SPaul E. McKenney  * @sp: which srcu_struct to count active readers (holding srcu_read_lock).
164*dad81a20SPaul E. McKenney  *
165*dad81a20SPaul E. McKenney  * Note that this is not an atomic primitive, and can therefore suffer
166*dad81a20SPaul E. McKenney  * severe errors when invoked on an active srcu_struct.  That said, it
167*dad81a20SPaul E. McKenney  * can be useful as an error check at cleanup time.
168*dad81a20SPaul E. McKenney  */
169*dad81a20SPaul E. McKenney static bool srcu_readers_active(struct srcu_struct *sp)
170*dad81a20SPaul E. McKenney {
171*dad81a20SPaul E. McKenney 	int cpu;
172*dad81a20SPaul E. McKenney 	unsigned long sum = 0;
173*dad81a20SPaul E. McKenney 
174*dad81a20SPaul E. McKenney 	for_each_possible_cpu(cpu) {
175*dad81a20SPaul E. McKenney 		struct srcu_array *cpuc = per_cpu_ptr(sp->per_cpu_ref, cpu);
176*dad81a20SPaul E. McKenney 
177*dad81a20SPaul E. McKenney 		sum += READ_ONCE(cpuc->lock_count[0]);
178*dad81a20SPaul E. McKenney 		sum += READ_ONCE(cpuc->lock_count[1]);
179*dad81a20SPaul E. McKenney 		sum -= READ_ONCE(cpuc->unlock_count[0]);
180*dad81a20SPaul E. McKenney 		sum -= READ_ONCE(cpuc->unlock_count[1]);
181*dad81a20SPaul E. McKenney 	}
182*dad81a20SPaul E. McKenney 	return sum;
183*dad81a20SPaul E. McKenney }
184*dad81a20SPaul E. McKenney 
185*dad81a20SPaul E. McKenney #define SRCU_INTERVAL		1
186*dad81a20SPaul E. McKenney 
187*dad81a20SPaul E. McKenney /**
188*dad81a20SPaul E. McKenney  * cleanup_srcu_struct - deconstruct a sleep-RCU structure
189*dad81a20SPaul E. McKenney  * @sp: structure to clean up.
190*dad81a20SPaul E. McKenney  *
191*dad81a20SPaul E. McKenney  * Must invoke this after you are finished using a given srcu_struct that
192*dad81a20SPaul E. McKenney  * was initialized via init_srcu_struct(), else you leak memory.
193*dad81a20SPaul E. McKenney  */
194*dad81a20SPaul E. McKenney void cleanup_srcu_struct(struct srcu_struct *sp)
195*dad81a20SPaul E. McKenney {
196*dad81a20SPaul E. McKenney 	WARN_ON_ONCE(atomic_read(&sp->srcu_exp_cnt));
197*dad81a20SPaul E. McKenney 	if (WARN_ON(srcu_readers_active(sp)))
198*dad81a20SPaul E. McKenney 		return; /* Leakage unless caller handles error. */
199*dad81a20SPaul E. McKenney 	if (WARN_ON(!rcu_segcblist_empty(&sp->srcu_cblist)))
200*dad81a20SPaul E. McKenney 		return; /* Leakage unless caller handles error. */
201*dad81a20SPaul E. McKenney 	flush_delayed_work(&sp->work);
202*dad81a20SPaul E. McKenney 	if (WARN_ON(rcu_seq_state(READ_ONCE(sp->srcu_gp_seq)) != SRCU_STATE_IDLE)) {
203*dad81a20SPaul E. McKenney 		pr_info("cleanup_srcu_struct: Active srcu_struct %lu CBs %c state: %d\n", rcu_segcblist_n_cbs(&sp->srcu_cblist), ".E"[rcu_segcblist_empty(&sp->srcu_cblist)], rcu_seq_state(READ_ONCE(sp->srcu_gp_seq)));
204*dad81a20SPaul E. McKenney 		return; /* Caller forgot to stop doing call_srcu()? */
205*dad81a20SPaul E. McKenney 	}
206*dad81a20SPaul E. McKenney 	free_percpu(sp->per_cpu_ref);
207*dad81a20SPaul E. McKenney 	sp->per_cpu_ref = NULL;
208*dad81a20SPaul E. McKenney }
209*dad81a20SPaul E. McKenney EXPORT_SYMBOL_GPL(cleanup_srcu_struct);
210*dad81a20SPaul E. McKenney 
211*dad81a20SPaul E. McKenney /*
212*dad81a20SPaul E. McKenney  * Counts the new reader in the appropriate per-CPU element of the
213*dad81a20SPaul E. McKenney  * srcu_struct.  Must be called from process context.
214*dad81a20SPaul E. McKenney  * Returns an index that must be passed to the matching srcu_read_unlock().
215*dad81a20SPaul E. McKenney  */
216*dad81a20SPaul E. McKenney int __srcu_read_lock(struct srcu_struct *sp)
217*dad81a20SPaul E. McKenney {
218*dad81a20SPaul E. McKenney 	int idx;
219*dad81a20SPaul E. McKenney 
220*dad81a20SPaul E. McKenney 	idx = READ_ONCE(sp->completed) & 0x1;
221*dad81a20SPaul E. McKenney 	__this_cpu_inc(sp->per_cpu_ref->lock_count[idx]);
222*dad81a20SPaul E. McKenney 	smp_mb(); /* B */  /* Avoid leaking the critical section. */
223*dad81a20SPaul E. McKenney 	return idx;
224*dad81a20SPaul E. McKenney }
225*dad81a20SPaul E. McKenney EXPORT_SYMBOL_GPL(__srcu_read_lock);
226*dad81a20SPaul E. McKenney 
227*dad81a20SPaul E. McKenney /*
228*dad81a20SPaul E. McKenney  * Removes the count for the old reader from the appropriate per-CPU
229*dad81a20SPaul E. McKenney  * element of the srcu_struct.  Note that this may well be a different
230*dad81a20SPaul E. McKenney  * CPU than that which was incremented by the corresponding srcu_read_lock().
231*dad81a20SPaul E. McKenney  * Must be called from process context.
232*dad81a20SPaul E. McKenney  */
233*dad81a20SPaul E. McKenney void __srcu_read_unlock(struct srcu_struct *sp, int idx)
234*dad81a20SPaul E. McKenney {
235*dad81a20SPaul E. McKenney 	smp_mb(); /* C */  /* Avoid leaking the critical section. */
236*dad81a20SPaul E. McKenney 	this_cpu_inc(sp->per_cpu_ref->unlock_count[idx]);
237*dad81a20SPaul E. McKenney }
238*dad81a20SPaul E. McKenney EXPORT_SYMBOL_GPL(__srcu_read_unlock);
239*dad81a20SPaul E. McKenney 
240*dad81a20SPaul E. McKenney /*
241*dad81a20SPaul E. McKenney  * We use an adaptive strategy for synchronize_srcu() and especially for
242*dad81a20SPaul E. McKenney  * synchronize_srcu_expedited().  We spin for a fixed time period
243*dad81a20SPaul E. McKenney  * (defined below) to allow SRCU readers to exit their read-side critical
244*dad81a20SPaul E. McKenney  * sections.  If there are still some readers after a few microseconds,
245*dad81a20SPaul E. McKenney  * we repeatedly block for 1-millisecond time periods.
246*dad81a20SPaul E. McKenney  */
247*dad81a20SPaul E. McKenney #define SRCU_RETRY_CHECK_DELAY		5
248*dad81a20SPaul E. McKenney 
249*dad81a20SPaul E. McKenney /*
250*dad81a20SPaul E. McKenney  * Start an SRCU grace period.
251*dad81a20SPaul E. McKenney  */
252*dad81a20SPaul E. McKenney static void srcu_gp_start(struct srcu_struct *sp)
253*dad81a20SPaul E. McKenney {
254*dad81a20SPaul E. McKenney 	int state;
255*dad81a20SPaul E. McKenney 
256*dad81a20SPaul E. McKenney 	rcu_segcblist_accelerate(&sp->srcu_cblist,
257*dad81a20SPaul E. McKenney 				 rcu_seq_snap(&sp->srcu_gp_seq));
258*dad81a20SPaul E. McKenney 	rcu_seq_start(&sp->srcu_gp_seq);
259*dad81a20SPaul E. McKenney 	state = rcu_seq_state(READ_ONCE(sp->srcu_gp_seq));
260*dad81a20SPaul E. McKenney 	WARN_ON_ONCE(state != SRCU_STATE_SCAN1);
261*dad81a20SPaul E. McKenney }
262*dad81a20SPaul E. McKenney 
263*dad81a20SPaul E. McKenney /*
264*dad81a20SPaul E. McKenney  * Wait until all readers counted by array index idx complete, but
265*dad81a20SPaul E. McKenney  * loop an additional time if there is an expedited grace period pending.
266*dad81a20SPaul E. McKenney  * The caller must ensure that ->completed is not changed while checking.
267*dad81a20SPaul E. McKenney  */
268*dad81a20SPaul E. McKenney static bool try_check_zero(struct srcu_struct *sp, int idx, int trycount)
269*dad81a20SPaul E. McKenney {
270*dad81a20SPaul E. McKenney 	for (;;) {
271*dad81a20SPaul E. McKenney 		if (srcu_readers_active_idx_check(sp, idx))
272*dad81a20SPaul E. McKenney 			return true;
273*dad81a20SPaul E. McKenney 		if (--trycount + !!atomic_read(&sp->srcu_exp_cnt) <= 0)
274*dad81a20SPaul E. McKenney 			return false;
275*dad81a20SPaul E. McKenney 		udelay(SRCU_RETRY_CHECK_DELAY);
276*dad81a20SPaul E. McKenney 	}
277*dad81a20SPaul E. McKenney }
278*dad81a20SPaul E. McKenney 
279*dad81a20SPaul E. McKenney /*
280*dad81a20SPaul E. McKenney  * Increment the ->completed counter so that future SRCU readers will
281*dad81a20SPaul E. McKenney  * use the other rank of the ->(un)lock_count[] arrays.  This allows
282*dad81a20SPaul E. McKenney  * us to wait for pre-existing readers in a starvation-free manner.
283*dad81a20SPaul E. McKenney  */
284*dad81a20SPaul E. McKenney static void srcu_flip(struct srcu_struct *sp)
285*dad81a20SPaul E. McKenney {
286*dad81a20SPaul E. McKenney 	WRITE_ONCE(sp->completed, sp->completed + 1);
287*dad81a20SPaul E. McKenney 
288*dad81a20SPaul E. McKenney 	/*
289*dad81a20SPaul E. McKenney 	 * Ensure that if the updater misses an __srcu_read_unlock()
290*dad81a20SPaul E. McKenney 	 * increment, that task's next __srcu_read_lock() will see the
291*dad81a20SPaul E. McKenney 	 * above counter update.  Note that both this memory barrier
292*dad81a20SPaul E. McKenney 	 * and the one in srcu_readers_active_idx_check() provide the
293*dad81a20SPaul E. McKenney 	 * guarantee for __srcu_read_lock().
294*dad81a20SPaul E. McKenney 	 */
295*dad81a20SPaul E. McKenney 	smp_mb(); /* D */  /* Pairs with C. */
296*dad81a20SPaul E. McKenney }
297*dad81a20SPaul E. McKenney 
298*dad81a20SPaul E. McKenney /*
299*dad81a20SPaul E. McKenney  * End an SRCU grace period.
300*dad81a20SPaul E. McKenney  */
301*dad81a20SPaul E. McKenney static void srcu_gp_end(struct srcu_struct *sp)
302*dad81a20SPaul E. McKenney {
303*dad81a20SPaul E. McKenney 	rcu_seq_end(&sp->srcu_gp_seq);
304*dad81a20SPaul E. McKenney 
305*dad81a20SPaul E. McKenney 	spin_lock_irq(&sp->queue_lock);
306*dad81a20SPaul E. McKenney 	rcu_segcblist_advance(&sp->srcu_cblist,
307*dad81a20SPaul E. McKenney 			      rcu_seq_current(&sp->srcu_gp_seq));
308*dad81a20SPaul E. McKenney 	spin_unlock_irq(&sp->queue_lock);
309*dad81a20SPaul E. McKenney }
310*dad81a20SPaul E. McKenney 
311*dad81a20SPaul E. McKenney /*
312*dad81a20SPaul E. McKenney  * Enqueue an SRCU callback on the specified srcu_struct structure,
313*dad81a20SPaul E. McKenney  * initiating grace-period processing if it is not already running.
314*dad81a20SPaul E. McKenney  *
315*dad81a20SPaul E. McKenney  * Note that all CPUs must agree that the grace period extended beyond
316*dad81a20SPaul E. McKenney  * all pre-existing SRCU read-side critical section.  On systems with
317*dad81a20SPaul E. McKenney  * more than one CPU, this means that when "func()" is invoked, each CPU
318*dad81a20SPaul E. McKenney  * is guaranteed to have executed a full memory barrier since the end of
319*dad81a20SPaul E. McKenney  * its last corresponding SRCU read-side critical section whose beginning
320*dad81a20SPaul E. McKenney  * preceded the call to call_rcu().  It also means that each CPU executing
321*dad81a20SPaul E. McKenney  * an SRCU read-side critical section that continues beyond the start of
322*dad81a20SPaul E. McKenney  * "func()" must have executed a memory barrier after the call_rcu()
323*dad81a20SPaul E. McKenney  * but before the beginning of that SRCU read-side critical section.
324*dad81a20SPaul E. McKenney  * Note that these guarantees include CPUs that are offline, idle, or
325*dad81a20SPaul E. McKenney  * executing in user mode, as well as CPUs that are executing in the kernel.
326*dad81a20SPaul E. McKenney  *
327*dad81a20SPaul E. McKenney  * Furthermore, if CPU A invoked call_rcu() and CPU B invoked the
328*dad81a20SPaul E. McKenney  * resulting SRCU callback function "func()", then both CPU A and CPU
329*dad81a20SPaul E. McKenney  * B are guaranteed to execute a full memory barrier during the time
330*dad81a20SPaul E. McKenney  * interval between the call to call_rcu() and the invocation of "func()".
331*dad81a20SPaul E. McKenney  * This guarantee applies even if CPU A and CPU B are the same CPU (but
332*dad81a20SPaul E. McKenney  * again only if the system has more than one CPU).
333*dad81a20SPaul E. McKenney  *
334*dad81a20SPaul E. McKenney  * Of course, these guarantees apply only for invocations of call_srcu(),
335*dad81a20SPaul E. McKenney  * srcu_read_lock(), and srcu_read_unlock() that are all passed the same
336*dad81a20SPaul E. McKenney  * srcu_struct structure.
337*dad81a20SPaul E. McKenney  */
338*dad81a20SPaul E. McKenney void call_srcu(struct srcu_struct *sp, struct rcu_head *head,
339*dad81a20SPaul E. McKenney 	       rcu_callback_t func)
340*dad81a20SPaul E. McKenney {
341*dad81a20SPaul E. McKenney 	unsigned long flags;
342*dad81a20SPaul E. McKenney 
343*dad81a20SPaul E. McKenney 	head->next = NULL;
344*dad81a20SPaul E. McKenney 	head->func = func;
345*dad81a20SPaul E. McKenney 	spin_lock_irqsave(&sp->queue_lock, flags);
346*dad81a20SPaul E. McKenney 	smp_mb__after_unlock_lock(); /* Caller's prior accesses before GP. */
347*dad81a20SPaul E. McKenney 	rcu_segcblist_enqueue(&sp->srcu_cblist, head, false);
348*dad81a20SPaul E. McKenney 	if (rcu_seq_state(READ_ONCE(sp->srcu_gp_seq)) == SRCU_STATE_IDLE) {
349*dad81a20SPaul E. McKenney 		srcu_gp_start(sp);
350*dad81a20SPaul E. McKenney 		queue_delayed_work(system_power_efficient_wq, &sp->work, 0);
351*dad81a20SPaul E. McKenney 	}
352*dad81a20SPaul E. McKenney 	spin_unlock_irqrestore(&sp->queue_lock, flags);
353*dad81a20SPaul E. McKenney }
354*dad81a20SPaul E. McKenney EXPORT_SYMBOL_GPL(call_srcu);
355*dad81a20SPaul E. McKenney 
356*dad81a20SPaul E. McKenney static void srcu_reschedule(struct srcu_struct *sp, unsigned long delay);
357*dad81a20SPaul E. McKenney 
358*dad81a20SPaul E. McKenney /*
359*dad81a20SPaul E. McKenney  * Helper function for synchronize_srcu() and synchronize_srcu_expedited().
360*dad81a20SPaul E. McKenney  */
361*dad81a20SPaul E. McKenney static void __synchronize_srcu(struct srcu_struct *sp)
362*dad81a20SPaul E. McKenney {
363*dad81a20SPaul E. McKenney 	struct rcu_synchronize rcu;
364*dad81a20SPaul E. McKenney 	struct rcu_head *head = &rcu.head;
365*dad81a20SPaul E. McKenney 
366*dad81a20SPaul E. McKenney 	RCU_LOCKDEP_WARN(lock_is_held(&sp->dep_map) ||
367*dad81a20SPaul E. McKenney 			 lock_is_held(&rcu_bh_lock_map) ||
368*dad81a20SPaul E. McKenney 			 lock_is_held(&rcu_lock_map) ||
369*dad81a20SPaul E. McKenney 			 lock_is_held(&rcu_sched_lock_map),
370*dad81a20SPaul E. McKenney 			 "Illegal synchronize_srcu() in same-type SRCU (or in RCU) read-side critical section");
371*dad81a20SPaul E. McKenney 
372*dad81a20SPaul E. McKenney 	if (rcu_scheduler_active == RCU_SCHEDULER_INACTIVE)
373*dad81a20SPaul E. McKenney 		return;
374*dad81a20SPaul E. McKenney 	might_sleep();
375*dad81a20SPaul E. McKenney 	init_completion(&rcu.completion);
376*dad81a20SPaul E. McKenney 
377*dad81a20SPaul E. McKenney 	head->next = NULL;
378*dad81a20SPaul E. McKenney 	head->func = wakeme_after_rcu;
379*dad81a20SPaul E. McKenney 	spin_lock_irq(&sp->queue_lock);
380*dad81a20SPaul E. McKenney 	smp_mb__after_unlock_lock(); /* Caller's prior accesses before GP. */
381*dad81a20SPaul E. McKenney 	if (rcu_seq_state(READ_ONCE(sp->srcu_gp_seq)) == SRCU_STATE_IDLE) {
382*dad81a20SPaul E. McKenney 		/* steal the processing owner */
383*dad81a20SPaul E. McKenney 		rcu_segcblist_enqueue(&sp->srcu_cblist, head, false);
384*dad81a20SPaul E. McKenney 		srcu_gp_start(sp);
385*dad81a20SPaul E. McKenney 		spin_unlock_irq(&sp->queue_lock);
386*dad81a20SPaul E. McKenney 		/* give the processing owner to work_struct */
387*dad81a20SPaul E. McKenney 		srcu_reschedule(sp, 0);
388*dad81a20SPaul E. McKenney 	} else {
389*dad81a20SPaul E. McKenney 		rcu_segcblist_enqueue(&sp->srcu_cblist, head, false);
390*dad81a20SPaul E. McKenney 		spin_unlock_irq(&sp->queue_lock);
391*dad81a20SPaul E. McKenney 	}
392*dad81a20SPaul E. McKenney 
393*dad81a20SPaul E. McKenney 	wait_for_completion(&rcu.completion);
394*dad81a20SPaul E. McKenney 	smp_mb(); /* Caller's later accesses after GP. */
395*dad81a20SPaul E. McKenney }
396*dad81a20SPaul E. McKenney 
397*dad81a20SPaul E. McKenney /**
398*dad81a20SPaul E. McKenney  * synchronize_srcu_expedited - Brute-force SRCU grace period
399*dad81a20SPaul E. McKenney  * @sp: srcu_struct with which to synchronize.
400*dad81a20SPaul E. McKenney  *
401*dad81a20SPaul E. McKenney  * Wait for an SRCU grace period to elapse, but be more aggressive about
402*dad81a20SPaul E. McKenney  * spinning rather than blocking when waiting.
403*dad81a20SPaul E. McKenney  *
404*dad81a20SPaul E. McKenney  * Note that synchronize_srcu_expedited() has the same deadlock and
405*dad81a20SPaul E. McKenney  * memory-ordering properties as does synchronize_srcu().
406*dad81a20SPaul E. McKenney  */
407*dad81a20SPaul E. McKenney void synchronize_srcu_expedited(struct srcu_struct *sp)
408*dad81a20SPaul E. McKenney {
409*dad81a20SPaul E. McKenney 	bool do_norm = rcu_gp_is_normal();
410*dad81a20SPaul E. McKenney 
411*dad81a20SPaul E. McKenney 	if (!do_norm) {
412*dad81a20SPaul E. McKenney 		atomic_inc(&sp->srcu_exp_cnt);
413*dad81a20SPaul E. McKenney 		smp_mb__after_atomic(); /* increment before GP. */
414*dad81a20SPaul E. McKenney 	}
415*dad81a20SPaul E. McKenney 	__synchronize_srcu(sp);
416*dad81a20SPaul E. McKenney 	if (!do_norm) {
417*dad81a20SPaul E. McKenney 		smp_mb__before_atomic(); /* GP before decrement. */
418*dad81a20SPaul E. McKenney 		atomic_dec(&sp->srcu_exp_cnt);
419*dad81a20SPaul E. McKenney 	}
420*dad81a20SPaul E. McKenney }
421*dad81a20SPaul E. McKenney EXPORT_SYMBOL_GPL(synchronize_srcu_expedited);
422*dad81a20SPaul E. McKenney 
423*dad81a20SPaul E. McKenney /**
424*dad81a20SPaul E. McKenney  * synchronize_srcu - wait for prior SRCU read-side critical-section completion
425*dad81a20SPaul E. McKenney  * @sp: srcu_struct with which to synchronize.
426*dad81a20SPaul E. McKenney  *
427*dad81a20SPaul E. McKenney  * Wait for the count to drain to zero of both indexes. To avoid the
428*dad81a20SPaul E. McKenney  * possible starvation of synchronize_srcu(), it waits for the count of
429*dad81a20SPaul E. McKenney  * the index=((->completed & 1) ^ 1) to drain to zero at first,
430*dad81a20SPaul E. McKenney  * and then flip the completed and wait for the count of the other index.
431*dad81a20SPaul E. McKenney  *
432*dad81a20SPaul E. McKenney  * Can block; must be called from process context.
433*dad81a20SPaul E. McKenney  *
434*dad81a20SPaul E. McKenney  * Note that it is illegal to call synchronize_srcu() from the corresponding
435*dad81a20SPaul E. McKenney  * SRCU read-side critical section; doing so will result in deadlock.
436*dad81a20SPaul E. McKenney  * However, it is perfectly legal to call synchronize_srcu() on one
437*dad81a20SPaul E. McKenney  * srcu_struct from some other srcu_struct's read-side critical section,
438*dad81a20SPaul E. McKenney  * as long as the resulting graph of srcu_structs is acyclic.
439*dad81a20SPaul E. McKenney  *
440*dad81a20SPaul E. McKenney  * There are memory-ordering constraints implied by synchronize_srcu().
441*dad81a20SPaul E. McKenney  * On systems with more than one CPU, when synchronize_srcu() returns,
442*dad81a20SPaul E. McKenney  * each CPU is guaranteed to have executed a full memory barrier since
443*dad81a20SPaul E. McKenney  * the end of its last corresponding SRCU-sched read-side critical section
444*dad81a20SPaul E. McKenney  * whose beginning preceded the call to synchronize_srcu().  In addition,
445*dad81a20SPaul E. McKenney  * each CPU having an SRCU read-side critical section that extends beyond
446*dad81a20SPaul E. McKenney  * the return from synchronize_srcu() is guaranteed to have executed a
447*dad81a20SPaul E. McKenney  * full memory barrier after the beginning of synchronize_srcu() and before
448*dad81a20SPaul E. McKenney  * the beginning of that SRCU read-side critical section.  Note that these
449*dad81a20SPaul E. McKenney  * guarantees include CPUs that are offline, idle, or executing in user mode,
450*dad81a20SPaul E. McKenney  * as well as CPUs that are executing in the kernel.
451*dad81a20SPaul E. McKenney  *
452*dad81a20SPaul E. McKenney  * Furthermore, if CPU A invoked synchronize_srcu(), which returned
453*dad81a20SPaul E. McKenney  * to its caller on CPU B, then both CPU A and CPU B are guaranteed
454*dad81a20SPaul E. McKenney  * to have executed a full memory barrier during the execution of
455*dad81a20SPaul E. McKenney  * synchronize_srcu().  This guarantee applies even if CPU A and CPU B
456*dad81a20SPaul E. McKenney  * are the same CPU, but again only if the system has more than one CPU.
457*dad81a20SPaul E. McKenney  *
458*dad81a20SPaul E. McKenney  * Of course, these memory-ordering guarantees apply only when
459*dad81a20SPaul E. McKenney  * synchronize_srcu(), srcu_read_lock(), and srcu_read_unlock() are
460*dad81a20SPaul E. McKenney  * passed the same srcu_struct structure.
461*dad81a20SPaul E. McKenney  */
462*dad81a20SPaul E. McKenney void synchronize_srcu(struct srcu_struct *sp)
463*dad81a20SPaul E. McKenney {
464*dad81a20SPaul E. McKenney 	if (rcu_gp_is_expedited())
465*dad81a20SPaul E. McKenney 		synchronize_srcu_expedited(sp);
466*dad81a20SPaul E. McKenney 	else
467*dad81a20SPaul E. McKenney 		__synchronize_srcu(sp);
468*dad81a20SPaul E. McKenney }
469*dad81a20SPaul E. McKenney EXPORT_SYMBOL_GPL(synchronize_srcu);
470*dad81a20SPaul E. McKenney 
471*dad81a20SPaul E. McKenney /**
472*dad81a20SPaul E. McKenney  * srcu_barrier - Wait until all in-flight call_srcu() callbacks complete.
473*dad81a20SPaul E. McKenney  * @sp: srcu_struct on which to wait for in-flight callbacks.
474*dad81a20SPaul E. McKenney  */
475*dad81a20SPaul E. McKenney void srcu_barrier(struct srcu_struct *sp)
476*dad81a20SPaul E. McKenney {
477*dad81a20SPaul E. McKenney 	synchronize_srcu(sp);
478*dad81a20SPaul E. McKenney }
479*dad81a20SPaul E. McKenney EXPORT_SYMBOL_GPL(srcu_barrier);
480*dad81a20SPaul E. McKenney 
481*dad81a20SPaul E. McKenney /**
482*dad81a20SPaul E. McKenney  * srcu_batches_completed - return batches completed.
483*dad81a20SPaul E. McKenney  * @sp: srcu_struct on which to report batch completion.
484*dad81a20SPaul E. McKenney  *
485*dad81a20SPaul E. McKenney  * Report the number of batches, correlated with, but not necessarily
486*dad81a20SPaul E. McKenney  * precisely the same as, the number of grace periods that have elapsed.
487*dad81a20SPaul E. McKenney  */
488*dad81a20SPaul E. McKenney unsigned long srcu_batches_completed(struct srcu_struct *sp)
489*dad81a20SPaul E. McKenney {
490*dad81a20SPaul E. McKenney 	return sp->completed;
491*dad81a20SPaul E. McKenney }
492*dad81a20SPaul E. McKenney EXPORT_SYMBOL_GPL(srcu_batches_completed);
493*dad81a20SPaul E. McKenney 
494*dad81a20SPaul E. McKenney /*
495*dad81a20SPaul E. McKenney  * Core SRCU state machine.  Advance callbacks from ->batch_check0 to
496*dad81a20SPaul E. McKenney  * ->batch_check1 and then to ->batch_done as readers drain.
497*dad81a20SPaul E. McKenney  */
498*dad81a20SPaul E. McKenney static void srcu_advance_batches(struct srcu_struct *sp)
499*dad81a20SPaul E. McKenney {
500*dad81a20SPaul E. McKenney 	int idx;
501*dad81a20SPaul E. McKenney 
502*dad81a20SPaul E. McKenney 	/*
503*dad81a20SPaul E. McKenney 	 * Because readers might be delayed for an extended period after
504*dad81a20SPaul E. McKenney 	 * fetching ->completed for their index, at any point in time there
505*dad81a20SPaul E. McKenney 	 * might well be readers using both idx=0 and idx=1.  We therefore
506*dad81a20SPaul E. McKenney 	 * need to wait for readers to clear from both index values before
507*dad81a20SPaul E. McKenney 	 * invoking a callback.
508*dad81a20SPaul E. McKenney 	 *
509*dad81a20SPaul E. McKenney 	 * The load-acquire ensures that we see the accesses performed
510*dad81a20SPaul E. McKenney 	 * by the prior grace period.
511*dad81a20SPaul E. McKenney 	 */
512*dad81a20SPaul E. McKenney 	idx = rcu_seq_state(smp_load_acquire(&sp->srcu_gp_seq)); /* ^^^ */
513*dad81a20SPaul E. McKenney 	if (idx == SRCU_STATE_IDLE) {
514*dad81a20SPaul E. McKenney 		spin_lock_irq(&sp->queue_lock);
515*dad81a20SPaul E. McKenney 		if (rcu_segcblist_empty(&sp->srcu_cblist)) {
516*dad81a20SPaul E. McKenney 			spin_unlock_irq(&sp->queue_lock);
517*dad81a20SPaul E. McKenney 			return;
518*dad81a20SPaul E. McKenney 		}
519*dad81a20SPaul E. McKenney 		idx = rcu_seq_state(READ_ONCE(sp->srcu_gp_seq));
520*dad81a20SPaul E. McKenney 		if (idx == SRCU_STATE_IDLE)
521*dad81a20SPaul E. McKenney 			srcu_gp_start(sp);
522*dad81a20SPaul E. McKenney 		spin_unlock_irq(&sp->queue_lock);
523*dad81a20SPaul E. McKenney 		if (idx != SRCU_STATE_IDLE)
524*dad81a20SPaul E. McKenney 			return; /* Someone else started the grace period. */
525*dad81a20SPaul E. McKenney 	}
526*dad81a20SPaul E. McKenney 
527*dad81a20SPaul E. McKenney 	if (rcu_seq_state(READ_ONCE(sp->srcu_gp_seq)) == SRCU_STATE_SCAN1) {
528*dad81a20SPaul E. McKenney 		idx = 1 ^ (sp->completed & 1);
529*dad81a20SPaul E. McKenney 		if (!try_check_zero(sp, idx, 1))
530*dad81a20SPaul E. McKenney 			return; /* readers present, retry later. */
531*dad81a20SPaul E. McKenney 		srcu_flip(sp);
532*dad81a20SPaul E. McKenney 		rcu_seq_set_state(&sp->srcu_gp_seq, SRCU_STATE_SCAN2);
533*dad81a20SPaul E. McKenney 	}
534*dad81a20SPaul E. McKenney 
535*dad81a20SPaul E. McKenney 	if (rcu_seq_state(READ_ONCE(sp->srcu_gp_seq)) == SRCU_STATE_SCAN2) {
536*dad81a20SPaul E. McKenney 
537*dad81a20SPaul E. McKenney 		/*
538*dad81a20SPaul E. McKenney 		 * SRCU read-side critical sections are normally short,
539*dad81a20SPaul E. McKenney 		 * so check at least twice in quick succession after a flip.
540*dad81a20SPaul E. McKenney 		 */
541*dad81a20SPaul E. McKenney 		idx = 1 ^ (sp->completed & 1);
542*dad81a20SPaul E. McKenney 		if (!try_check_zero(sp, idx, 2))
543*dad81a20SPaul E. McKenney 			return; /* readers present, retry after later. */
544*dad81a20SPaul E. McKenney 		srcu_gp_end(sp);
545*dad81a20SPaul E. McKenney 	}
546*dad81a20SPaul E. McKenney }
547*dad81a20SPaul E. McKenney 
548*dad81a20SPaul E. McKenney /*
549*dad81a20SPaul E. McKenney  * Invoke a limited number of SRCU callbacks that have passed through
550*dad81a20SPaul E. McKenney  * their grace period.  If there are more to do, SRCU will reschedule
551*dad81a20SPaul E. McKenney  * the workqueue.  Note that needed memory barriers have been executed
552*dad81a20SPaul E. McKenney  * in this task's context by srcu_readers_active_idx_check().
553*dad81a20SPaul E. McKenney  */
554*dad81a20SPaul E. McKenney static void srcu_invoke_callbacks(struct srcu_struct *sp)
555*dad81a20SPaul E. McKenney {
556*dad81a20SPaul E. McKenney 	struct rcu_cblist ready_cbs;
557*dad81a20SPaul E. McKenney 	struct rcu_head *rhp;
558*dad81a20SPaul E. McKenney 
559*dad81a20SPaul E. McKenney 	spin_lock_irq(&sp->queue_lock);
560*dad81a20SPaul E. McKenney 	if (!rcu_segcblist_ready_cbs(&sp->srcu_cblist)) {
561*dad81a20SPaul E. McKenney 		spin_unlock_irq(&sp->queue_lock);
562*dad81a20SPaul E. McKenney 		return;
563*dad81a20SPaul E. McKenney 	}
564*dad81a20SPaul E. McKenney 	rcu_cblist_init(&ready_cbs);
565*dad81a20SPaul E. McKenney 	rcu_segcblist_extract_done_cbs(&sp->srcu_cblist, &ready_cbs);
566*dad81a20SPaul E. McKenney 	spin_unlock_irq(&sp->queue_lock);
567*dad81a20SPaul E. McKenney 	rhp = rcu_cblist_dequeue(&ready_cbs);
568*dad81a20SPaul E. McKenney 	for (; rhp != NULL; rhp = rcu_cblist_dequeue(&ready_cbs)) {
569*dad81a20SPaul E. McKenney 		local_bh_disable();
570*dad81a20SPaul E. McKenney 		rhp->func(rhp);
571*dad81a20SPaul E. McKenney 		local_bh_enable();
572*dad81a20SPaul E. McKenney 	}
573*dad81a20SPaul E. McKenney 	spin_lock_irq(&sp->queue_lock);
574*dad81a20SPaul E. McKenney 	rcu_segcblist_insert_count(&sp->srcu_cblist, &ready_cbs);
575*dad81a20SPaul E. McKenney 	spin_unlock_irq(&sp->queue_lock);
576*dad81a20SPaul E. McKenney }
577*dad81a20SPaul E. McKenney 
578*dad81a20SPaul E. McKenney /*
579*dad81a20SPaul E. McKenney  * Finished one round of SRCU grace period.  Start another if there are
580*dad81a20SPaul E. McKenney  * more SRCU callbacks queued, otherwise put SRCU into not-running state.
581*dad81a20SPaul E. McKenney  */
582*dad81a20SPaul E. McKenney static void srcu_reschedule(struct srcu_struct *sp, unsigned long delay)
583*dad81a20SPaul E. McKenney {
584*dad81a20SPaul E. McKenney 	bool pending = true;
585*dad81a20SPaul E. McKenney 	int state;
586*dad81a20SPaul E. McKenney 
587*dad81a20SPaul E. McKenney 	if (rcu_segcblist_empty(&sp->srcu_cblist)) {
588*dad81a20SPaul E. McKenney 		spin_lock_irq(&sp->queue_lock);
589*dad81a20SPaul E. McKenney 		state = rcu_seq_state(READ_ONCE(sp->srcu_gp_seq));
590*dad81a20SPaul E. McKenney 		if (rcu_segcblist_empty(&sp->srcu_cblist) &&
591*dad81a20SPaul E. McKenney 		    state == SRCU_STATE_IDLE)
592*dad81a20SPaul E. McKenney 			pending = false;
593*dad81a20SPaul E. McKenney 		spin_unlock_irq(&sp->queue_lock);
594*dad81a20SPaul E. McKenney 	}
595*dad81a20SPaul E. McKenney 
596*dad81a20SPaul E. McKenney 	if (pending)
597*dad81a20SPaul E. McKenney 		queue_delayed_work(system_power_efficient_wq, &sp->work, delay);
598*dad81a20SPaul E. McKenney }
599*dad81a20SPaul E. McKenney 
600*dad81a20SPaul E. McKenney /*
601*dad81a20SPaul E. McKenney  * This is the work-queue function that handles SRCU grace periods.
602*dad81a20SPaul E. McKenney  */
603*dad81a20SPaul E. McKenney void process_srcu(struct work_struct *work)
604*dad81a20SPaul E. McKenney {
605*dad81a20SPaul E. McKenney 	struct srcu_struct *sp;
606*dad81a20SPaul E. McKenney 
607*dad81a20SPaul E. McKenney 	sp = container_of(work, struct srcu_struct, work.work);
608*dad81a20SPaul E. McKenney 
609*dad81a20SPaul E. McKenney 	srcu_advance_batches(sp);
610*dad81a20SPaul E. McKenney 	srcu_invoke_callbacks(sp);
611*dad81a20SPaul E. McKenney 	srcu_reschedule(sp, atomic_read(&sp->srcu_exp_cnt) ? 0 : SRCU_INTERVAL);
612*dad81a20SPaul E. McKenney }
613*dad81a20SPaul E. McKenney EXPORT_SYMBOL_GPL(process_srcu);
614