···57585758 rcutorture.test_boost_duration= [KNL]57595759 Duration (s) of each individual boost test.5760576057615761+ rcutorture.test_boost_holdoff= [KNL]57625762+ Holdoff time (s) from start of test to the start57635763+ of RCU priority-boost testing. Defaults to zero,57645764+ that is, no holdoff.57655765+57615766 rcutorture.test_boost_interval= [KNL]57625767 Interval (s) between each boost test.57635768
···4747#define SRCU_READ_FLAVOR_NORMAL 0x1 // srcu_read_lock().4848#define SRCU_READ_FLAVOR_NMI 0x2 // srcu_read_lock_nmisafe().4949#define SRCU_READ_FLAVOR_LITE 0x4 // srcu_read_lock_lite().5050-#define SRCU_READ_FLAVOR_ALL 0x7 // All of the above.5050+#define SRCU_READ_FLAVOR_FAST 0x8 // srcu_read_lock_fast().5151+#define SRCU_READ_FLAVOR_ALL (SRCU_READ_FLAVOR_NORMAL | SRCU_READ_FLAVOR_NMI | \5252+ SRCU_READ_FLAVOR_LITE | SRCU_READ_FLAVOR_FAST) // All of the above.5353+#define SRCU_READ_FLAVOR_SLOWGP (SRCU_READ_FLAVOR_LITE | SRCU_READ_FLAVOR_FAST)5454+ // Flavors requiring synchronize_rcu()5555+ // instead of smp_mb().5656+void __srcu_read_unlock(struct srcu_struct *ssp, int idx) __releases(ssp);51575258#ifdef CONFIG_TINY_SRCU5359#include <linux/srcutiny.h>···6660void call_srcu(struct srcu_struct *ssp, struct rcu_head *head,6761 void (*func)(struct rcu_head *head));6862void cleanup_srcu_struct(struct srcu_struct *ssp);6969-int __srcu_read_lock(struct srcu_struct *ssp) __acquires(ssp);7070-void __srcu_read_unlock(struct srcu_struct *ssp, int idx) __releases(ssp);7171-#ifdef CONFIG_TINY_SRCU7272-#define __srcu_read_lock_lite __srcu_read_lock7373-#define __srcu_read_unlock_lite __srcu_read_unlock7474-#else // #ifdef CONFIG_TINY_SRCU7575-int __srcu_read_lock_lite(struct srcu_struct *ssp) __acquires(ssp);7676-void __srcu_read_unlock_lite(struct srcu_struct *ssp, int idx) __releases(ssp);7777-#endif // #else // #ifdef CONFIG_TINY_SRCU7863void synchronize_srcu(struct srcu_struct *ssp);79648065#define SRCU_GET_STATE_COMPLETED 0x1···255258}256259257260/**261261+ * srcu_read_lock_fast - register a new reader for an SRCU-protected structure.262262+ * @ssp: srcu_struct in which to register the new reader.263263+ *264264+ * Enter an SRCU read-side critical section, but for a light-weight265265+ * smp_mb()-free reader. See srcu_read_lock() for more information.266266+ *267267+ * If srcu_read_lock_fast() is ever used on an srcu_struct structure,268268+ * then none of the other flavors may be used, whether before, during,269269+ * or after. Note that grace-period auto-expediting is disabled for _fast270270+ * srcu_struct structures because auto-expedited grace periods invoke271271+ * synchronize_rcu_expedited(), IPIs and all.272272+ *273273+ * Note that srcu_read_lock_fast() can be invoked only from those contexts274274+ * where RCU is watching, that is, from contexts where it would be legal275275+ * to invoke rcu_read_lock(). Otherwise, lockdep will complain.276276+ */277277+static inline struct srcu_ctr __percpu *srcu_read_lock_fast(struct srcu_struct *ssp) __acquires(ssp)278278+{279279+ struct srcu_ctr __percpu *retval;280280+281281+ srcu_check_read_flavor_force(ssp, SRCU_READ_FLAVOR_FAST);282282+ retval = __srcu_read_lock_fast(ssp);283283+ rcu_try_lock_acquire(&ssp->dep_map);284284+ return retval;285285+}286286+287287+/**288288+ * srcu_down_read_fast - register a new reader for an SRCU-protected structure.289289+ * @ssp: srcu_struct in which to register the new reader.290290+ *291291+ * Enter a semaphore-like SRCU read-side critical section, but for292292+ * a light-weight smp_mb()-free reader. See srcu_read_lock_fast() and293293+ * srcu_down_read() for more information.294294+ *295295+ * The same srcu_struct may be used concurrently by srcu_down_read_fast()296296+ * and srcu_read_lock_fast().297297+ */298298+static inline struct srcu_ctr __percpu *srcu_down_read_fast(struct srcu_struct *ssp) __acquires(ssp)299299+{300300+ WARN_ON_ONCE(IS_ENABLED(CONFIG_PROVE_RCU) && in_nmi());301301+ srcu_check_read_flavor_force(ssp, SRCU_READ_FLAVOR_FAST);302302+ return __srcu_read_lock_fast(ssp);303303+}304304+305305+/**258306 * srcu_read_lock_lite - register a new reader for an SRCU-protected structure.259307 * @ssp: srcu_struct in which to register the new reader.260308 *···320278{321279 int retval;322280323323- srcu_check_read_flavor_lite(ssp);281281+ srcu_check_read_flavor_force(ssp, SRCU_READ_FLAVOR_LITE);324282 retval = __srcu_read_lock_lite(ssp);325283 rcu_try_lock_acquire(&ssp->dep_map);326284 return retval;···377335 * srcu_down_read() nor srcu_up_read() may be invoked from an NMI handler.378336 *379337 * Calls to srcu_down_read() may be nested, similar to the manner in380380- * which calls to down_read() may be nested.338338+ * which calls to down_read() may be nested. The same srcu_struct may be339339+ * used concurrently by srcu_down_read() and srcu_read_lock().381340 */382341static inline int srcu_down_read(struct srcu_struct *ssp) __acquires(ssp)383342{···404361}405362406363/**364364+ * srcu_read_unlock_fast - unregister a old reader from an SRCU-protected structure.365365+ * @ssp: srcu_struct in which to unregister the old reader.366366+ * @scp: return value from corresponding srcu_read_lock_fast().367367+ *368368+ * Exit a light-weight SRCU read-side critical section.369369+ */370370+static inline void srcu_read_unlock_fast(struct srcu_struct *ssp, struct srcu_ctr __percpu *scp)371371+ __releases(ssp)372372+{373373+ srcu_check_read_flavor(ssp, SRCU_READ_FLAVOR_FAST);374374+ srcu_lock_release(&ssp->dep_map);375375+ __srcu_read_unlock_fast(ssp, scp);376376+}377377+378378+/**379379+ * srcu_up_read_fast - unregister a old reader from an SRCU-protected structure.380380+ * @ssp: srcu_struct in which to unregister the old reader.381381+ * @scp: return value from corresponding srcu_read_lock_fast().382382+ *383383+ * Exit an SRCU read-side critical section, but not necessarily from384384+ * the same context as the maching srcu_down_read_fast().385385+ */386386+static inline void srcu_up_read_fast(struct srcu_struct *ssp, struct srcu_ctr __percpu *scp)387387+ __releases(ssp)388388+{389389+ WARN_ON_ONCE(IS_ENABLED(CONFIG_PROVE_RCU) && in_nmi());390390+ srcu_check_read_flavor(ssp, SRCU_READ_FLAVOR_FAST);391391+ __srcu_read_unlock_fast(ssp, scp);392392+}393393+394394+/**407395 * srcu_read_unlock_lite - unregister a old reader from an SRCU-protected structure.408396 * @ssp: srcu_struct in which to unregister the old reader.409409- * @idx: return value from corresponding srcu_read_lock().397397+ * @idx: return value from corresponding srcu_read_lock_lite().410398 *411399 * Exit a light-weight SRCU read-side critical section.412400 */···453379/**454380 * srcu_read_unlock_nmisafe - unregister a old reader from an SRCU-protected structure.455381 * @ssp: srcu_struct in which to unregister the old reader.456456- * @idx: return value from corresponding srcu_read_lock().382382+ * @idx: return value from corresponding srcu_read_lock_nmisafe().457383 *458384 * Exit an SRCU read-side critical section, but in an NMI-safe manner.459385 */
+27-2
include/linux/srcutiny.h
···6464{6565 int idx;66666767- preempt_disable(); // Needed for PREEMPT_AUTO6767+ preempt_disable(); // Needed for PREEMPT_LAZY6868 idx = ((READ_ONCE(ssp->srcu_idx) + 1) & 0x2) >> 1;6969 WRITE_ONCE(ssp->srcu_lock_nesting[idx], READ_ONCE(ssp->srcu_lock_nesting[idx]) + 1);7070 preempt_enable();7171 return idx;7272}7373+7474+struct srcu_ctr;7575+7676+static inline bool __srcu_ptr_to_ctr(struct srcu_struct *ssp, struct srcu_ctr __percpu *scpp)7777+{7878+ return (int)(intptr_t)(struct srcu_ctr __force __kernel *)scpp;7979+}8080+8181+static inline struct srcu_ctr __percpu *__srcu_ctr_to_ptr(struct srcu_struct *ssp, int idx)8282+{8383+ return (struct srcu_ctr __percpu *)(intptr_t)idx;8484+}8585+8686+static inline struct srcu_ctr __percpu *__srcu_read_lock_fast(struct srcu_struct *ssp)8787+{8888+ return __srcu_ctr_to_ptr(ssp, __srcu_read_lock(ssp));8989+}9090+9191+static inline void __srcu_read_unlock_fast(struct srcu_struct *ssp, struct srcu_ctr __percpu *scp)9292+{9393+ __srcu_read_unlock(ssp, __srcu_ptr_to_ctr(ssp, scp));9494+}9595+9696+#define __srcu_read_lock_lite __srcu_read_lock9797+#define __srcu_read_unlock_lite __srcu_read_unlock73987499static inline void synchronize_srcu_expedited(struct srcu_struct *ssp)75100{···10782}1088310984#define srcu_check_read_flavor(ssp, read_flavor) do { } while (0)110110-#define srcu_check_read_flavor_lite(ssp) do { } while (0)8585+#define srcu_check_read_flavor_force(ssp, read_flavor) do { } while (0)1118611287/* Defined here to avoid size increase for non-torture kernels. */11388static inline void srcu_torture_stats_print(struct srcu_struct *ssp,
+86-12
include/linux/srcutree.h
···1717struct srcu_node;1818struct srcu_struct;19192020+/* One element of the srcu_data srcu_ctrs array. */2121+struct srcu_ctr {2222+ atomic_long_t srcu_locks; /* Locks per CPU. */2323+ atomic_long_t srcu_unlocks; /* Unlocks per CPU. */2424+};2525+2026/*2127 * Per-CPU structure feeding into leaf srcu_node, similar in function2228 * to rcu_node.2329 */2430struct srcu_data {2531 /* Read-side state. */2626- atomic_long_t srcu_lock_count[2]; /* Locks per CPU. */2727- atomic_long_t srcu_unlock_count[2]; /* Unlocks per CPU. */3232+ struct srcu_ctr srcu_ctrs[2]; /* Locks and unlocks per CPU. */2833 int srcu_reader_flavor; /* Reader flavor for srcu_struct structure? */2934 /* Values: SRCU_READ_FLAVOR_.* */3035···10095 * Per-SRCU-domain structure, similar in function to rcu_state.10196 */10297struct srcu_struct {103103- unsigned int srcu_idx; /* Current rdr array element. */9898+ struct srcu_ctr __percpu *srcu_ctrp;10499 struct srcu_data __percpu *sda; /* Per-CPU srcu_data array. */105100 struct lockdep_map dep_map;106101 struct srcu_usage *srcu_sup; /* Update-side data. */···167162#define __SRCU_STRUCT_INIT(name, usage_name, pcpu_name) \168163{ \169164 .sda = &pcpu_name, \165165+ .srcu_ctrp = &pcpu_name.srcu_ctrs[0], \170166 __SRCU_STRUCT_INIT_COMMON(name, usage_name) \171167}172168···207201#define DEFINE_SRCU(name) __DEFINE_SRCU(name, /* not static */)208202#define DEFINE_STATIC_SRCU(name) __DEFINE_SRCU(name, static)209203204204+int __srcu_read_lock(struct srcu_struct *ssp) __acquires(ssp);210205void synchronize_srcu_expedited(struct srcu_struct *ssp);211206void srcu_barrier(struct srcu_struct *ssp);212207void srcu_torture_stats_print(struct srcu_struct *ssp, char *tt, char *tf);208208+209209+// Converts a per-CPU pointer to an ->srcu_ctrs[] array element to that210210+// element's index.211211+static inline bool __srcu_ptr_to_ctr(struct srcu_struct *ssp, struct srcu_ctr __percpu *scpp)212212+{213213+ return scpp - &ssp->sda->srcu_ctrs[0];214214+}215215+216216+// Converts an integer to a per-CPU pointer to the corresponding217217+// ->srcu_ctrs[] array element.218218+static inline struct srcu_ctr __percpu *__srcu_ctr_to_ptr(struct srcu_struct *ssp, int idx)219219+{220220+ return &ssp->sda->srcu_ctrs[idx];221221+}222222+223223+/*224224+ * Counts the new reader in the appropriate per-CPU element of the225225+ * srcu_struct. Returns a pointer that must be passed to the matching226226+ * srcu_read_unlock_fast().227227+ *228228+ * Note that both this_cpu_inc() and atomic_long_inc() are RCU read-side229229+ * critical sections either because they disables interrupts, because they230230+ * are a single instruction, or because they are a read-modify-write atomic231231+ * operation, depending on the whims of the architecture.232232+ *233233+ * This means that __srcu_read_lock_fast() is not all that fast234234+ * on architectures that support NMIs but do not supply NMI-safe235235+ * implementations of this_cpu_inc().236236+ */237237+static inline struct srcu_ctr __percpu *__srcu_read_lock_fast(struct srcu_struct *ssp)238238+{239239+ struct srcu_ctr __percpu *scp = READ_ONCE(ssp->srcu_ctrp);240240+241241+ RCU_LOCKDEP_WARN(!rcu_is_watching(), "RCU must be watching srcu_read_lock_fast().");242242+ if (!IS_ENABLED(CONFIG_NEED_SRCU_NMI_SAFE))243243+ this_cpu_inc(scp->srcu_locks.counter); /* Y */244244+ else245245+ atomic_long_inc(raw_cpu_ptr(&scp->srcu_locks)); /* Z */246246+ barrier(); /* Avoid leaking the critical section. */247247+ return scp;248248+}249249+250250+/*251251+ * Removes the count for the old reader from the appropriate252252+ * per-CPU element of the srcu_struct. Note that this may well be a253253+ * different CPU than that which was incremented by the corresponding254254+ * srcu_read_lock_fast(), but it must be within the same task.255255+ *256256+ * Note that both this_cpu_inc() and atomic_long_inc() are RCU read-side257257+ * critical sections either because they disables interrupts, because they258258+ * are a single instruction, or because they are a read-modify-write atomic259259+ * operation, depending on the whims of the architecture.260260+ *261261+ * This means that __srcu_read_unlock_fast() is not all that fast262262+ * on architectures that support NMIs but do not supply NMI-safe263263+ * implementations of this_cpu_inc().264264+ */265265+static inline void __srcu_read_unlock_fast(struct srcu_struct *ssp, struct srcu_ctr __percpu *scp)266266+{267267+ barrier(); /* Avoid leaking the critical section. */268268+ if (!IS_ENABLED(CONFIG_NEED_SRCU_NMI_SAFE))269269+ this_cpu_inc(scp->srcu_unlocks.counter); /* Z */270270+ else271271+ atomic_long_inc(raw_cpu_ptr(&scp->srcu_unlocks)); /* Z */272272+ RCU_LOCKDEP_WARN(!rcu_is_watching(), "RCU must be watching srcu_read_unlock_fast().");273273+}213274214275/*215276 * Counts the new reader in the appropriate per-CPU element of the···290217 */291218static inline int __srcu_read_lock_lite(struct srcu_struct *ssp)292219{293293- int idx;220220+ struct srcu_ctr __percpu *scp = READ_ONCE(ssp->srcu_ctrp);294221295222 RCU_LOCKDEP_WARN(!rcu_is_watching(), "RCU must be watching srcu_read_lock_lite().");296296- idx = READ_ONCE(ssp->srcu_idx) & 0x1;297297- this_cpu_inc(ssp->sda->srcu_lock_count[idx].counter); /* Y */223223+ this_cpu_inc(scp->srcu_locks.counter); /* Y */298224 barrier(); /* Avoid leaking the critical section. */299299- return idx;225225+ return __srcu_ptr_to_ctr(ssp, scp);300226}301227302228/*···312240static inline void __srcu_read_unlock_lite(struct srcu_struct *ssp, int idx)313241{314242 barrier(); /* Avoid leaking the critical section. */315315- this_cpu_inc(ssp->sda->srcu_unlock_count[idx].counter); /* Z */243243+ this_cpu_inc(__srcu_ctr_to_ptr(ssp, idx)->srcu_unlocks.counter); /* Z */316244 RCU_LOCKDEP_WARN(!rcu_is_watching(), "RCU must be watching srcu_read_unlock_lite().");317245}318246319247void __srcu_check_read_flavor(struct srcu_struct *ssp, int read_flavor);320248321321-// Record _lite() usage even for CONFIG_PROVE_RCU=n kernels.322322-static inline void srcu_check_read_flavor_lite(struct srcu_struct *ssp)249249+// Record reader usage even for CONFIG_PROVE_RCU=n kernels. This is250250+// needed only for flavors that require grace-period smp_mb() calls to be251251+// promoted to synchronize_rcu().252252+static inline void srcu_check_read_flavor_force(struct srcu_struct *ssp, int read_flavor)323253{324254 struct srcu_data *sdp = raw_cpu_ptr(ssp->sda);325255326326- if (likely(READ_ONCE(sdp->srcu_reader_flavor) & SRCU_READ_FLAVOR_LITE))256256+ if (likely(READ_ONCE(sdp->srcu_reader_flavor) & read_flavor))327257 return;328258329259 // Note that the cmpxchg() in __srcu_check_read_flavor() is fully ordered.330330- __srcu_check_read_flavor(ssp, SRCU_READ_FLAVOR_LITE);260260+ __srcu_check_read_flavor(ssp, read_flavor);331261}332262333263// Record non-_lite() usage only for CONFIG_PROVE_RCU=y kernels.
+1
include/linux/torture.h
···104104/* Initialization and cleanup. */105105bool torture_init_begin(char *ttype, int v);106106void torture_init_end(void);107107+unsigned long get_torture_init_jiffies(void);107108bool torture_cleanup_begin(void);108109void torture_cleanup_end(void);109110bool torture_must_stop(void);
···8080 */8181static noinstr void ct_kernel_exit_state(int offset)8282{8383- int seq;8484-8583 /*8684 * CPUs seeing atomic_add_return() must see prior RCU read-side8785 * critical sections, and we also must force ordering with the8886 * next idle sojourn.8987 */9088 rcu_task_trace_heavyweight_enter(); // Before CT state update!9191- seq = ct_state_inc(offset);9292- // RCU is no longer watching. Better be in extended quiescent state!9393- WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && (seq & CT_RCU_WATCHING));8989+ // RCU is still watching. Better not be in extended quiescent state!9090+ WARN_ON_ONCE(IS_ENABLED(CONFIG_RCU_EQS_DEBUG) && !rcu_is_watching_curr_cpu());9191+ (void)ct_state_inc(offset);9292+ // RCU is no longer watching.9493}95949695/*
+1-3
kernel/printk/printk.c
···24612461}24622462EXPORT_SYMBOL(_printk);2463246324642464-static bool pr_flush(int timeout_ms, bool reset_on_progress);24652464static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_progress);2466246524672466#else /* CONFIG_PRINTK */···2473247424742475static u64 syslog_seq;2475247624762476-static bool pr_flush(int timeout_ms, bool reset_on_progress) { return true; }24772477static bool __pr_flush(struct console *con, int timeout_ms, bool reset_on_progress) { return true; }2478247824792479#endif /* CONFIG_PRINTK */···44644466 * Context: Process context. May sleep while acquiring console lock.44654467 * Return: true if all usable printers are caught up.44664468 */44674467-static bool pr_flush(int timeout_ms, bool reset_on_progress)44694469+bool pr_flush(int timeout_ms, bool reset_on_progress)44684470{44694471 return __pr_flush(NULL, timeout_ms, reset_on_progress);44704472}
+13-2
kernel/rcu/Kconfig
···18181919config PREEMPT_RCU2020 bool2121- default y if PREEMPTION2121+ default y if (PREEMPT || PREEMPT_RT || PREEMPT_DYNAMIC)2222 select TREE_RCU2323 help2424 This option selects the RCU implementation that is···6565 help6666 This option selects the full-fledged version of SRCU.67676868+config FORCE_NEED_SRCU_NMI_SAFE6969+ bool "Force selection of NEED_SRCU_NMI_SAFE"7070+ depends on !TINY_SRCU7171+ select NEED_SRCU_NMI_SAFE7272+ default n7373+ help7474+ This option forces selection of the NEED_SRCU_NMI_SAFE7575+ Kconfig option, allowing testing of srcu_read_lock_nmisafe()7676+ and srcu_read_unlock_nmisafe() on architectures (like x86)7777+ that select the ARCH_HAS_NMI_SAFE_THIS_CPU_OPS Kconfig option.7878+6879config NEED_SRCU_NMI_SAFE6980 def_bool HAVE_NMI && !ARCH_HAS_NMI_SAFE_THIS_CPU_OPS && !TINY_SRCU7081···1029110392config TASKS_RCU10493 bool105105- default NEED_TASKS_RCU && (PREEMPTION || PREEMPT_AUTO)9494+ default NEED_TASKS_RCU && PREEMPTION10695 select IRQ_WORK1079610897config FORCE_TASKS_RUDE_RCU
+16-2
kernel/rcu/Kconfig.debug
···5454 Say N if you are unsure.55555656config RCU_TORTURE_TEST_CHK_RDR_STATE5757- tristate "Check rcutorture reader state"5757+ bool "Check rcutorture reader state"5858 depends on RCU_TORTURE_TEST5959 default n6060 help···7070 Say N if you are unsure.71717272config RCU_TORTURE_TEST_LOG_CPU7373- tristate "Log CPU for rcutorture failures"7373+ bool "Log CPU for rcutorture failures"7474 depends on RCU_TORTURE_TEST7575 default n7676 help···8282 less probable.83838484 Say Y here if you want CPU IDs logged.8585+ Say N if you are unsure.8686+8787+config RCU_TORTURE_TEST_LOG_GP8888+ bool "Log grace-period numbers for rcutorture failures"8989+ depends on RCU_TORTURE_TEST9090+ default n9191+ help9292+ This option causes rcutorture to decorate each entry of its9393+ log of failure/close-call rcutorture reader segments with the9494+ corresponding grace-period sequence numbers. This information9595+ can be useful, but it does incur additional overhead, overhead9696+ that can make both failures and close calls less probable.9797+9898+ Say Y here if you want grace-period sequence numbers logged.8599 Say N if you are unsure.8610087101config RCU_REF_SCALE_TEST
+9-4
kernel/rcu/rcu.h
···162162{163163 unsigned long cur_s = READ_ONCE(*sp);164164165165- return ULONG_CMP_GE(cur_s, s) || ULONG_CMP_LT(cur_s, s - (2 * RCU_SEQ_STATE_MASK + 1));165165+ return ULONG_CMP_GE(cur_s, s) || ULONG_CMP_LT(cur_s, s - (3 * RCU_SEQ_STATE_MASK + 1));166166}167167168168/*···590590#endif591591static inline void rcu_gp_set_torture_wait(int duration) { }592592#endif593593+unsigned long long rcutorture_gather_gp_seqs(void);594594+void rcutorture_format_gp_seqs(unsigned long long seqs, char *cp, size_t len);593595594596#ifdef CONFIG_TINY_SRCU595597···613611static inline bool rcu_watching_zero_in_eqs(int cpu, int *vp) { return false; }614612static inline unsigned long rcu_get_gp_seq(void) { return 0; }615613static inline unsigned long rcu_exp_batches_completed(void) { return 0; }616616-static inline unsigned long617617-srcu_batches_completed(struct srcu_struct *sp) { return 0; }618614static inline void rcu_force_quiescent_state(void) { }619615static inline bool rcu_check_boost_fail(unsigned long gp_state, int *cpup) { return true; }620616static inline void show_rcu_gp_kthreads(void) { }···624624bool rcu_watching_zero_in_eqs(int cpu, int *vp);625625unsigned long rcu_get_gp_seq(void);626626unsigned long rcu_exp_batches_completed(void);627627-unsigned long srcu_batches_completed(struct srcu_struct *sp);628627bool rcu_check_boost_fail(unsigned long gp_state, int *cpup);629628void show_rcu_gp_kthreads(void);630629int rcu_get_gp_kthreads_prio(void);···634635void rcu_gp_slow_register(atomic_t *rgssp);635636void rcu_gp_slow_unregister(atomic_t *rgssp);636637#endif /* #else #ifdef CONFIG_TINY_RCU */638638+639639+#ifdef CONFIG_TINY_SRCU640640+static inline unsigned long srcu_batches_completed(struct srcu_struct *sp) { return 0; }641641+#else // #ifdef CONFIG_TINY_SRCU642642+unsigned long srcu_batches_completed(struct srcu_struct *sp);643643+#endif // #else // #ifdef CONFIG_TINY_SRCU637644638645#ifdef CONFIG_RCU_NOCB_CPU639646void rcu_bind_current_to_nocb(void);
+110-14
kernel/rcu/rcutorture.c
···135135torture_param(int, stutter, 5, "Number of seconds to run/halt test");136136torture_param(int, test_boost, 1, "Test RCU prio boost: 0=no, 1=maybe, 2=yes.");137137torture_param(int, test_boost_duration, 4, "Duration of each boost test, seconds.");138138+torture_param(int, test_boost_holdoff, 0, "Holdoff time from rcutorture start, seconds.");138139torture_param(int, test_boost_interval, 7, "Interval between boost tests, seconds.");139140torture_param(int, test_nmis, 0, "End-test NMI tests, 0 to disable.");140141torture_param(bool, test_no_idle_hz, true, "Test support for tickless idle CPUs");···148147149148static int nrealnocbers;150149static int nrealreaders;150150+static int nrealfakewriters;151151static struct task_struct *writer_task;152152static struct task_struct **fakewriter_tasks;153153static struct task_struct **reader_tasks;···274272 bool rt_preempted;275273 int rt_cpu;276274 int rt_end_cpu;275275+ unsigned long long rt_gp_seq;276276+ unsigned long long rt_gp_seq_end;277277+ u64 rt_ts;277278};278279static int err_segs_recorded;279280static struct rt_read_seg err_segs[RCUTORTURE_RDR_MAX_SEGS];···411406 void (*gp_slow_register)(atomic_t *rgssp);412407 void (*gp_slow_unregister)(atomic_t *rgssp);413408 bool (*reader_blocked)(void);409409+ unsigned long long (*gather_gp_seqs)(void);410410+ void (*format_gp_seqs)(unsigned long long seqs, char *cp, size_t len);414411 long cbflood_max;415412 int irq_capable;416413 int can_boost;···617610 .reader_blocked = IS_ENABLED(CONFIG_RCU_TORTURE_TEST_LOG_CPU)618611 ? has_rcu_reader_blocked619612 : NULL,613613+ .gather_gp_seqs = rcutorture_gather_gp_seqs,614614+ .format_gp_seqs = rcutorture_format_gp_seqs,620615 .irq_capable = 1,621616 .can_boost = IS_ENABLED(CONFIG_RCU_BOOST),622617 .extendables = RCUTORTURE_MAX_EXTEND,···664655 .sync = synchronize_rcu_busted,665656 .exp_sync = synchronize_rcu_busted,666657 .call = call_rcu_busted,658658+ .gather_gp_seqs = rcutorture_gather_gp_seqs,659659+ .format_gp_seqs = rcutorture_format_gp_seqs,667660 .irq_capable = 1,668661 .extendables = RCUTORTURE_MAX_EXTEND,669662 .name = "busted"···688677static int srcu_torture_read_lock(void)689678{690679 int idx;680680+ struct srcu_ctr __percpu *scp;691681 int ret = 0;682682+683683+ WARN_ON_ONCE(reader_flavor & ~SRCU_READ_FLAVOR_ALL);692684693685 if ((reader_flavor & SRCU_READ_FLAVOR_NORMAL) || !(reader_flavor & SRCU_READ_FLAVOR_ALL)) {694686 idx = srcu_read_lock(srcu_ctlp);···707693 idx = srcu_read_lock_lite(srcu_ctlp);708694 WARN_ON_ONCE(idx & ~0x1);709695 ret += idx << 2;696696+ }697697+ if (reader_flavor & SRCU_READ_FLAVOR_FAST) {698698+ scp = srcu_read_lock_fast(srcu_ctlp);699699+ idx = __srcu_ptr_to_ctr(srcu_ctlp, scp);700700+ WARN_ON_ONCE(idx & ~0x1);701701+ ret += idx << 3;710702 }711703 return ret;712704}···739719static void srcu_torture_read_unlock(int idx)740720{741721 WARN_ON_ONCE((reader_flavor && (idx & ~reader_flavor)) || (!reader_flavor && (idx & ~0x1)));722722+ if (reader_flavor & SRCU_READ_FLAVOR_FAST)723723+ srcu_read_unlock_fast(srcu_ctlp, __srcu_ctr_to_ptr(srcu_ctlp, (idx & 0x8) >> 3));742724 if (reader_flavor & SRCU_READ_FLAVOR_LITE)743725 srcu_read_unlock_lite(srcu_ctlp, (idx & 0x4) >> 2);744726 if (reader_flavor & SRCU_READ_FLAVOR_NMI)···813791 .readunlock = srcu_torture_read_unlock,814792 .readlock_held = torture_srcu_read_lock_held,815793 .get_gp_seq = srcu_torture_completed,794794+ .gp_diff = rcu_seq_diff,816795 .deferred_free = srcu_torture_deferred_free,817796 .sync = srcu_torture_synchronize,818797 .exp_sync = srcu_torture_synchronize_expedited,···857834 .readunlock = srcu_torture_read_unlock,858835 .readlock_held = torture_srcu_read_lock_held,859836 .get_gp_seq = srcu_torture_completed,837837+ .gp_diff = rcu_seq_diff,860838 .deferred_free = srcu_torture_deferred_free,861839 .sync = srcu_torture_synchronize,862840 .exp_sync = srcu_torture_synchronize_expedited,···11721148 unsigned long gp_state;11731149 unsigned long gp_state_time;11741150 unsigned long oldstarttime;11511151+ unsigned long booststarttime = get_torture_init_jiffies() + test_boost_holdoff * HZ;1175115211761176- VERBOSE_TOROUT_STRING("rcu_torture_boost started");11531153+ if (test_boost_holdoff <= 0 || time_after(jiffies, booststarttime)) {11541154+ VERBOSE_TOROUT_STRING("rcu_torture_boost started");11551155+ } else {11561156+ VERBOSE_TOROUT_STRING("rcu_torture_boost started holdoff period");11571157+ while (time_before(jiffies, booststarttime)) {11581158+ schedule_timeout_idle(HZ);11591159+ if (kthread_should_stop())11601160+ goto cleanup;11611161+ }11621162+ VERBOSE_TOROUT_STRING("rcu_torture_boost finished holdoff period");11631163+ }1177116411781165 /* Set real-time priority. */11791166 sched_set_fifo_low(current);···12601225 sched_set_fifo_low(current);12611226 } while (!torture_must_stop());1262122712281228+cleanup:12631229 /* Clean up and exit. */12641230 while (!kthread_should_stop()) {12651231 torture_shutdown_absorb("rcu_torture_boost");···17641728 do {17651729 torture_hrtimeout_jiffies(torture_random(&rand) % 10, &rand);17661730 if (cur_ops->cb_barrier != NULL &&17671767- torture_random(&rand) % (nfakewriters * 8) == 0) {17311731+ torture_random(&rand) % (nrealfakewriters * 8) == 0) {17681732 cur_ops->cb_barrier();17691733 } else {17701734 switch (synctype[torture_random(&rand) % nsynctypes]) {···19091873#define ROEC_ARGS "%s %s: Current %#x To add %#x To remove %#x preempt_count() %#x\n", __func__, s, curstate, new, old, preempt_count()19101874static void rcutorture_one_extend_check(char *s, int curstate, int new, int old, bool insoftirq)19111875{18761876+ int mask;18771877+19121878 if (!IS_ENABLED(CONFIG_RCU_TORTURE_TEST_CHK_RDR_STATE))19131879 return;19141880···19371899 WARN_ONCE(cur_ops->extendables &&19381900 !(curstate & (RCUTORTURE_RDR_BH | RCUTORTURE_RDR_RBH)) &&19391901 (preempt_count() & SOFTIRQ_MASK), ROEC_ARGS);19401940- WARN_ONCE(cur_ops->extendables &&19411941- !(curstate & (RCUTORTURE_RDR_PREEMPT | RCUTORTURE_RDR_SCHED)) &&19021902+19031903+ /*19041904+ * non-preemptible RCU in a preemptible kernel uses preempt_disable()19051905+ * as rcu_read_lock().19061906+ */19071907+ mask = RCUTORTURE_RDR_PREEMPT | RCUTORTURE_RDR_SCHED;19081908+ if (!IS_ENABLED(CONFIG_PREEMPT_RCU))19091909+ mask |= RCUTORTURE_RDR_RCU_1 | RCUTORTURE_RDR_RCU_2;19101910+19111911+ WARN_ONCE(cur_ops->extendables && !(curstate & mask) &&19421912 (preempt_count() & PREEMPT_MASK), ROEC_ARGS);19431943- WARN_ONCE(cur_ops->readlock_nesting &&19441944- !(curstate & (RCUTORTURE_RDR_RCU_1 | RCUTORTURE_RDR_RCU_2)) &&19131913+19141914+ /*19151915+ * non-preemptible RCU in a preemptible kernel uses "preempt_count() &19161916+ * PREEMPT_MASK" as ->readlock_nesting().19171917+ */19181918+ mask = RCUTORTURE_RDR_RCU_1 | RCUTORTURE_RDR_RCU_2;19191919+ if (!IS_ENABLED(CONFIG_PREEMPT_RCU))19201920+ mask |= RCUTORTURE_RDR_PREEMPT | RCUTORTURE_RDR_SCHED;19211921+19221922+ WARN_ONCE(cur_ops->readlock_nesting && !(curstate & mask) &&19451923 cur_ops->readlock_nesting() > 0, ROEC_ARGS);19461924}19471925···20181964 if (cur_ops->reader_blocked)20191965 rtrsp[-1].rt_preempted = cur_ops->reader_blocked();20201966 }19671967+ }19681968+ // Sample grace-period sequence number, as good a place as any.19691969+ if (IS_ENABLED(CONFIG_RCU_TORTURE_TEST_LOG_GP) && cur_ops->gather_gp_seqs) {19701970+ rtrsp->rt_gp_seq = cur_ops->gather_gp_seqs();19711971+ rtrsp->rt_ts = ktime_get_mono_fast_ns();19721972+ if (!first)19731973+ rtrsp[-1].rt_gp_seq_end = rtrsp->rt_gp_seq;20211974 }2022197520231976 /*···25732512 "shuffle_interval=%d stutter=%d irqreader=%d "25742513 "fqs_duration=%d fqs_holdoff=%d fqs_stutter=%d "25752514 "test_boost=%d/%d test_boost_interval=%d "25762576- "test_boost_duration=%d shutdown_secs=%d "25152515+ "test_boost_duration=%d test_boost_holdoff=%d shutdown_secs=%d "25772516 "stall_cpu=%d stall_cpu_holdoff=%d stall_cpu_irqsoff=%d "25782517 "stall_cpu_block=%d stall_cpu_repeat=%d "25792518 "n_barrier_cbs=%d "···25832522 "nocbs_nthreads=%d nocbs_toggle=%d "25842523 "test_nmis=%d "25852524 "preempt_duration=%d preempt_interval=%d\n",25862586- torture_type, tag, nrealreaders, nfakewriters,25252525+ torture_type, tag, nrealreaders, nrealfakewriters,25872526 stat_interval, verbose, test_no_idle_hz, shuffle_interval,25882527 stutter, irqreader, fqs_duration, fqs_holdoff, fqs_stutter,25892528 test_boost, cur_ops->can_boost,25902590- test_boost_interval, test_boost_duration, shutdown_secs,25292529+ test_boost_interval, test_boost_duration, test_boost_holdoff, shutdown_secs,25912530 stall_cpu, stall_cpu_holdoff, stall_cpu_irqsoff,25922531 stall_cpu_block, stall_cpu_repeat,25932532 n_barrier_cbs,···36143553 int flags = 0;36153554 unsigned long gp_seq = 0;36163555 int i;35563556+ int j;3617355736183558 if (torture_cleanup_begin()) {36193559 if (cur_ops->cb_barrier != NULL) {···36593597 rcu_torture_reader_mbchk = NULL;3660359836613599 if (fakewriter_tasks) {36623662- for (i = 0; i < nfakewriters; i++)36003600+ for (i = 0; i < nrealfakewriters; i++)36633601 torture_stop_kthread(rcu_torture_fakewriter,36643602 fakewriter_tasks[i]);36653603 kfree(fakewriter_tasks);···36973635 pr_alert("\t: No segments recorded!!!\n");36983636 firsttime = 1;36993637 for (i = 0; i < rt_read_nsegs; i++) {37003700- pr_alert("\t%d: %#4x", i, err_segs[i].rt_readstate);36383638+ if (IS_ENABLED(CONFIG_RCU_TORTURE_TEST_LOG_GP))36393639+ pr_alert("\t%lluus ", div64_u64(err_segs[i].rt_ts, 1000ULL));36403640+ else36413641+ pr_alert("\t");36423642+ pr_cont("%d: %#4x", i, err_segs[i].rt_readstate);37013643 if (err_segs[i].rt_delay_jiffies != 0) {37023644 pr_cont("%s%ldjiffies", firsttime ? "" : "+",37033645 err_segs[i].rt_delay_jiffies);···37133647 pr_cont("->%-2d", err_segs[i].rt_end_cpu);37143648 else37153649 pr_cont(" ...");36503650+ }36513651+ if (IS_ENABLED(CONFIG_RCU_TORTURE_TEST_LOG_GP) &&36523652+ cur_ops->gather_gp_seqs && cur_ops->format_gp_seqs) {36533653+ char buf1[20+1];36543654+ char buf2[20+1];36553655+ char sepchar = '-';36563656+36573657+ cur_ops->format_gp_seqs(err_segs[i].rt_gp_seq,36583658+ buf1, ARRAY_SIZE(buf1));36593659+ cur_ops->format_gp_seqs(err_segs[i].rt_gp_seq_end,36603660+ buf2, ARRAY_SIZE(buf2));36613661+ if (err_segs[i].rt_gp_seq == err_segs[i].rt_gp_seq_end) {36623662+ if (buf2[0]) {36633663+ for (j = 0; buf2[j]; j++)36643664+ buf2[j] = '.';36653665+ if (j)36663666+ buf2[j - 1] = ' ';36673667+ }36683668+ sepchar = ' ';36693669+ }36703670+ pr_cont(" %s%c%s", buf1, sepchar, buf2);37163671 }37173672 if (err_segs[i].rt_delay_ms != 0) {37183673 pr_cont(" %s%ldms", firsttime ? "" : "+",···4081399440823995 rcu_torture_init_srcu_lockdep();4083399639973997+ if (nfakewriters >= 0) {39983998+ nrealfakewriters = nfakewriters;39993999+ } else {40004000+ nrealfakewriters = num_online_cpus() - 2 - nfakewriters;40014001+ if (nrealfakewriters <= 0)40024002+ nrealfakewriters = 1;40034003+ }40044004+40844005 if (nreaders >= 0) {40854006 nrealreaders = nreaders;40864007 } else {···41454050 writer_task);41464051 if (torture_init_error(firsterr))41474052 goto unwind;41484148- if (nfakewriters > 0) {41494149- fakewriter_tasks = kcalloc(nfakewriters,40534053+40544054+ if (nrealfakewriters > 0) {40554055+ fakewriter_tasks = kcalloc(nrealfakewriters,41504056 sizeof(fakewriter_tasks[0]),41514057 GFP_KERNEL);41524058 if (fakewriter_tasks == NULL) {···41564060 goto unwind;41574061 }41584062 }41594159- for (i = 0; i < nfakewriters; i++) {40634063+ for (i = 0; i < nrealfakewriters; i++) {41604064 firsterr = torture_create_kthread(rcu_torture_fakewriter,41614065 NULL, fakewriter_tasks[i]);41624066 if (torture_init_error(firsterr))
+31-1
kernel/rcu/refscale.c
···216216 .name = "srcu"217217};218218219219+static void srcu_fast_ref_scale_read_section(const int nloops)220220+{221221+ int i;222222+ struct srcu_ctr __percpu *scp;223223+224224+ for (i = nloops; i >= 0; i--) {225225+ scp = srcu_read_lock_fast(srcu_ctlp);226226+ srcu_read_unlock_fast(srcu_ctlp, scp);227227+ }228228+}229229+230230+static void srcu_fast_ref_scale_delay_section(const int nloops, const int udl, const int ndl)231231+{232232+ int i;233233+ struct srcu_ctr __percpu *scp;234234+235235+ for (i = nloops; i >= 0; i--) {236236+ scp = srcu_read_lock_fast(srcu_ctlp);237237+ un_delay(udl, ndl);238238+ srcu_read_unlock_fast(srcu_ctlp, scp);239239+ }240240+}241241+242242+static const struct ref_scale_ops srcu_fast_ops = {243243+ .init = rcu_sync_scale_init,244244+ .readsection = srcu_fast_ref_scale_read_section,245245+ .delaysection = srcu_fast_ref_scale_delay_section,246246+ .name = "srcu-fast"247247+};248248+219249static void srcu_lite_ref_scale_read_section(const int nloops)220250{221251 int i;···11931163 long i;11941164 int firsterr = 0;11951165 static const struct ref_scale_ops *scale_ops[] = {11961196- &rcu_ops, &srcu_ops, &srcu_lite_ops, RCU_TRACE_OPS RCU_TASKS_OPS11661166+ &rcu_ops, &srcu_ops, &srcu_fast_ops, &srcu_lite_ops, RCU_TRACE_OPS RCU_TASKS_OPS11971167 &refcnt_ops, &rwlock_ops, &rwsem_ops, &lock_ops, &lock_irq_ops,11981168 &acqrel_ops, &sched_clock_ops, &clock_ops, &jiffies_ops,11991169 &typesafe_ref_ops, &typesafe_lock_ops, &typesafe_seqlock_ops,
+13-7
kernel/rcu/srcutiny.c
···2020#include "rcu_segcblist.h"2121#include "rcu.h"22222323+#ifndef CONFIG_TREE_RCU2324int rcu_scheduler_active __read_mostly;2525+#else // #ifndef CONFIG_TREE_RCU2626+extern int rcu_scheduler_active;2727+#endif // #else // #ifndef CONFIG_TREE_RCU2428static LIST_HEAD(srcu_boot_list);2529static bool srcu_init_done;2630···10298{10399 int newval;104100105105- preempt_disable(); // Needed for PREEMPT_AUTO101101+ preempt_disable(); // Needed for PREEMPT_LAZY106102 newval = READ_ONCE(ssp->srcu_lock_nesting[idx]) - 1;107103 WRITE_ONCE(ssp->srcu_lock_nesting[idx], newval);108104 preempt_enable();···124120 struct srcu_struct *ssp;125121126122 ssp = container_of(wp, struct srcu_struct, srcu_work);127127- preempt_disable(); // Needed for PREEMPT_AUTO123123+ preempt_disable(); // Needed for PREEMPT_LAZY128124 if (ssp->srcu_gp_running || ULONG_CMP_GE(ssp->srcu_idx, READ_ONCE(ssp->srcu_idx_max))) {129125 preempt_enable();130126 return; /* Already running or nothing to do. */···142138 WRITE_ONCE(ssp->srcu_gp_waiting, true); /* srcu_read_unlock() wakes! */143139 preempt_enable();144140 swait_event_exclusive(ssp->srcu_wq, !READ_ONCE(ssp->srcu_lock_nesting[idx]));145145- preempt_disable(); // Needed for PREEMPT_AUTO141141+ preempt_disable(); // Needed for PREEMPT_LAZY146142 WRITE_ONCE(ssp->srcu_gp_waiting, false); /* srcu_read_unlock() cheap. */147143 WRITE_ONCE(ssp->srcu_idx, ssp->srcu_idx + 1);148144 preempt_enable();···163159 * at interrupt level, but the ->srcu_gp_running checks will164160 * straighten that out.165161 */166166- preempt_disable(); // Needed for PREEMPT_AUTO162162+ preempt_disable(); // Needed for PREEMPT_LAZY167163 WRITE_ONCE(ssp->srcu_gp_running, false);168164 idx = ULONG_CMP_LT(ssp->srcu_idx, READ_ONCE(ssp->srcu_idx_max));169165 preempt_enable();···176172{177173 unsigned long cookie;178174179179- preempt_disable(); // Needed for PREEMPT_AUTO175175+ preempt_disable(); // Needed for PREEMPT_LAZY180176 cookie = get_state_synchronize_srcu(ssp);181177 if (ULONG_CMP_GE(READ_ONCE(ssp->srcu_idx_max), cookie)) {182178 preempt_enable();···203199204200 rhp->func = func;205201 rhp->next = NULL;206206- preempt_disable(); // Needed for PREEMPT_AUTO202202+ preempt_disable(); // Needed for PREEMPT_LAZY207203 local_irq_save(flags);208204 *ssp->srcu_cb_tail = rhp;209205 ssp->srcu_cb_tail = &rhp->next;···265261{266262 unsigned long ret;267263268268- preempt_disable(); // Needed for PREEMPT_AUTO264264+ preempt_disable(); // Needed for PREEMPT_LAZY269265 ret = get_state_synchronize_srcu(ssp);270266 srcu_gp_start_if_needed(ssp);271267 preempt_enable();···286282}287283EXPORT_SYMBOL_GPL(poll_state_synchronize_srcu);288284285285+#ifndef CONFIG_TREE_RCU289286/* Lockdep diagnostics. */290287void __init rcu_scheduler_starting(void)291288{292289 rcu_scheduler_active = RCU_SCHEDULER_RUNNING;293290}291291+#endif // #ifndef CONFIG_TREE_RCU294292295293/*296294 * Queue work for srcu_struct structures with early boot callbacks.
+104-95
kernel/rcu/srcutree.c
···116116/*117117 * Initialize SRCU per-CPU data. Note that statically allocated118118 * srcu_struct structures might already have srcu_read_lock() and119119- * srcu_read_unlock() running against them. So if the is_static parameter120120- * is set, don't initialize ->srcu_lock_count[] and ->srcu_unlock_count[].119119+ * srcu_read_unlock() running against them. So if the is_static120120+ * parameter is set, don't initialize ->srcu_ctrs[].srcu_locks and121121+ * ->srcu_ctrs[].srcu_unlocks.121122 */122123static void init_srcu_struct_data(struct srcu_struct *ssp)123124{···129128 * Initialize the per-CPU srcu_data array, which feeds into the130129 * leaves of the srcu_node tree.131130 */132132- BUILD_BUG_ON(ARRAY_SIZE(sdp->srcu_lock_count) !=133133- ARRAY_SIZE(sdp->srcu_unlock_count));134131 for_each_possible_cpu(cpu) {135132 sdp = per_cpu_ptr(ssp->sda, cpu);136133 spin_lock_init(&ACCESS_PRIVATE(sdp, lock));···246247 ssp->srcu_sup->node = NULL;247248 mutex_init(&ssp->srcu_sup->srcu_cb_mutex);248249 mutex_init(&ssp->srcu_sup->srcu_gp_mutex);249249- ssp->srcu_idx = 0;250250 ssp->srcu_sup->srcu_gp_seq = SRCU_GP_SEQ_INITIAL_VAL;251251 ssp->srcu_sup->srcu_barrier_seq = 0;252252 mutex_init(&ssp->srcu_sup->srcu_barrier_mutex);253253 atomic_set(&ssp->srcu_sup->srcu_barrier_cpu_cnt, 0);254254 INIT_DELAYED_WORK(&ssp->srcu_sup->work, process_srcu);255255 ssp->srcu_sup->sda_is_static = is_static;256256- if (!is_static)256256+ if (!is_static) {257257 ssp->sda = alloc_percpu(struct srcu_data);258258+ ssp->srcu_ctrp = &ssp->sda->srcu_ctrs[0];259259+ }258260 if (!ssp->sda)259261 goto err_free_sup;260262 init_srcu_struct_data(ssp);···429429}430430431431/*432432- * Computes approximate total of the readers' ->srcu_lock_count[] values433433- * for the rank of per-CPU counters specified by idx, and returns true if434434- * the caller did the proper barrier (gp), and if the count of the locks435435- * matches that of the unlocks passed in.432432+ * Computes approximate total of the readers' ->srcu_ctrs[].srcu_locks433433+ * values for the rank of per-CPU counters specified by idx, and returns434434+ * true if the caller did the proper barrier (gp), and if the count of435435+ * the locks matches that of the unlocks passed in.436436 */437437static bool srcu_readers_lock_idx(struct srcu_struct *ssp, int idx, bool gp, unsigned long unlocks)438438{···443443 for_each_possible_cpu(cpu) {444444 struct srcu_data *sdp = per_cpu_ptr(ssp->sda, cpu);445445446446- sum += atomic_long_read(&sdp->srcu_lock_count[idx]);446446+ sum += atomic_long_read(&sdp->srcu_ctrs[idx].srcu_locks);447447 if (IS_ENABLED(CONFIG_PROVE_RCU))448448 mask = mask | READ_ONCE(sdp->srcu_reader_flavor);449449 }450450 WARN_ONCE(IS_ENABLED(CONFIG_PROVE_RCU) && (mask & (mask - 1)),451451 "Mixed reader flavors for srcu_struct at %ps.\n", ssp);452452- if (mask & SRCU_READ_FLAVOR_LITE && !gp)452452+ if (mask & SRCU_READ_FLAVOR_SLOWGP && !gp)453453 return false;454454 return sum == unlocks;455455}456456457457/*458458- * Returns approximate total of the readers' ->srcu_unlock_count[] values459459- * for the rank of per-CPU counters specified by idx.458458+ * Returns approximate total of the readers' ->srcu_ctrs[].srcu_unlocks459459+ * values for the rank of per-CPU counters specified by idx.460460 */461461static unsigned long srcu_readers_unlock_idx(struct srcu_struct *ssp, int idx, unsigned long *rdm)462462{···467467 for_each_possible_cpu(cpu) {468468 struct srcu_data *sdp = per_cpu_ptr(ssp->sda, cpu);469469470470- sum += atomic_long_read(&sdp->srcu_unlock_count[idx]);470470+ sum += atomic_long_read(&sdp->srcu_ctrs[idx].srcu_unlocks);471471 mask = mask | READ_ONCE(sdp->srcu_reader_flavor);472472 }473473 WARN_ONCE(IS_ENABLED(CONFIG_PROVE_RCU) && (mask & (mask - 1)),···487487 unsigned long unlocks;488488489489 unlocks = srcu_readers_unlock_idx(ssp, idx, &rdm);490490- did_gp = !!(rdm & SRCU_READ_FLAVOR_LITE);490490+ did_gp = !!(rdm & SRCU_READ_FLAVOR_SLOWGP);491491492492 /*493493 * Make sure that a lock is always counted if the corresponding···509509 * If the locks are the same as the unlocks, then there must have510510 * been no readers on this index at some point in this function.511511 * But there might be more readers, as a task might have read512512- * the current ->srcu_idx but not yet have incremented its CPU's513513- * ->srcu_lock_count[idx] counter. In fact, it is possible512512+ * the current ->srcu_ctrp but not yet have incremented its CPU's513513+ * ->srcu_ctrs[idx].srcu_locks counter. In fact, it is possible514514 * that most of the tasks have been preempted between fetching515515- * ->srcu_idx and incrementing ->srcu_lock_count[idx]. And there516516- * could be almost (ULONG_MAX / sizeof(struct task_struct)) tasks517517- * in a system whose address space was fully populated with memory.518518- * Call this quantity Nt.515515+ * ->srcu_ctrp and incrementing ->srcu_ctrs[idx].srcu_locks. And516516+ * there could be almost (ULONG_MAX / sizeof(struct task_struct))517517+ * tasks in a system whose address space was fully populated518518+ * with memory. Call this quantity Nt.519519 *520520- * So suppose that the updater is preempted at this point in the521521- * code for a long time. That now-preempted updater has already522522- * flipped ->srcu_idx (possibly during the preceding grace period),523523- * done an smp_mb() (again, possibly during the preceding grace524524- * period), and summed up the ->srcu_unlock_count[idx] counters.525525- * How many times can a given one of the aforementioned Nt tasks526526- * increment the old ->srcu_idx value's ->srcu_lock_count[idx]527527- * counter, in the absence of nesting?520520+ * So suppose that the updater is preempted at this521521+ * point in the code for a long time. That now-preempted522522+ * updater has already flipped ->srcu_ctrp (possibly during523523+ * the preceding grace period), done an smp_mb() (again,524524+ * possibly during the preceding grace period), and summed up525525+ * the ->srcu_ctrs[idx].srcu_unlocks counters. How many times526526+ * can a given one of the aforementioned Nt tasks increment the527527+ * old ->srcu_ctrp value's ->srcu_ctrs[idx].srcu_locks counter,528528+ * in the absence of nesting?528529 *529530 * It can clearly do so once, given that it has already fetched530530- * the old value of ->srcu_idx and is just about to use that value531531- * to index its increment of ->srcu_lock_count[idx]. But as soon as532532- * it leaves that SRCU read-side critical section, it will increment533533- * ->srcu_unlock_count[idx], which must follow the updater's above534534- * read from that same value. Thus, as soon the reading task does535535- * an smp_mb() and a later fetch from ->srcu_idx, that task will be536536- * guaranteed to get the new index. Except that the increment of537537- * ->srcu_unlock_count[idx] in __srcu_read_unlock() is after the538538- * smp_mb(), and the fetch from ->srcu_idx in __srcu_read_lock()539539- * is before the smp_mb(). Thus, that task might not see the new540540- * value of ->srcu_idx until the -second- __srcu_read_lock(),541541- * which in turn means that this task might well increment542542- * ->srcu_lock_count[idx] for the old value of ->srcu_idx twice,543543- * not just once.531531+ * the old value of ->srcu_ctrp and is just about to use that532532+ * value to index its increment of ->srcu_ctrs[idx].srcu_locks.533533+ * But as soon as it leaves that SRCU read-side critical section,534534+ * it will increment ->srcu_ctrs[idx].srcu_unlocks, which must535535+ * follow the updater's above read from that same value. Thus,536536+ as soon the reading task does an smp_mb() and a later fetch from537537+ * ->srcu_ctrp, that task will be guaranteed to get the new index.538538+ * Except that the increment of ->srcu_ctrs[idx].srcu_unlocks539539+ * in __srcu_read_unlock() is after the smp_mb(), and the fetch540540+ * from ->srcu_ctrp in __srcu_read_lock() is before the smp_mb().541541+ * Thus, that task might not see the new value of ->srcu_ctrp until542542+ * the -second- __srcu_read_lock(), which in turn means that this543543+ * task might well increment ->srcu_ctrs[idx].srcu_locks for the544544+ * old value of ->srcu_ctrp twice, not just once.544545 *545546 * However, it is important to note that a given smp_mb() takes546547 * effect not just for the task executing it, but also for any547548 * later task running on that same CPU.548549 *549549- * That is, there can be almost Nt + Nc further increments of550550- * ->srcu_lock_count[idx] for the old index, where Nc is the number551551- * of CPUs. But this is OK because the size of the task_struct552552- * structure limits the value of Nt and current systems limit Nc553553- * to a few thousand.550550+ * That is, there can be almost Nt + Nc further increments551551+ * of ->srcu_ctrs[idx].srcu_locks for the old index, where Nc552552+ * is the number of CPUs. But this is OK because the size of553553+ * the task_struct structure limits the value of Nt and current554554+ * systems limit Nc to a few thousand.554555 *555556 * OK, but what about nesting? This does impose a limit on556557 * nesting of half of the size of the task_struct structure···582581 for_each_possible_cpu(cpu) {583582 struct srcu_data *sdp = per_cpu_ptr(ssp->sda, cpu);584583585585- sum += atomic_long_read(&sdp->srcu_lock_count[0]);586586- sum += atomic_long_read(&sdp->srcu_lock_count[1]);587587- sum -= atomic_long_read(&sdp->srcu_unlock_count[0]);588588- sum -= atomic_long_read(&sdp->srcu_unlock_count[1]);584584+ sum += atomic_long_read(&sdp->srcu_ctrs[0].srcu_locks);585585+ sum += atomic_long_read(&sdp->srcu_ctrs[1].srcu_locks);586586+ sum -= atomic_long_read(&sdp->srcu_ctrs[0].srcu_unlocks);587587+ sum -= atomic_long_read(&sdp->srcu_ctrs[1].srcu_unlocks);589588 }590589 return sum;591590}···648647 unsigned long jbase = SRCU_INTERVAL;649648 struct srcu_usage *sup = ssp->srcu_sup;650649650650+ lockdep_assert_held(&ACCESS_PRIVATE(ssp->srcu_sup, lock));651651 if (srcu_gp_is_expedited(ssp))652652 jbase = 0;653653 if (rcu_seq_state(READ_ONCE(sup->srcu_gp_seq))) {···676674void cleanup_srcu_struct(struct srcu_struct *ssp)677675{678676 int cpu;677677+ unsigned long delay;679678 struct srcu_usage *sup = ssp->srcu_sup;680679681681- if (WARN_ON(!srcu_get_delay(ssp)))680680+ spin_lock_irq_rcu_node(ssp->srcu_sup);681681+ delay = srcu_get_delay(ssp);682682+ spin_unlock_irq_rcu_node(ssp->srcu_sup);683683+ if (WARN_ON(!delay))682684 return; /* Just leak it! */683685 if (WARN_ON(srcu_readers_active(ssp)))684686 return; /* Just leak it! */···749743 */750744int __srcu_read_lock(struct srcu_struct *ssp)751745{752752- int idx;746746+ struct srcu_ctr __percpu *scp = READ_ONCE(ssp->srcu_ctrp);753747754754- idx = READ_ONCE(ssp->srcu_idx) & 0x1;755755- this_cpu_inc(ssp->sda->srcu_lock_count[idx].counter);748748+ this_cpu_inc(scp->srcu_locks.counter);756749 smp_mb(); /* B */ /* Avoid leaking the critical section. */757757- return idx;750750+ return __srcu_ptr_to_ctr(ssp, scp);758751}759752EXPORT_SYMBOL_GPL(__srcu_read_lock);760753···765760void __srcu_read_unlock(struct srcu_struct *ssp, int idx)766761{767762 smp_mb(); /* C */ /* Avoid leaking the critical section. */768768- this_cpu_inc(ssp->sda->srcu_unlock_count[idx].counter);763763+ this_cpu_inc(__srcu_ctr_to_ptr(ssp, idx)->srcu_unlocks.counter);769764}770765EXPORT_SYMBOL_GPL(__srcu_read_unlock);771766···778773 */779774int __srcu_read_lock_nmisafe(struct srcu_struct *ssp)780775{781781- int idx;782782- struct srcu_data *sdp = raw_cpu_ptr(ssp->sda);776776+ struct srcu_ctr __percpu *scpp = READ_ONCE(ssp->srcu_ctrp);777777+ struct srcu_ctr *scp = raw_cpu_ptr(scpp);783778784784- idx = READ_ONCE(ssp->srcu_idx) & 0x1;785785- atomic_long_inc(&sdp->srcu_lock_count[idx]);779779+ atomic_long_inc(&scp->srcu_locks);786780 smp_mb__after_atomic(); /* B */ /* Avoid leaking the critical section. */787787- return idx;781781+ return __srcu_ptr_to_ctr(ssp, scpp);788782}789783EXPORT_SYMBOL_GPL(__srcu_read_lock_nmisafe);790784···794790 */795791void __srcu_read_unlock_nmisafe(struct srcu_struct *ssp, int idx)796792{797797- struct srcu_data *sdp = raw_cpu_ptr(ssp->sda);798798-799793 smp_mb__before_atomic(); /* C */ /* Avoid leaking the critical section. */800800- atomic_long_inc(&sdp->srcu_unlock_count[idx]);794794+ atomic_long_inc(&raw_cpu_ptr(__srcu_ctr_to_ptr(ssp, idx))->srcu_unlocks);801795}802796EXPORT_SYMBOL_GPL(__srcu_read_unlock_nmisafe);803797···10981096/*10991097 * Wait until all readers counted by array index idx complete, but11001098 * loop an additional time if there is an expedited grace period pending.11011101- * The caller must ensure that ->srcu_idx is not changed while checking.10991099+ * The caller must ensure that ->srcu_ctrp is not changed while checking.11021100 */11031101static bool try_check_zero(struct srcu_struct *ssp, int idx, int trycount)11041102{11051103 unsigned long curdelay;1106110411051105+ spin_lock_irq_rcu_node(ssp->srcu_sup);11071106 curdelay = !srcu_get_delay(ssp);11071107+ spin_unlock_irq_rcu_node(ssp->srcu_sup);1108110811091109 for (;;) {11101110 if (srcu_readers_active_idx_check(ssp, idx))···11181114}1119111511201116/*11211121- * Increment the ->srcu_idx counter so that future SRCU readers will11171117+ * Increment the ->srcu_ctrp counter so that future SRCU readers will11221118 * use the other rank of the ->srcu_(un)lock_count[] arrays. This allows11231119 * us to wait for pre-existing readers in a starvation-free manner.11241120 */11251121static void srcu_flip(struct srcu_struct *ssp)11261122{11271123 /*11281128- * Because the flip of ->srcu_idx is executed only if the11241124+ * Because the flip of ->srcu_ctrp is executed only if the11291125 * preceding call to srcu_readers_active_idx_check() found that11301130- * the ->srcu_unlock_count[] and ->srcu_lock_count[] sums matched11311131- * and because that summing uses atomic_long_read(), there is11321132- * ordering due to a control dependency between that summing and11331133- * the WRITE_ONCE() in this call to srcu_flip(). This ordering11341134- * ensures that if this updater saw a given reader's increment from11351135- * __srcu_read_lock(), that reader was using a value of ->srcu_idx11361136- * from before the previous call to srcu_flip(), which should be11371137- * quite rare. This ordering thus helps forward progress because11381138- * the grace period could otherwise be delayed by additional11391139- * calls to __srcu_read_lock() using that old (soon to be new)11401140- * value of ->srcu_idx.11261126+ * the ->srcu_ctrs[].srcu_unlocks and ->srcu_ctrs[].srcu_locks sums11271127+ * matched and because that summing uses atomic_long_read(),11281128+ * there is ordering due to a control dependency between that11291129+ * summing and the WRITE_ONCE() in this call to srcu_flip().11301130+ * This ordering ensures that if this updater saw a given reader's11311131+ * increment from __srcu_read_lock(), that reader was using a value11321132+ * of ->srcu_ctrp from before the previous call to srcu_flip(),11331133+ * which should be quite rare. This ordering thus helps forward11341134+ * progress because the grace period could otherwise be delayed11351135+ * by additional calls to __srcu_read_lock() using that old (soon11361136+ * to be new) value of ->srcu_ctrp.11411137 *11421138 * This sum-equality check and ordering also ensures that if11431139 * a given call to __srcu_read_lock() uses the new value of11441144- * ->srcu_idx, this updater's earlier scans cannot have seen11401140+ * ->srcu_ctrp, this updater's earlier scans cannot have seen11451141 * that reader's increments, which is all to the good, because11461142 * this grace period need not wait on that reader. After all,11471143 * if those earlier scans had seen that reader, there would have···11561152 */11571153 smp_mb(); /* E */ /* Pairs with B and C. */1158115411591159- WRITE_ONCE(ssp->srcu_idx, ssp->srcu_idx + 1); // Flip the counter.11551155+ WRITE_ONCE(ssp->srcu_ctrp,11561156+ &ssp->sda->srcu_ctrs[!(ssp->srcu_ctrp - &ssp->sda->srcu_ctrs[0])]);1160115711611158 /*11621159 * Ensure that if the updater misses an __srcu_read_unlock()···1203119812041199 check_init_srcu_struct(ssp);12051200 /* If _lite() readers, don't do unsolicited expediting. */12061206- if (this_cpu_read(ssp->sda->srcu_reader_flavor) & SRCU_READ_FLAVOR_LITE)12011201+ if (this_cpu_read(ssp->sda->srcu_reader_flavor) & SRCU_READ_FLAVOR_SLOWGP)12071202 return false;12081203 /* If the local srcu_data structure has callbacks, not idle. */12091204 sdp = raw_cpu_ptr(ssp->sda);···14741469 *14751470 * Wait for the count to drain to zero of both indexes. To avoid the14761471 * possible starvation of synchronize_srcu(), it waits for the count of14771477- * the index=((->srcu_idx & 1) ^ 1) to drain to zero at first,14781478- * and then flip the srcu_idx and wait for the count of the other index.14721472+ * the index=!(ssp->srcu_ctrp - &ssp->sda->srcu_ctrs[0]) to drain to zero14731473+ * at first, and then flip the ->srcu_ctrp and wait for the count of the14741474+ * other index.14791475 *14801476 * Can block; must be called from process context.14811477 *···16851679 */16861680unsigned long srcu_batches_completed(struct srcu_struct *ssp)16871681{16881688- return READ_ONCE(ssp->srcu_idx);16821682+ return READ_ONCE(ssp->srcu_sup->srcu_gp_seq);16891683}16901684EXPORT_SYMBOL_GPL(srcu_batches_completed);16911685···1702169617031697 /*17041698 * Because readers might be delayed for an extended period after17051705- * fetching ->srcu_idx for their index, at any point in time there16991699+ * fetching ->srcu_ctrp for their index, at any point in time there17061700 * might well be readers using both idx=0 and idx=1. We therefore17071701 * need to wait for readers to clear from both index values before17081702 * invoking a callback.···17301724 }1731172517321726 if (rcu_seq_state(READ_ONCE(ssp->srcu_sup->srcu_gp_seq)) == SRCU_STATE_SCAN1) {17331733- idx = 1 ^ (ssp->srcu_idx & 1);17271727+ idx = !(ssp->srcu_ctrp - &ssp->sda->srcu_ctrs[0]);17341728 if (!try_check_zero(ssp, idx, 1)) {17351729 mutex_unlock(&ssp->srcu_sup->srcu_gp_mutex);17361730 return; /* readers present, retry later. */···17481742 * SRCU read-side critical sections are normally short,17491743 * so check at least twice in quick succession after a flip.17501744 */17511751- idx = 1 ^ (ssp->srcu_idx & 1);17451745+ idx = !(ssp->srcu_ctrp - &ssp->sda->srcu_ctrs[0]);17521746 if (!try_check_zero(ssp, idx, 2)) {17531747 mutex_unlock(&ssp->srcu_sup->srcu_gp_mutex);17541748 return; /* readers present, retry later. */···18591853 ssp = sup->srcu_ssp;1860185418611855 srcu_advance_state(ssp);18561856+ spin_lock_irq_rcu_node(ssp->srcu_sup);18621857 curdelay = srcu_get_delay(ssp);18581858+ spin_unlock_irq_rcu_node(ssp->srcu_sup);18631859 if (curdelay) {18641860 WRITE_ONCE(sup->reschedule_count, 0);18651861 } else {···19081900 int ss_state = READ_ONCE(ssp->srcu_sup->srcu_size_state);19091901 int ss_state_idx = ss_state;1910190219111911- idx = ssp->srcu_idx & 0x1;19031903+ idx = ssp->srcu_ctrp - &ssp->sda->srcu_ctrs[0];19121904 if (ss_state < 0 || ss_state >= ARRAY_SIZE(srcu_size_state_name))19131905 ss_state_idx = ARRAY_SIZE(srcu_size_state_name) - 1;19141906 pr_alert("%s%s Tree SRCU g%ld state %d (%s)",···19261918 struct srcu_data *sdp;1927191919281920 sdp = per_cpu_ptr(ssp->sda, cpu);19291929- u0 = data_race(atomic_long_read(&sdp->srcu_unlock_count[!idx]));19301930- u1 = data_race(atomic_long_read(&sdp->srcu_unlock_count[idx]));19211921+ u0 = data_race(atomic_long_read(&sdp->srcu_ctrs[!idx].srcu_unlocks));19221922+ u1 = data_race(atomic_long_read(&sdp->srcu_ctrs[idx].srcu_unlocks));1931192319321924 /*19331925 * Make sure that a lock is always counted if the corresponding···19351927 */19361928 smp_rmb();1937192919381938- l0 = data_race(atomic_long_read(&sdp->srcu_lock_count[!idx]));19391939- l1 = data_race(atomic_long_read(&sdp->srcu_lock_count[idx]));19301930+ l0 = data_race(atomic_long_read(&sdp->srcu_ctrs[!idx].srcu_locks));19311931+ l1 = data_race(atomic_long_read(&sdp->srcu_ctrs[idx].srcu_locks));1940193219411933 c0 = l0 - u0;19421934 c1 = l1 - u1;···20132005 ssp->sda = alloc_percpu(struct srcu_data);20142006 if (WARN_ON_ONCE(!ssp->sda))20152007 return -ENOMEM;20082008+ ssp->srcu_ctrp = &ssp->sda->srcu_ctrs[0];20162009 }20172010 return 0;20182011}
+4-1
kernel/rcu/tasks.h
···22562256#endif22572257}2258225822592259-void __init rcu_init_tasks_generic(void)22592259+static int __init rcu_init_tasks_generic(void)22602260{22612261#ifdef CONFIG_TASKS_RCU22622262 rcu_spawn_tasks_kthread();···2272227222732273 // Run the self-tests.22742274 rcu_tasks_initiate_self_tests();22752275+22762276+ return 0;22752277}22782278+core_initcall(rcu_init_tasks_generic);2276227922772280#else /* #ifdef CONFIG_TASKS_RCU_GENERIC */22782281static inline void rcu_tasks_bootup_oddness(void) {}
+14
kernel/rcu/tiny.c
···257257EXPORT_SYMBOL_GPL(kvfree_call_rcu);258258#endif259259260260+#if IS_ENABLED(CONFIG_RCU_TORTURE_TEST)261261+unsigned long long rcutorture_gather_gp_seqs(void)262262+{263263+ return READ_ONCE(rcu_ctrlblk.gp_seq) & 0xffffULL;264264+}265265+EXPORT_SYMBOL_GPL(rcutorture_gather_gp_seqs);266266+267267+void rcutorture_format_gp_seqs(unsigned long long seqs, char *cp, size_t len)268268+{269269+ snprintf(cp, len, "g%04llx", seqs & 0xffffULL);270270+}271271+EXPORT_SYMBOL_GPL(rcutorture_format_gp_seqs);272272+#endif273273+260274void __init rcu_init(void)261275{262276 open_softirq(RCU_SOFTIRQ, rcu_process_callbacks);
+37-12
kernel/rcu/tree.c
···538538}539539EXPORT_SYMBOL_GPL(rcutorture_get_gp_data);540540541541+/* Gather grace-period sequence numbers for rcutorture diagnostics. */542542+unsigned long long rcutorture_gather_gp_seqs(void)543543+{544544+ return ((READ_ONCE(rcu_state.gp_seq) & 0xffffULL) << 40) |545545+ ((READ_ONCE(rcu_state.expedited_sequence) & 0xffffffULL) << 16) |546546+ (READ_ONCE(rcu_state.gp_seq_polled) & 0xffffULL);547547+}548548+EXPORT_SYMBOL_GPL(rcutorture_gather_gp_seqs);549549+550550+/* Format grace-period sequence numbers for rcutorture diagnostics. */551551+void rcutorture_format_gp_seqs(unsigned long long seqs, char *cp, size_t len)552552+{553553+ unsigned int egp = (seqs >> 16) & 0xffffffULL;554554+ unsigned int ggp = (seqs >> 40) & 0xffffULL;555555+ unsigned int pgp = seqs & 0xffffULL;556556+557557+ snprintf(cp, len, "g%04x:e%06x:p%04x", ggp, egp, pgp);558558+}559559+EXPORT_SYMBOL_GPL(rcutorture_format_gp_seqs);560560+541561#if defined(CONFIG_NO_HZ_FULL) && (!defined(CONFIG_GENERIC_ENTRY) || !defined(CONFIG_KVM_XFER_TO_GUEST_WORK))542562/*543563 * An empty function that will trigger a reschedule on···1274125412751255 /* Handle the ends of any preceding grace periods first. */12761256 if (rcu_seq_completed_gp(rdp->gp_seq, rnp->gp_seq) ||12771277- unlikely(READ_ONCE(rdp->gpwrap))) {12571257+ unlikely(rdp->gpwrap)) {12781258 if (!offloaded)12791259 ret = rcu_advance_cbs(rnp, rdp); /* Advance CBs. */12801260 rdp->core_needs_qs = false;···1288126812891269 /* Now handle the beginnings of any new-to-this-CPU grace periods. */12901270 if (rcu_seq_new_gp(rdp->gp_seq, rnp->gp_seq) ||12911291- unlikely(READ_ONCE(rdp->gpwrap))) {12711271+ unlikely(rdp->gpwrap)) {12921272 /*12931273 * If the current grace period is waiting for this CPU,12941274 * set up to detect a quiescent state, otherwise don't···13031283 rdp->gp_seq = rnp->gp_seq; /* Remember new grace-period state. */13041284 if (ULONG_CMP_LT(rdp->gp_seq_needed, rnp->gp_seq_needed) || rdp->gpwrap)13051285 WRITE_ONCE(rdp->gp_seq_needed, rnp->gp_seq_needed);13061306- if (IS_ENABLED(CONFIG_PROVE_RCU) && READ_ONCE(rdp->gpwrap))12861286+ if (IS_ENABLED(CONFIG_PROVE_RCU) && rdp->gpwrap)13071287 WRITE_ONCE(rdp->last_sched_clock, jiffies);13081288 WRITE_ONCE(rdp->gpwrap, false);13091289 rcu_gpnum_ovf(rnp, rdp);···16321612{16331613 struct rcu_synchronize *rs = container_of(16341614 (struct rcu_head *) node, struct rcu_synchronize, head);16351635- unsigned long oldstate = (unsigned long) rs->head.func;1636161516371616 WARN_ONCE(IS_ENABLED(CONFIG_PROVE_RCU) &&16381638- !poll_state_synchronize_rcu(oldstate),16391639- "A full grace period is not passed yet: %lu",16401640- rcu_seq_diff(get_state_synchronize_rcu(), oldstate));16171617+ !poll_state_synchronize_rcu_full(&rs->oldstate),16181618+ "A full grace period is not passed yet!\n");1641161916421620 /* Finally. */16431621 complete(&rs->completion);···1819180118201802 /* Advance to a new grace period and initialize state. */18211803 record_gp_stall_check_time();18041804+ /*18051805+ * A new wait segment must be started before gp_seq advanced, so18061806+ * that previous gp waiters won't observe the new gp_seq.18071807+ */18081808+ start_new_poll = rcu_sr_normal_gp_init();18221809 /* Record GP times before starting GP, hence rcu_seq_start(). */18231810 rcu_seq_start(&rcu_state.gp_seq);18241811 ASSERT_EXCLUSIVE_WRITER(rcu_state.gp_seq);18251825- start_new_poll = rcu_sr_normal_gp_init();18261812 trace_rcu_grace_period(rcu_state.name, rcu_state.gp_seq, TPS("start"));18271813 rcu_poll_gp_seq_start(&rcu_state.gp_seq_polled_snap);18281814 raw_spin_unlock_irq_rcu_node(rnp);···32493227 * snapshot before adding a request.32503228 */32513229 if (IS_ENABLED(CONFIG_PROVE_RCU))32523252- rs.head.func = (void *) get_state_synchronize_rcu();32303230+ get_state_synchronize_rcu_full(&rs.oldstate);3253323132543232 rcu_sr_normal_add_req(&rs);32553233···33923370 */33933371void get_state_synchronize_rcu_full(struct rcu_gp_oldstate *rgosp)33943372{33953395- struct rcu_node *rnp = rcu_get_root();33963396-33973373 /*33983374 * Any prior manipulation of RCU-protected data must happen33993375 * before the loads from ->gp_seq and ->expedited_sequence.34003376 */34013377 smp_mb(); /* ^^^ */34023402- rgosp->rgos_norm = rcu_seq_snap(&rnp->gp_seq);33783378+33793379+ // Yes, rcu_state.gp_seq, not rnp_root->gp_seq, the latter's use33803380+ // in poll_state_synchronize_rcu_full() notwithstanding. Use of33813381+ // the latter here would result in too-short grace periods due to33823382+ // interactions with newly onlined CPUs.33833383+ rgosp->rgos_norm = rcu_seq_snap(&rcu_state.gp_seq);34033384 rgosp->rgos_exp = rcu_seq_snap(&rcu_state.expedited_sequence);34043385}34053386EXPORT_SYMBOL_GPL(get_state_synchronize_rcu_full);
+4-2
kernel/rcu/tree_exp.h
···230230 * specified leaf rcu_node structure, which is acquired by the caller.231231 */232232static void rcu_report_exp_cpu_mult(struct rcu_node *rnp, unsigned long flags,233233- unsigned long mask, bool wake)233233+ unsigned long mask_in, bool wake)234234 __releases(rnp->lock)235235{236236 int cpu;237237+ unsigned long mask;237238 struct rcu_data *rdp;238239239240 raw_lockdep_assert_held_rcu_node(rnp);240240- if (!(rnp->expmask & mask)) {241241+ if (!(rnp->expmask & mask_in)) {241242 raw_spin_unlock_irqrestore_rcu_node(rnp, flags);242243 return;243244 }245245+ mask = mask_in & rnp->expmask;244246 WRITE_ONCE(rnp->expmask, rnp->expmask & ~mask);245247 for_each_leaf_node_cpu_mask(rnp, cpu, mask) {246248 rdp = per_cpu_ptr(&rcu_data, cpu);
···833833{834834 struct rcu_data *rdp;835835836836- if (irqs_disabled() || preempt_count() || !rcu_state.gp_kthread)836836+ if (irqs_disabled() || in_atomic_preempt_off() || !rcu_state.gp_kthread)837837 return;838838+839839+ /*840840+ * rcu_report_qs_rdp() can only be invoked with a stable rdp and841841+ * from the local CPU.842842+ *843843+ * The in_atomic_preempt_off() check ensures that we come here holding844844+ * the last preempt_count (which will get dropped once we return to845845+ * __rcu_read_unlock().846846+ */838847 rdp = this_cpu_ptr(&rcu_data);839848 rdp->cpu_no_qs.b.norm = false;840849 rcu_report_qs_rdp(rdp);···984975 */985976static void rcu_flavor_sched_clock_irq(int user)986977{987987- if (user || rcu_is_cpu_rrupt_from_idle()) {978978+ if (user || rcu_is_cpu_rrupt_from_idle() ||979979+ (IS_ENABLED(CONFIG_PREEMPT_COUNT) &&980980+ (preempt_count() == HARDIRQ_OFFSET))) {988981989982 /*990983 * Get here if this CPU took its interrupt from user991991- * mode or from the idle loop, and if this is not a992992- * nested interrupt. In this case, the CPU is in993993- * a quiescent state, so note it.984984+ * mode, from the idle loop without this being a nested985985+ * interrupt, or while not holding the task preempt count986986+ * (with PREEMPT_COUNT=y). In this case, the CPU is in a987987+ * quiescent state, so note it.994988 *995989 * No memory barrier is required here because rcu_qs()996990 * references only CPU-local variables that other CPUs
···72897289 return 1;72907290 }72917291 /*72927292- * In preemptible kernels, ->rcu_read_lock_nesting tells the tick72927292+ * In PREEMPT_RCU kernels, ->rcu_read_lock_nesting tells the tick72937293 * whether the current CPU is in an RCU read-side critical section,72947294 * so the tick can report quiescent states even for CPUs looping72957295 * in kernel context. In contrast, in non-preemptible kernels,···72987298 * RCU quiescent state. Therefore, the following code causes72997299 * cond_resched() to report a quiescent state, but only when RCU73007300 * is in urgent need of one.73017301+ * A third case, preemptible, but non-PREEMPT_RCU provides for73027302+ * urgently needed quiescent states via rcu_flavor_sched_clock_irq().73017303 */73027304#ifndef CONFIG_PREEMPT_RCU73037305 rcu_all_qs();
+12
kernel/torture.c
···792792 stutter_task = NULL;793793}794794795795+static unsigned long torture_init_jiffies;796796+795797static void796798torture_print_module_parms(void)797799{···823821 torture_type = ttype;824822 verbose = v;825823 fullstop = FULLSTOP_DONTSTOP;824824+ WRITE_ONCE(torture_init_jiffies, jiffies); // Lockless reads.826825 torture_print_module_parms();827826 return true;828827}···838835 register_reboot_notifier(&torture_shutdown_nb);839836}840837EXPORT_SYMBOL_GPL(torture_init_end);838838+839839+/*840840+ * Get the torture_init_begin()-time value of the jiffies counter.841841+ */842842+unsigned long get_torture_init_jiffies(void)843843+{844844+ return READ_ONCE(torture_init_jiffies);845845+}846846+EXPORT_SYMBOL_GPL(get_torture_init_jiffies);841847842848/*843849 * Clean up torture module. Please note that this is -not- invoked via
+15-17
kernel/trace/trace_osnoise.c
···1542154215431543 /*15441544 * In some cases, notably when running on a nohz_full CPU with15451545- * a stopped tick PREEMPT_RCU has no way to account for QSs.15461546- * This will eventually cause unwarranted noise as PREEMPT_RCU15471547- * will force preemption as the means of ending the current15481548- * grace period. We avoid this problem by calling15491549- * rcu_momentary_eqs(), which performs a zero duration15501550- * EQS allowing PREEMPT_RCU to end the current grace period.15511551- * This call shouldn't be wrapped inside an RCU critical15521552- * section.15451545+ * a stopped tick PREEMPT_RCU or PREEMPT_LAZY have no way to15461546+ * account for QSs. This will eventually cause unwarranted15471547+ * noise as RCU forces preemption as the means of ending the15481548+ * current grace period. We avoid this by calling15491549+ * rcu_momentary_eqs(), which performs a zero duration EQS15501550+ * allowing RCU to end the current grace period. This call15511551+ * shouldn't be wrapped inside an RCU critical section.15531552 *15541554- * Note that in non PREEMPT_RCU kernels QSs are handled through15551555- * cond_resched()15531553+ * Normally QSs for other cases are handled through cond_resched().15541554+ * For simplicity, however, we call rcu_momentary_eqs() for all15551555+ * configurations here.15561556 */15571557- if (IS_ENABLED(CONFIG_PREEMPT_RCU)) {15581558- if (!disable_irq)15591559- local_irq_disable();15571557+ if (!disable_irq)15581558+ local_irq_disable();1560155915611561- rcu_momentary_eqs();15601560+ rcu_momentary_eqs();1562156115631563- if (!disable_irq)15641564- local_irq_enable();15651565- }15621562+ if (!disable_irq)15631563+ local_irq_enable();1566156415671565 /*15681566 * For the non-preemptive kernel config: let threads runs, if
···22rcutree.gp_init_delay=333rcutree.gp_cleanup_delay=344rcupdate.rcu_self_test=155+66+# This part is for synchronize_rcu() testing77+rcutorture.nfakewriters=-188+rcutorture.gp_sync=199+rcupdate.rcu_normal=11010+rcutree.rcu_normal_wake_from_gp=1