Skip to content

Commit bb94b12

Browse files
paulmckrcuFrederic Weisbecker
authored andcommitted
srcu: Allow inlining of __srcu_read_{,un}lock_lite()
This commit moves __srcu_read_lock_lite() and __srcu_read_unlock_lite() into include/linux/srcu.h and marks them "static inline" so that they can be inlined into srcu_read_lock_lite() and srcu_read_unlock_lite(), respectively. They are not hand-inlined due to Tree SRCU and Tiny SRCU having different implementations. The earlier removal of smp_mb() combined with the inlining produce significant single-percentage performance wins. Link: https://lore.kernel.org/all/CAEf4BzYgiNmSb=ZKQ65tm6nJDi1UX2Gq26cdHSH1mPwXJYZj5g@mail.gmail.com/ Reported-by: Alexei Starovoitov <[email protected]> Signed-off-by: Paul E. McKenney <[email protected]> Cc: Alexei Starovoitov <[email protected]> Cc: Andrii Nakryiko <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Kent Overstreet <[email protected]> Cc: <[email protected]> Reviewed-by: Neeraj Upadhyay <[email protected]> Signed-off-by: Frederic Weisbecker <[email protected]>
1 parent 6364dd8 commit bb94b12

File tree

2 files changed

+39
-41
lines changed

2 files changed

+39
-41
lines changed

include/linux/srcutree.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,4 +209,43 @@ void synchronize_srcu_expedited(struct srcu_struct *ssp);
209209
void srcu_barrier(struct srcu_struct *ssp);
210210
void srcu_torture_stats_print(struct srcu_struct *ssp, char *tt, char *tf);
211211

212+
/*
213+
* Counts the new reader in the appropriate per-CPU element of the
214+
* srcu_struct. Returns an index that must be passed to the matching
215+
* srcu_read_unlock_lite().
216+
*
217+
* Note that this_cpu_inc() is an RCU read-side critical section either
218+
* because it disables interrupts, because it is a single instruction,
219+
* or because it is a read-modify-write atomic operation, depending on
220+
* the whims of the architecture.
221+
*/
222+
static inline int __srcu_read_lock_lite(struct srcu_struct *ssp)
223+
{
224+
int idx;
225+
226+
RCU_LOCKDEP_WARN(!rcu_is_watching(), "RCU must be watching srcu_read_lock_lite().");
227+
idx = READ_ONCE(ssp->srcu_idx) & 0x1;
228+
this_cpu_inc(ssp->sda->srcu_lock_count[idx].counter); /* Y */
229+
barrier(); /* Avoid leaking the critical section. */
230+
return idx;
231+
}
232+
233+
/*
234+
* Removes the count for the old reader from the appropriate
235+
* per-CPU element of the srcu_struct. Note that this may well be a
236+
* different CPU than that which was incremented by the corresponding
237+
* srcu_read_lock_lite(), but it must be within the same task.
238+
*
239+
* Note that this_cpu_inc() is an RCU read-side critical section either
240+
* because it disables interrupts, because it is a single instruction,
241+
* or because it is a read-modify-write atomic operation, depending on
242+
* the whims of the architecture.
243+
*/
244+
static inline void __srcu_read_unlock_lite(struct srcu_struct *ssp, int idx)
245+
{
246+
barrier(); /* Avoid leaking the critical section. */
247+
this_cpu_inc(ssp->sda->srcu_unlock_count[idx].counter); /* Z */
248+
RCU_LOCKDEP_WARN(!rcu_is_watching(), "RCU must be watching srcu_read_unlock_lite().");
249+
}
250+
212251
#endif

kernel/rcu/srcutree.c

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -763,47 +763,6 @@ void __srcu_read_unlock(struct srcu_struct *ssp, int idx)
763763
}
764764
EXPORT_SYMBOL_GPL(__srcu_read_unlock);
765765

766-
/*
767-
* Counts the new reader in the appropriate per-CPU element of the
768-
* srcu_struct. Returns an index that must be passed to the matching
769-
* srcu_read_unlock_lite().
770-
*
771-
* Note that this_cpu_inc() is an RCU read-side critical section either
772-
* because it disables interrupts, because it is a single instruction,
773-
* or because it is a read-modify-write atomic operation, depending on
774-
* the whims of the architecture.
775-
*/
776-
int __srcu_read_lock_lite(struct srcu_struct *ssp)
777-
{
778-
int idx;
779-
780-
RCU_LOCKDEP_WARN(!rcu_is_watching(), "RCU must be watching srcu_read_lock_lite().");
781-
idx = READ_ONCE(ssp->srcu_idx) & 0x1;
782-
this_cpu_inc(ssp->sda->srcu_lock_count[idx].counter); /* Y */
783-
barrier(); /* Avoid leaking the critical section. */
784-
return idx;
785-
}
786-
EXPORT_SYMBOL_GPL(__srcu_read_lock_lite);
787-
788-
/*
789-
* Removes the count for the old reader from the appropriate
790-
* per-CPU element of the srcu_struct. Note that this may well be a
791-
* different CPU than that which was incremented by the corresponding
792-
* srcu_read_lock_lite(), but it must be within the same task.
793-
*
794-
* Note that this_cpu_inc() is an RCU read-side critical section either
795-
* because it disables interrupts, because it is a single instruction,
796-
* or because it is a read-modify-write atomic operation, depending on
797-
* the whims of the architecture.
798-
*/
799-
void __srcu_read_unlock_lite(struct srcu_struct *ssp, int idx)
800-
{
801-
barrier(); /* Avoid leaking the critical section. */
802-
this_cpu_inc(ssp->sda->srcu_unlock_count[idx].counter); /* Z */
803-
RCU_LOCKDEP_WARN(!rcu_is_watching(), "RCU must be watching srcu_read_unlock_lite().");
804-
}
805-
EXPORT_SYMBOL_GPL(__srcu_read_unlock_lite);
806-
807766
#ifdef CONFIG_NEED_SRCU_NMI_SAFE
808767

809768
/*

0 commit comments

Comments
 (0)