@@ -253,8 +253,10 @@ static int init_srcu_struct_fields(struct srcu_struct *ssp, bool is_static)
253
253
atomic_set (& ssp -> srcu_sup -> srcu_barrier_cpu_cnt , 0 );
254
254
INIT_DELAYED_WORK (& ssp -> srcu_sup -> work , process_srcu );
255
255
ssp -> srcu_sup -> sda_is_static = is_static ;
256
- if (!is_static )
256
+ if (!is_static ) {
257
257
ssp -> sda = alloc_percpu (struct srcu_data );
258
+ ssp -> srcu_ctrp = & ssp -> sda -> srcu_ctrs [0 ];
259
+ }
258
260
if (!ssp -> sda )
259
261
goto err_free_sup ;
260
262
init_srcu_struct_data (ssp );
@@ -742,12 +744,11 @@ EXPORT_SYMBOL_GPL(__srcu_check_read_flavor);
742
744
*/
743
745
int __srcu_read_lock (struct srcu_struct * ssp )
744
746
{
745
- int idx ;
747
+ struct srcu_ctr __percpu * scp = READ_ONCE ( ssp -> srcu_ctrp ) ;
746
748
747
- idx = READ_ONCE (ssp -> srcu_idx ) & 0x1 ;
748
- this_cpu_inc (ssp -> sda -> srcu_ctrs [idx ].srcu_locks .counter );
749
+ this_cpu_inc (scp -> srcu_locks .counter );
749
750
smp_mb (); /* B */ /* Avoid leaking the critical section. */
750
- return idx ;
751
+ return scp - & ssp -> sda -> srcu_ctrs [ 0 ] ;
751
752
}
752
753
EXPORT_SYMBOL_GPL (__srcu_read_lock );
753
754
@@ -772,13 +773,12 @@ EXPORT_SYMBOL_GPL(__srcu_read_unlock);
772
773
*/
773
774
int __srcu_read_lock_nmisafe (struct srcu_struct * ssp )
774
775
{
775
- int idx ;
776
- struct srcu_data * sdp = raw_cpu_ptr (ssp -> sda );
776
+ struct srcu_ctr __percpu * scpp = READ_ONCE ( ssp -> srcu_ctrp ) ;
777
+ struct srcu_ctr * scp = raw_cpu_ptr (scpp );
777
778
778
- idx = READ_ONCE (ssp -> srcu_idx ) & 0x1 ;
779
- atomic_long_inc (& sdp -> srcu_ctrs [idx ].srcu_locks );
779
+ atomic_long_inc (& scp -> srcu_locks );
780
780
smp_mb__after_atomic (); /* B */ /* Avoid leaking the critical section. */
781
- return idx ;
781
+ return scpp - & ssp -> sda -> srcu_ctrs [ 0 ] ;
782
782
}
783
783
EXPORT_SYMBOL_GPL (__srcu_read_lock_nmisafe );
784
784
@@ -1152,6 +1152,8 @@ static void srcu_flip(struct srcu_struct *ssp)
1152
1152
smp_mb (); /* E */ /* Pairs with B and C. */
1153
1153
1154
1154
WRITE_ONCE (ssp -> srcu_idx , ssp -> srcu_idx + 1 ); // Flip the counter.
1155
+ WRITE_ONCE (ssp -> srcu_ctrp ,
1156
+ & ssp -> sda -> srcu_ctrs [!(ssp -> srcu_ctrp - & ssp -> sda -> srcu_ctrs [0 ])]);
1155
1157
1156
1158
/*
1157
1159
* Ensure that if the updater misses an __srcu_read_unlock()
@@ -2000,6 +2002,7 @@ static int srcu_module_coming(struct module *mod)
2000
2002
ssp -> sda = alloc_percpu (struct srcu_data );
2001
2003
if (WARN_ON_ONCE (!ssp -> sda ))
2002
2004
return - ENOMEM ;
2005
+ ssp -> srcu_ctrp = & ssp -> sda -> srcu_ctrs [0 ];
2003
2006
}
2004
2007
return 0 ;
2005
2008
}
0 commit comments