@@ -511,27 +511,75 @@ static bool srcu_readers_active(struct srcu_struct *ssp)
511
511
return sum ;
512
512
}
513
513
514
- #define SRCU_INTERVAL 1 // Base delay if no expedited GPs pending.
515
- #define SRCU_MAX_INTERVAL 10 // Maximum incremental delay from slow readers.
516
- #define SRCU_MAX_NODELAY_PHASE 1 // Maximum per-GP-phase consecutive no-delay instances.
517
- #define SRCU_MAX_NODELAY 100 // Maximum consecutive no-delay instances.
514
+ /*
515
+ * We use an adaptive strategy for synchronize_srcu() and especially for
516
+ * synchronize_srcu_expedited(). We spin for a fixed time period
517
+ * (defined below, boot time configurable) to allow SRCU readers to exit
518
+ * their read-side critical sections. If there are still some readers
519
+ * after one jiffy, we repeatedly block for one jiffy time periods.
520
+ * The blocking time is increased as the grace-period age increases,
521
+ * with max blocking time capped at 10 jiffies.
522
+ */
523
+ #define SRCU_DEFAULT_RETRY_CHECK_DELAY 5
524
+
525
+ static ulong srcu_retry_check_delay = SRCU_DEFAULT_RETRY_CHECK_DELAY ;
526
+ module_param (srcu_retry_check_delay , ulong , 0444 );
527
+
528
+ #define SRCU_INTERVAL 1 // Base delay if no expedited GPs pending.
529
+ #define SRCU_MAX_INTERVAL 10 // Maximum incremental delay from slow readers.
530
+
531
+ #define SRCU_DEFAULT_MAX_NODELAY_PHASE_LO 3UL // Lowmark on default per-GP-phase
532
+ // no-delay instances.
533
+ #define SRCU_DEFAULT_MAX_NODELAY_PHASE_HI 1000UL // Highmark on default per-GP-phase
534
+ // no-delay instances.
535
+
536
+ #define SRCU_UL_CLAMP_LO (val , low ) ((val) > (low) ? (val) : (low))
537
+ #define SRCU_UL_CLAMP_HI (val , high ) ((val) < (high) ? (val) : (high))
538
+ #define SRCU_UL_CLAMP (val , low , high ) SRCU_UL_CLAMP_HI(SRCU_UL_CLAMP_LO((val), (low)), (high))
539
+ // per-GP-phase no-delay instances adjusted to allow non-sleeping poll upto
540
+ // one jiffies time duration. Mult by 2 is done to factor in the srcu_get_delay()
541
+ // called from process_srcu().
542
+ #define SRCU_DEFAULT_MAX_NODELAY_PHASE_ADJUSTED \
543
+ (2UL * USEC_PER_SEC / HZ / SRCU_DEFAULT_RETRY_CHECK_DELAY)
544
+
545
+ // Maximum per-GP-phase consecutive no-delay instances.
546
+ #define SRCU_DEFAULT_MAX_NODELAY_PHASE \
547
+ SRCU_UL_CLAMP(SRCU_DEFAULT_MAX_NODELAY_PHASE_ADJUSTED, \
548
+ SRCU_DEFAULT_MAX_NODELAY_PHASE_LO, \
549
+ SRCU_DEFAULT_MAX_NODELAY_PHASE_HI)
550
+
551
+ static ulong srcu_max_nodelay_phase = SRCU_DEFAULT_MAX_NODELAY_PHASE ;
552
+ module_param (srcu_max_nodelay_phase , ulong , 0444 );
553
+
554
+ // Maximum consecutive no-delay instances.
555
+ #define SRCU_DEFAULT_MAX_NODELAY (SRCU_DEFAULT_MAX_NODELAY_PHASE > 100 ? \
556
+ SRCU_DEFAULT_MAX_NODELAY_PHASE : 100)
557
+
558
+ static ulong srcu_max_nodelay = SRCU_DEFAULT_MAX_NODELAY ;
559
+ module_param (srcu_max_nodelay , ulong , 0444 );
518
560
519
561
/*
520
562
* Return grace-period delay, zero if there are expedited grace
521
563
* periods pending, SRCU_INTERVAL otherwise.
522
564
*/
523
565
static unsigned long srcu_get_delay (struct srcu_struct * ssp )
524
566
{
567
+ unsigned long gpstart ;
568
+ unsigned long j ;
525
569
unsigned long jbase = SRCU_INTERVAL ;
526
570
527
571
if (ULONG_CMP_LT (READ_ONCE (ssp -> srcu_gp_seq ), READ_ONCE (ssp -> srcu_gp_seq_needed_exp )))
528
572
jbase = 0 ;
529
- if (rcu_seq_state (READ_ONCE (ssp -> srcu_gp_seq )))
530
- jbase += jiffies - READ_ONCE (ssp -> srcu_gp_start );
531
- if (!jbase ) {
532
- WRITE_ONCE (ssp -> srcu_n_exp_nodelay , READ_ONCE (ssp -> srcu_n_exp_nodelay ) + 1 );
533
- if (READ_ONCE (ssp -> srcu_n_exp_nodelay ) > SRCU_MAX_NODELAY_PHASE )
534
- jbase = 1 ;
573
+ if (rcu_seq_state (READ_ONCE (ssp -> srcu_gp_seq ))) {
574
+ j = jiffies - 1 ;
575
+ gpstart = READ_ONCE (ssp -> srcu_gp_start );
576
+ if (time_after (j , gpstart ))
577
+ jbase += j - gpstart ;
578
+ if (!jbase ) {
579
+ WRITE_ONCE (ssp -> srcu_n_exp_nodelay , READ_ONCE (ssp -> srcu_n_exp_nodelay ) + 1 );
580
+ if (READ_ONCE (ssp -> srcu_n_exp_nodelay ) > srcu_max_nodelay_phase )
581
+ jbase = 1 ;
582
+ }
535
583
}
536
584
return jbase > SRCU_MAX_INTERVAL ? SRCU_MAX_INTERVAL : jbase ;
537
585
}
@@ -606,15 +654,6 @@ void __srcu_read_unlock(struct srcu_struct *ssp, int idx)
606
654
}
607
655
EXPORT_SYMBOL_GPL (__srcu_read_unlock );
608
656
609
- /*
610
- * We use an adaptive strategy for synchronize_srcu() and especially for
611
- * synchronize_srcu_expedited(). We spin for a fixed time period
612
- * (defined below) to allow SRCU readers to exit their read-side critical
613
- * sections. If there are still some readers after a few microseconds,
614
- * we repeatedly block for 1-millisecond time periods.
615
- */
616
- #define SRCU_RETRY_CHECK_DELAY 5
617
-
618
657
/*
619
658
* Start an SRCU grace period.
620
659
*/
@@ -700,7 +739,7 @@ static void srcu_schedule_cbs_snp(struct srcu_struct *ssp, struct srcu_node *snp
700
739
*/
701
740
static void srcu_gp_end (struct srcu_struct * ssp )
702
741
{
703
- unsigned long cbdelay ;
742
+ unsigned long cbdelay = 1 ;
704
743
bool cbs ;
705
744
bool last_lvl ;
706
745
int cpu ;
@@ -720,7 +759,9 @@ static void srcu_gp_end(struct srcu_struct *ssp)
720
759
spin_lock_irq_rcu_node (ssp );
721
760
idx = rcu_seq_state (ssp -> srcu_gp_seq );
722
761
WARN_ON_ONCE (idx != SRCU_STATE_SCAN2 );
723
- cbdelay = !!srcu_get_delay (ssp );
762
+ if (ULONG_CMP_LT (READ_ONCE (ssp -> srcu_gp_seq ), READ_ONCE (ssp -> srcu_gp_seq_needed_exp )))
763
+ cbdelay = 0 ;
764
+
724
765
WRITE_ONCE (ssp -> srcu_last_gp_end , ktime_get_mono_fast_ns ());
725
766
rcu_seq_end (& ssp -> srcu_gp_seq );
726
767
gpseq = rcu_seq_current (& ssp -> srcu_gp_seq );
@@ -921,12 +962,16 @@ static void srcu_funnel_gp_start(struct srcu_struct *ssp, struct srcu_data *sdp,
921
962
*/
922
963
static bool try_check_zero (struct srcu_struct * ssp , int idx , int trycount )
923
964
{
965
+ unsigned long curdelay ;
966
+
967
+ curdelay = !srcu_get_delay (ssp );
968
+
924
969
for (;;) {
925
970
if (srcu_readers_active_idx_check (ssp , idx ))
926
971
return true;
927
- if (-- trycount + ! srcu_get_delay ( ssp ) <= 0 )
972
+ if (( -- trycount + curdelay ) <= 0 )
928
973
return false;
929
- udelay (SRCU_RETRY_CHECK_DELAY );
974
+ udelay (srcu_retry_check_delay );
930
975
}
931
976
}
932
977
@@ -1582,7 +1627,7 @@ static void process_srcu(struct work_struct *work)
1582
1627
j = jiffies ;
1583
1628
if (READ_ONCE (ssp -> reschedule_jiffies ) == j ) {
1584
1629
WRITE_ONCE (ssp -> reschedule_count , READ_ONCE (ssp -> reschedule_count ) + 1 );
1585
- if (READ_ONCE (ssp -> reschedule_count ) > SRCU_MAX_NODELAY )
1630
+ if (READ_ONCE (ssp -> reschedule_count ) > srcu_max_nodelay )
1586
1631
curdelay = 1 ;
1587
1632
} else {
1588
1633
WRITE_ONCE (ssp -> reschedule_count , 1 );
@@ -1674,6 +1719,11 @@ static int __init srcu_bootup_announce(void)
1674
1719
pr_info ("Hierarchical SRCU implementation.\n" );
1675
1720
if (exp_holdoff != DEFAULT_SRCU_EXP_HOLDOFF )
1676
1721
pr_info ("\tNon-default auto-expedite holdoff of %lu ns.\n" , exp_holdoff );
1722
+ if (srcu_retry_check_delay != SRCU_DEFAULT_RETRY_CHECK_DELAY )
1723
+ pr_info ("\tNon-default retry check delay of %lu us.\n" , srcu_retry_check_delay );
1724
+ if (srcu_max_nodelay != SRCU_DEFAULT_MAX_NODELAY )
1725
+ pr_info ("\tNon-default max no-delay of %lu.\n" , srcu_max_nodelay );
1726
+ pr_info ("\tMax phase no-delay instances is %lu.\n" , srcu_max_nodelay_phase );
1677
1727
return 0 ;
1678
1728
}
1679
1729
early_initcall (srcu_bootup_announce );
0 commit comments