Skip to content

Commit 9c80e44

Browse files
author
Joel Fernandes
committed
Merge branches 'rcu/misc-for-6.16', 'rcu/seq-counters-for-6.16' and 'rcu/torture-for-6.16' into rcu/for-next
3 parents 36f8e30 + f50ad4b + cbb44d9 commit 9c80e44

File tree

14 files changed

+369
-66
lines changed

14 files changed

+369
-66
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5657,6 +5657,31 @@
56575657
are zero, rcutorture acts as if is interpreted
56585658
they are all non-zero.
56595659

5660+
rcutorture.gpwrap_lag= [KNL]
5661+
Enable grace-period wrap lag testing. Setting
5662+
to false prevents the gpwrap lag test from
5663+
running. Default is true.
5664+
5665+
rcutorture.gpwrap_lag_gps= [KNL]
5666+
Set the value for grace-period wrap lag during
5667+
active lag testing periods. This controls how many
5668+
grace periods differences we tolerate between
5669+
rdp and rnp's gp_seq before setting overflow flag.
5670+
The default is always set to 8.
5671+
5672+
rcutorture.gpwrap_lag_cycle_mins= [KNL]
5673+
Set the total cycle duration for gpwrap lag
5674+
testing in minutes. This is the total time for
5675+
one complete cycle of active and inactive
5676+
testing periods. Default is 30 minutes.
5677+
5678+
rcutorture.gpwrap_lag_active_mins= [KNL]
5679+
Set the duration for which gpwrap lag is active
5680+
within each cycle, in minutes. During this time,
5681+
the grace-period wrap lag will be set to the
5682+
value specified by gpwrap_lag_gps. Default is
5683+
5 minutes.
5684+
56605685
rcutorture.irqreader= [KNL]
56615686
Run RCU readers from irq handlers, or, more
56625687
accurately, from a timer handler. Not all RCU

kernel/rcu/rcu.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@
5757
/* Low-order bit definition for polled grace-period APIs. */
5858
#define RCU_GET_STATE_COMPLETED 0x1
5959

60+
/* A complete grace period count */
61+
#define RCU_SEQ_GP (RCU_SEQ_STATE_MASK + 1)
62+
6063
extern int sysctl_sched_rt_runtime;
6164

6265
/*
@@ -157,12 +160,21 @@ static inline bool rcu_seq_done(unsigned long *sp, unsigned long s)
157160
* Given a snapshot from rcu_seq_snap(), determine whether or not a
158161
* full update-side operation has occurred, but do not allow the
159162
* (ULONG_MAX / 2) safety-factor/guard-band.
163+
*
164+
* The token returned by get_state_synchronize_rcu_full() is based on
165+
* rcu_state.gp_seq but it is tested in poll_state_synchronize_rcu_full()
166+
* against the root rnp->gp_seq. Since rcu_seq_start() is first called
167+
* on rcu_state.gp_seq and only later reflected on the root rnp->gp_seq,
168+
* it is possible that rcu_seq_snap(rcu_state.gp_seq) returns 2 full grace
169+
* periods ahead of the root rnp->gp_seq. To prevent false-positives with the
170+
* full polling API that a wrap around instantly completed the GP, when nothing
171+
* like that happened, adjust for the 2 GPs in the ULONG_CMP_LT().
160172
*/
161173
static inline bool rcu_seq_done_exact(unsigned long *sp, unsigned long s)
162174
{
163175
unsigned long cur_s = READ_ONCE(*sp);
164176

165-
return ULONG_CMP_GE(cur_s, s) || ULONG_CMP_LT(cur_s, s - (3 * RCU_SEQ_STATE_MASK + 1));
177+
return ULONG_CMP_GE(cur_s, s) || ULONG_CMP_LT(cur_s, s - (2 * RCU_SEQ_GP));
166178
}
167179

168180
/*
@@ -572,6 +584,8 @@ void do_trace_rcu_torture_read(const char *rcutorturename,
572584
unsigned long c_old,
573585
unsigned long c);
574586
void rcu_gp_set_torture_wait(int duration);
587+
void rcu_set_gpwrap_lag(unsigned long lag);
588+
int rcu_get_gpwrap_count(int cpu);
575589
#else
576590
static inline void rcutorture_get_gp_data(int *flags, unsigned long *gp_seq)
577591
{
@@ -589,6 +603,8 @@ void do_trace_rcu_torture_read(const char *rcutorturename,
589603
do { } while (0)
590604
#endif
591605
static inline void rcu_gp_set_torture_wait(int duration) { }
606+
static inline void rcu_set_gpwrap_lag(unsigned long lag) { }
607+
static inline int rcu_get_gpwrap_count(int cpu) { return 0; }
592608
#endif
593609
unsigned long long rcutorture_gather_gp_seqs(void);
594610
void rcutorture_format_gp_seqs(unsigned long long seqs, char *cp, size_t len);

0 commit comments

Comments
 (0)