Skip to contentSkip to conversation

RCU changes for v4.2

GIT PULL Ingo Molnar 1 participant 1 message Jun 22, 2015

Subsystems (14)
Documentation x86 PowerPC Kselftest +10 more subsystems
lore
Share & tools
lore
#0 lore raw

Linus,

Please pull the latest core-rcu-for-linus git tree from:

git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git core-rcu-for-linus

# HEAD: 085c789783f5f95c253740d3d0a1659ec5ff32a8 Merge branch 'for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu into core/rcu

- Continued initialization/Kconfig updates: hide most Kconfig options from unsuspecting users. There's now a single high level configuration option:

*
* RCU Subsystem
*
Make expert-level adjustments to RCU configuration (RCU_EXPERT) [N/y/?] (NEW)

Which if answered in the negative, leaves us with a single interactive configuration option:

Offload RCU callback processing from boot-selected CPUs (RCU_NOCB_CPU) [N/y/?] (NEW)

All the rest of the RCU options are configured automatically. Later on we'll remove this single leftover configuration option as well.

- Remove all uses of RCU-protected array indexes: replace the rcu_[access|dereference]_index_check() APIs with READ_ONCE() and rcu_lockdep_assert().

- RCU CPU-hotplug cleanups.

- Updates to Tiny RCU: a race fix and further code shrinkage.

- RCU torture-testing updates: fixes, speedups, cleanups and documentation updates.

- Miscellaneous fixes.

- Documentation updates.

Thanks,

Ingo

------------------>
Alexey Kodanev (1):
locktorture: fix deadlock in 'rw_lock_irq' type

Joe Perches (1):
rcu: tree_plugin: Use bool function return values of true/false not 1/0

Milos Vyletel (1):
documentation: State that rcu_dereference() reloads pointer

Nicholas Mc Guire (1):
rcu: Change function declaration to bool

Nicolas Iooss (1):
rcu: Make rcu_*_data variables static

Patrick Daly (1):
rcu: Fix missing task information during rcu-preempt stall

Paul E. McKenney (50):
rcu: Convert ACCESS_ONCE() to READ_ONCE() and WRITE_ONCE()
mce: Stop using array-index-based RCU primitives
rcu: Eliminate array-index-based RCU primitives
documentation: RCU-protected array indexes no longer supported
mce: mce_chrdev_write() can be static
documentation: Update rcu_dereference.txt based on WG21 discussions
rcu: Convert from rcu_preempt_state to *rcu_state_p
rcu: Eliminate a few RCU_BOOST #ifdefs in favor of IS_ENABLED()
rcu: Tell the compiler that rcu_state_p is immutable
rcu: Create an immutable rcu_data_p pointer to default rcu_data structure
rcu: Eliminate a few CONFIG_RCU_NOCB_CPU_ALL #ifdefs
rcu: Force wakeup of rcu_gp_kthread at grace-period end
powerpc: Fix smp_mb__before_spinlock()
rcu: Add more debug info on "kthread starved" RCU CPU stall warnings
smp: Make control dependencies work on Alpha, improve documentation
rcu: Make synchronize_sched_expedited() call wait_rcu_gp()
rcu: Eliminate HOTPLUG_CPU #ifdef in favor of IS_ENABLED()
rcu: Adjust ->lock acquisition for tasks no longer migrating
rcu: Remove dead code from force_qs_rnp()
rcu: Remove redundant offline check
rcu: Correctly initialize ->rcu_qs_ctr_snap at online time
cpu: Handle smpboot_unpark_threads() uniformly
rcu: Modulate grace-period slow init to normalize delay
rcu: Shut up spurious gcc uninitialized-variable warning
rcu: Provide diagnostic option to slow down grace-period scans
rcu: Directly drive TASKS_RCU from Kconfig
rcu: Directly drive RCU_USER_QS from Kconfig
rcu: Convert CONFIG_RCU_FANOUT_EXACT to boot parameter
rcu: Enable diagnostic dump of rcu_node combining tree
rcu: Create RCU_EXPERT Kconfig and hide booleans behind it
rcu: Break dependency of RCU_FANOUT_LEAF on RCU_FANOUT
rcu: Make RCU able to tolerate undefined CONFIG_RCU_FANOUT
rcu: Make RCU able to tolerate undefined CONFIG_RCU_FANOUT_LEAF
rcu: Make RCU able to tolerate undefined CONFIG_RCU_KTHREAD_PRIO
rcu: Conditionally compile RCU's eqs warnings
rcu: Further shrink Tiny RCU by making empty functions static inlines
rcutorture: Test both RCU-sched and RCU-bh for Tiny RCU
rcu: Correctly handle non-empty Tiny RCU callback list with none ready
rcutorture: Exchange TREE03 and TREE04 geometries
rcutorture: Exchange TREE03 and TREE08 NR_CPUS, speed up CPU hotplug
rcutorture: Allow negative values of nreaders to oversubscribe
locktorture: Change longdelay_us to longdelay_ms
rcutorture: Replace barriers with smp_store_release() and smp_load_acquire()
rcutorture: Test SRCU cleanup code path
rcutorture: TASKS_RCU set directly, so don't explicitly set it
rcutorture: Update configuration fragments for rcutree.rcu_fanout_exact
rcutorture: Make rcutorture scripts force RCU_EXPERT
rcutorture: Update TREE_RCU-kconfig.txt
rcutorture: Display "make oldconfig" errors
rcutorture: Allow repetition factors in Kconfig-fragment lists

Paul Gortmaker (1):
cpu: Remove new instance of __cpuinit that crept back in

Pranith Kumar (1):
rcu: Remove prompt for RCU implementation

Will Deacon (1):
documentation: memory-barriers: Fix smp_mb__before_spinlock() semantics

Ying Xue (1):
rculist: Fix another sparse warning

 Documentation/RCU/arrayRCU.txt                     |  20 +-
 Documentation/RCU/lockdep.txt                      |  10 -
 Documentation/RCU/rcu_dereference.txt              |  38 +--
 Documentation/RCU/whatisRCU.txt                    |   6 +-
 Documentation/kernel-parameters.txt                |  33 +-
 Documentation/memory-barriers.txt                  |  62 ++--
 arch/powerpc/include/asm/barrier.h                 |   1 +
 arch/x86/kernel/cpu/mcheck/mce.c                   |  15 +-
 include/linux/compiler.h                           |  16 +
 include/linux/rculist.h                            |  10 +-
 include/linux/rcupdate.h                           |  70 +---
 include/linux/rcutiny.h                            |  16 +
 include/linux/rcutree.h                            |   7 +-
 include/linux/spinlock.h                           |   2 +-
 init/Kconfig                                       |  72 ++--
 kernel/cpu.c                                       |   4 +-
 kernel/events/ring_buffer.c                        |   2 +-
 kernel/locking/locktorture.c                       |  14 +-
 kernel/rcu/rcutorture.c                            | 103 ++++--
 kernel/rcu/srcu.c                                  |  10 +-
 kernel/rcu/tiny.c                                  |  38 +--
 kernel/rcu/tiny_plugin.h                           |  12 +-
 kernel/rcu/tree.c                                  | 365 ++++++++++++---------
 kernel/rcu/tree.h                                  |  35 +-
 kernel/rcu/tree_plugin.h                           | 216 ++++++------
 kernel/rcu/tree_trace.c                            |   6 +-
 kernel/rcu/update.c                                |  30 +-
 kernel/torture.c                                   |  26 +-
 lib/Kconfig.debug                                  |  66 +++-
 .../testing/selftests/rcutorture/bin/configinit.sh |   2 +-
 .../selftests/rcutorture/bin/kvm-recheck.sh        |   4 +
 tools/testing/selftests/rcutorture/bin/kvm.sh      |  25 +-
 .../selftests/rcutorture/configs/rcu/CFcommon      |   2 +
 .../selftests/rcutorture/configs/rcu/SRCU-N        |   1 +
 .../selftests/rcutorture/configs/rcu/SRCU-P        |   1 +
 .../selftests/rcutorture/configs/rcu/SRCU-P.boot   |   2 +-
 .../selftests/rcutorture/configs/rcu/TASKS01       |   5 +-
 .../selftests/rcutorture/configs/rcu/TASKS02       |   1 -
 .../selftests/rcutorture/configs/rcu/TASKS03       |   2 +-
 .../selftests/rcutorture/configs/rcu/TINY02        |   2 +-
 .../selftests/rcutorture/configs/rcu/TINY02.boot   |   1 +
 .../selftests/rcutorture/configs/rcu/TREE01        |   1 +
 .../selftests/rcutorture/configs/rcu/TREE02        |   2 +-
 .../selftests/rcutorture/configs/rcu/TREE02-T      |   1 -
 .../selftests/rcutorture/configs/rcu/TREE03        |   8 +-
 .../selftests/rcutorture/configs/rcu/TREE03.boot   |   1 +
 .../selftests/rcutorture/configs/rcu/TREE04        |   8 +-
 .../selftests/rcutorture/configs/rcu/TREE05        |   4 +-
 .../selftests/rcutorture/configs/rcu/TREE06        |   4 +-
 .../selftests/rcutorture/configs/rcu/TREE06.boot   |   1 +
 .../selftests/rcutorture/configs/rcu/TREE07        |   4 +-
 .../selftests/rcutorture/configs/rcu/TREE08        |   6 +-
 .../selftests/rcutorture/configs/rcu/TREE08-T      |   1 -
 .../selftests/rcutorture/configs/rcu/TREE08-T.boot |   1 +
 .../selftests/rcutorture/configs/rcu/TREE08.boot   |   1 +
 .../selftests/rcutorture/configs/rcu/TREE09        |   1 +
 .../selftests/rcutorture/doc/TREE_RCU-kconfig.txt  |  36 +-
 57 files changed, 809 insertions(+), 624 deletions(-)
 create mode 100644 tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot
 create mode 100644 tools/testing/selftests/rcutorture/configs/rcu/TREE08-T.boot
Documentation/RCU/arrayRCU.txt +16 -4
index 453ebe6953ee..f05a9afb2c39 100644
@@ -10,7 +10,19 @@ Although RCU is more commonly used to protect linked lists, it can
 
 3.  Resizeable Arrays
 
-Each of these situations are discussed below.
+Each of these three situations involves an RCU-protected pointer to an
+array that is separately indexed.  It might be tempting to consider use
+of RCU to instead protect the index into an array, however, this use
+case is -not- supported.  The problem with RCU-protected indexes into
+arrays is that compilers can play way too many optimization games with
+integers, which means that the rules governing handling of these indexes
+are far more trouble than they are worth.  If RCU-protected indexes into
+arrays prove to be particularly valuable (which they have not thus far),
+explicit cooperation from the compiler will be required to permit them
+to be safely used.
+
+That aside, each of the three RCU-protected pointer situations are
+described in the following sections.
 
 
 Situation 1: Hash Tables
@@ -36,9 +48,9 @@ Quick Quiz:  Why is it so important that updates be rare when
 Situation 3: Resizeable Arrays
 
 Use of RCU for resizeable arrays is demonstrated by the grow_ary()
-function used by the System V IPC code.  The array is used to map from
-semaphore, message-queue, and shared-memory IDs to the data structure
-that represents the corresponding IPC construct.  The grow_ary()
+function formerly used by the System V IPC code.  The array is used
+to map from semaphore, message-queue, and shared-memory IDs to the data
+structure that represents the corresponding IPC construct.  The grow_ary()
 function does not acquire any locks; instead its caller must hold the
 ids->sem semaphore.
 
Documentation/RCU/lockdep.txt +0 -10
index cd83d2348fef..da51d3068850 100644
@@ -47,11 +47,6 @@ In addition, a separate kernel config parameter CONFIG_PROVE_RCU enables
 		Use explicit check expression "c" along with
 		srcu_read_lock_held()().  This is useful in code that
 		is invoked by both SRCU readers and updaters.
-	rcu_dereference_index_check(p, c):
-		Use explicit check expression "c", but the caller
-		must supply one of the rcu_read_lock_held() functions.
-		This is useful in code that uses RCU-protected arrays
-		that is invoked by both RCU readers and updaters.
 	rcu_dereference_raw(p):
 		Don't check.  (Use sparingly, if at all.)
 	rcu_dereference_protected(p, c):
@@ -64,11 +59,6 @@ In addition, a separate kernel config parameter CONFIG_PROVE_RCU enables
 		but retain the compiler constraints that prevent duplicating
 		or coalescsing.  This is useful when when testing the
 		value of the pointer itself, for example, against NULL.
-	rcu_access_index(idx):
-		Return the value of the index and omit all barriers, but
-		retain the compiler constraints that prevent duplicating
-		or coalescsing.  This is useful when when testing the
-		value of the index itself, for example, against -1.
 
 The rcu_dereference_check() check expression can be any boolean
 expression, but would normally include a lockdep expression.  However,
Documentation/RCU/rcu_dereference.txt +17 -21
index ceb05da5a5ac..1e6c0da994f5 100644
@@ -25,17 +25,6 @@ o	You must use one of the rcu_dereference() family of primitives
 	for an example where the compiler can in fact deduce the exact
 	value of the pointer, and thus cause misordering.
 
-o	Do not use single-element RCU-protected arrays.  The compiler
-	is within its right to assume that the value of an index into
-	such an array must necessarily evaluate to zero.  The compiler
-	could then substitute the constant zero for the computation, so
-	that the array index no longer depended on the value returned
-	by rcu_dereference().  If the array index no longer depends
-	on rcu_dereference(), then both the compiler and the CPU
-	are within their rights to order the array access before the
-	rcu_dereference(), which can cause the array access to return
-	garbage.
-
 o	Avoid cancellation when using the "+" and "-" infix arithmetic
 	operators.  For example, for a given variable "x", avoid
 	"(x-x)".  There are similar arithmetic pitfalls from other
@@ -76,14 +65,15 @@ o	Do not use the results from the boolean "&&" and "||" when
 	dereferencing.	For example, the following (rather improbable)
 	code is buggy:
 
-		int a[2];
-		int index;
-		int force_zero_index = 1;
+		int *p;
+		int *q;
 
 		...
 
-		r1 = rcu_dereference(i1)
-		r2 = a[r1 && force_zero_index];  /* BUGGY!!! */
+		p = rcu_dereference(gp)
+		q = &global_q;
+		q += p != &oom_p1 && p != &oom_p2;
+		r1 = *q;  /* BUGGY!!! */
 
 	The reason this is buggy is that "&&" and "||" are often compiled
 	using branches.  While weak-memory machines such as ARM or PowerPC
@@ -94,14 +84,15 @@ o	Do not use the results from relational operators ("==", "!=",
 	">", ">=", "<", or "<=") when dereferencing.  For example,
 	the following (quite strange) code is buggy:
 
-		int a[2];
-		int index;
-		int flip_index = 0;
+		int *p;
+		int *q;
 
 		...
 
-		r1 = rcu_dereference(i1)
-		r2 = a[r1 != flip_index];  /* BUGGY!!! */
+		p = rcu_dereference(gp)
+		q = &global_q;
+		q += p > &oom_p;
+		r1 = *q;  /* BUGGY!!! */
 
 	As before, the reason this is buggy is that relational operators
 	are often compiled using branches.  And as before, although
@@ -193,6 +184,11 @@ o	Be very careful about comparing pointers obtained from
 		pointer.  Note that the volatile cast in rcu_dereference()
 		will normally prevent the compiler from knowing too much.
 
+		However, please note that if the compiler knows that the
+		pointer takes on only one of two values, a not-equal
+		comparison will provide exactly the information that the
+		compiler needs to deduce the value of the pointer.
+
 o	Disable any value-speculation optimizations that your compiler
 	might provide, especially if you are making use of feedback-based
 	optimizations that take data collected from prior runs.  Such
Documentation/RCU/whatisRCU.txt +3 -3
index 88dfce182f66..5746b0c77f3e 100644
@@ -256,7 +256,9 @@ rcu_dereference()
 	If you are going to be fetching multiple fields from the
 	RCU-protected structure, using the local variable is of
 	course preferred.  Repeated rcu_dereference() calls look
-	ugly and incur unnecessary overhead on Alpha CPUs.
+	ugly, do not guarantee that the same pointer will be returned
+	if an update happened while in the critical section, and incur
+	unnecessary overhead on Alpha CPUs.
 
 	Note that the value returned by rcu_dereference() is valid
 	only within the enclosing RCU read-side critical section.
@@ -879,9 +881,7 @@ SRCU:	Initialization/cleanup
 
 All:  lockdep-checked RCU-protected pointer access
 
-	rcu_access_index
 	rcu_access_pointer
-	rcu_dereference_index_check
 	rcu_dereference_raw
 	rcu_lockdep_assert
 	rcu_sleep_check
Documentation/kernel-parameters.txt +30 -3
index 61ab1628a057..0b7f3e7a029c 100644
@@ -2992,11 +2992,34 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			Set maximum number of finished RCU callbacks to
 			process in one batch.
 
+	rcutree.dump_tree=	[KNL]
+			Dump the structure of the rcu_node combining tree
+			out at early boot.  This is used for diagnostic
+			purposes, to verify correct tree setup.
+
+	rcutree.gp_cleanup_delay=	[KNL]
+			Set the number of jiffies to delay each step of
+			RCU grace-period cleanup.  This only has effect
+			when CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP is set.
+
 	rcutree.gp_init_delay=	[KNL]
 			Set the number of jiffies to delay each step of
 			RCU grace-period initialization.  This only has
-			effect when CONFIG_RCU_TORTURE_TEST_SLOW_INIT is
-			set.
+			effect when CONFIG_RCU_TORTURE_TEST_SLOW_INIT
+			is set.
+
+	rcutree.gp_preinit_delay=	[KNL]
+			Set the number of jiffies to delay each step of
+			RCU grace-period pre-initialization, that is,
+			the propagation of recent CPU-hotplug changes up
+			the rcu_node combining tree.  This only has effect
+			when CONFIG_RCU_TORTURE_TEST_SLOW_PREINIT is set.
+
+	rcutree.rcu_fanout_exact= [KNL]
+			Disable autobalancing of the rcu_node combining
+			tree.  This is used by rcutorture, and might
+			possibly be useful for architectures having high
+			cache-to-cache transfer latencies.
 
 	rcutree.rcu_fanout_leaf= [KNL]
 			Increase the number of CPUs assigned to each
@@ -3101,7 +3124,11 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			test, hence the "fake".
 
 	rcutorture.nreaders= [KNL]
-			Set number of RCU readers.
+			Set number of RCU readers.  The value -1 selects
+			N-1, where N is the number of CPUs.  A value
+			"n" less than -1 selects N-n-2, where N is again
+			the number of CPUs.  For example, -2 selects N
+			(the number of CPUs), -3 selects N+1, and so on.
 
 	rcutorture.object_debug= [KNL]
 			Enable debug-object double-call_rcu() testing.
Documentation/memory-barriers.txt +36 -26

151 lines not on this page · raw message

arch/powerpc/include/asm/barrier.h +1 -0
index a3bf5be111ff..1124f59b8df4 100644
@@ -89,5 +89,6 @@ do {									\
 
 #define smp_mb__before_atomic()     smp_mb()
 #define smp_mb__after_atomic()      smp_mb()
+#define smp_mb__before_spinlock()   smp_mb()
 
 #endif /* _ASM_POWERPC_BARRIER_H */
arch/x86/kernel/cpu/mcheck/mce.c +9 -6
index 20190bdac9d5..95cf78d44ab4 100644
@@ -53,9 +53,12 @@
 static DEFINE_MUTEX(mce_chrdev_read_mutex);
 
 #define rcu_dereference_check_mce(p) \
-	rcu_dereference_index_check((p), \
-			      rcu_read_lock_sched_held() || \
-			      lockdep_is_held(&mce_chrdev_read_mutex))
+({ \
+	rcu_lockdep_assert(rcu_read_lock_sched_held() || \
+			   lockdep_is_held(&mce_chrdev_read_mutex), \
+			   "suspicious rcu_dereference_check_mce() usage"); \
+	smp_load_acquire(&(p)); \
+})
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/mce.h>
@@ -1887,7 +1890,7 @@ static ssize_t mce_chrdev_read(struct file *filp, char __user *ubuf,
 static unsigned int mce_chrdev_poll(struct file *file, poll_table *wait)
 {
 	poll_wait(file, &mce_chrdev_wait, wait);
-	if (rcu_access_index(mcelog.next))
+	if (READ_ONCE(mcelog.next))
 		return POLLIN | POLLRDNORM;
 	if (!mce_apei_read_done && apei_check_mce())
 		return POLLIN | POLLRDNORM;
@@ -1932,8 +1935,8 @@ void register_mce_write_callback(ssize_t (*fn)(struct file *filp,
 }
 EXPORT_SYMBOL_GPL(register_mce_write_callback);
 
-ssize_t mce_chrdev_write(struct file *filp, const char __user *ubuf,
-			 size_t usize, loff_t *off)
+static ssize_t mce_chrdev_write(struct file *filp, const char __user *ubuf,
+				size_t usize, loff_t *off)
 {
 	if (mce_write)
 		return mce_write(filp, ubuf, usize, off);
include/linux/compiler.h +16 -0
index 867722591be2..5d66777914db 100644
@@ -252,6 +252,22 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
 #define WRITE_ONCE(x, val) \
 	({ typeof(x) __val = (val); __write_once_size(&(x), &__val, sizeof(__val)); __val; })
 
+/**
+ * READ_ONCE_CTRL - Read a value heading a control dependency
+ * @x: The value to be read, heading the control dependency
+ *
+ * Control dependencies are tricky.  See Documentation/memory-barriers.txt
+ * for important information on how to use them.  Note that in many cases,
+ * use of smp_load_acquire() will be much simpler.  Control dependencies
+ * should be avoided except on the hottest of hotpaths.
+ */
+#define READ_ONCE_CTRL(x) \
+({ \
+	typeof(x) __val = READ_ONCE(x); \
+	smp_read_barrier_depends(); /* Enforce control dependency. */ \
+	__val; \
+})
+
 #endif /* __KERNEL__ */
 
 #endif /* __ASSEMBLY__ */
include/linux/rculist.h +5 -5
index a18b16f1dc0e..17c6b1f84a77 100644
@@ -29,8 +29,8 @@
  */
 static inline void INIT_LIST_HEAD_RCU(struct list_head *list)
 {
-	ACCESS_ONCE(list->next) = list;
-	ACCESS_ONCE(list->prev) = list;
+	WRITE_ONCE(list->next, list);
+	WRITE_ONCE(list->prev, list);
 }
 
 /*
@@ -288,7 +288,7 @@ static inline void list_splice_init_rcu(struct list_head *list,
 #define list_first_or_null_rcu(ptr, type, member) \
 ({ \
 	struct list_head *__ptr = (ptr); \
-	struct list_head *__next = ACCESS_ONCE(__ptr->next); \
+	struct list_head *__next = READ_ONCE(__ptr->next); \
 	likely(__ptr != __next) ? list_entry_rcu(__next, type, member) : NULL; \
 })
 
@@ -549,8 +549,8 @@ static inline void hlist_add_behind_rcu(struct hlist_node *n,
  */
 #define hlist_for_each_entry_from_rcu(pos, member)			\
 	for (; pos;							\
-	     pos = hlist_entry_safe(rcu_dereference((pos)->member.next),\
-			typeof(*(pos)), member))
+	     pos = hlist_entry_safe(rcu_dereference_raw(hlist_next_rcu(	\
+			&(pos)->member)), typeof(*(pos)), member))
 
 #endif	/* __KERNEL__ */
 #endif
include/linux/rcupdate.h +8 -62

128 lines not on this page · raw message

include/linux/rcutiny.h +16 -0
index 937edaeb150d..3df6c1ec4e25 100644
@@ -159,6 +159,22 @@ static inline void rcu_cpu_stall_reset(void)
 {
 }
 
+static inline void rcu_idle_enter(void)
+{
+}
+
+static inline void rcu_idle_exit(void)
+{
+}
+
+static inline void rcu_irq_enter(void)
+{
+}
+
+static inline void rcu_irq_exit(void)
+{
+}
+
 static inline void exit_rcu(void)
 {
 }
include/linux/rcutree.h +5 -2
index d2e583a6aaca..3fa4a43ab415 100644
@@ -31,9 +31,7 @@
 #define __LINUX_RCUTREE_H
 
 void rcu_note_context_switch(void);
-#ifndef CONFIG_RCU_NOCB_CPU_ALL
 int rcu_needs_cpu(unsigned long *delta_jiffies);
-#endif /* #ifndef CONFIG_RCU_NOCB_CPU_ALL */
 void rcu_cpu_stall_reset(void);
 
 /*
@@ -93,6 +91,11 @@ void rcu_force_quiescent_state(void);
 void rcu_bh_force_quiescent_state(void);
 void rcu_sched_force_quiescent_state(void);
 
+void rcu_idle_enter(void);
+void rcu_idle_exit(void);
+void rcu_irq_enter(void);
+void rcu_irq_exit(void);
+
 void exit_rcu(void);
 
 void rcu_scheduler_starting(void);
include/linux/spinlock.h +1 -1
index 3e18379dfa6f..0063b24b4f36 100644
@@ -120,7 +120,7 @@ do {								\
 /*
  * Despite its name it doesn't necessarily has to be a full barrier.
  * It should only guarantee that a STORE before the critical section
- * can not be reordered with a LOAD inside this section.
+ * can not be reordered with LOADs and STOREs inside this section.
  * spin_lock() is the one-way barrier, this LOAD can not escape out
  * of the region. So the default implementation simply ensures that
  * a STORE can not move into the critical section, smp_wmb() should
init/Kconfig +29 -43

153 lines not on this page · raw message

kernel/cpu.c +2 -2
index 94bbe4695232..9c9c9fab16cc 100644
@@ -398,7 +398,6 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)
 	err = __stop_machine(take_cpu_down, &tcd_param, cpumask_of(cpu));
 	if (err) {
 		/* CPU didn't die: tell everyone.  Can't complain. */
-		smpboot_unpark_threads(cpu);
 		cpu_notify_nofail(CPU_DOWN_FAILED | mod, hcpu);
 		goto out_release;
 	}
@@ -463,6 +462,7 @@ static int smpboot_thread_call(struct notifier_block *nfb,
 
 	switch (action & ~CPU_TASKS_FROZEN) {
 
+	case CPU_DOWN_FAILED:
 	case CPU_ONLINE:
 		smpboot_unpark_threads(cpu);
 		break;
@@ -479,7 +479,7 @@ static struct notifier_block smpboot_thread_notifier = {
 	.priority = CPU_PRI_SMPBOOT,
 };
 
-void __cpuinit smpboot_thread_init(void)
+void smpboot_thread_init(void)
 {
 	register_cpu_notifier(&smpboot_thread_notifier);
 }
kernel/events/ring_buffer.c +1 -1
index 232f00f273cb..17fcb73c4a50 100644
@@ -141,7 +141,7 @@ int perf_output_begin(struct perf_output_handle *handle,
 	perf_output_get_handle(handle);
 
 	do {
-		tail = ACCESS_ONCE(rb->user_page->data_tail);
+		tail = READ_ONCE_CTRL(rb->user_page->data_tail);
 		offset = head = local_read(&rb->head);
 		if (!rb->overwrite &&
 		    unlikely(CIRC_SPACE(head, tail, perf_data_size(rb)) < size))
kernel/locking/locktorture.c +7 -7
index ec8cce259779..32244186f1f2 100644
@@ -122,12 +122,12 @@ static int torture_lock_busted_write_lock(void)
 
 static void torture_lock_busted_write_delay(struct torture_random_state *trsp)
 {
-	const unsigned long longdelay_us = 100;
+	const unsigned long longdelay_ms = 100;
 
 	/* We want a long delay occasionally to force massive contention.  */
 	if (!(torture_random(trsp) %
-	      (cxt.nrealwriters_stress * 2000 * longdelay_us)))
-		mdelay(longdelay_us);
+	      (cxt.nrealwriters_stress * 2000 * longdelay_ms)))
+		mdelay(longdelay_ms);
 #ifdef CONFIG_PREEMPT
 	if (!(torture_random(trsp) % (cxt.nrealwriters_stress * 20000)))
 		preempt_schedule();  /* Allow test to be preempted. */
@@ -160,14 +160,14 @@ static int torture_spin_lock_write_lock(void) __acquires(torture_spinlock)
 static void torture_spin_lock_write_delay(struct torture_random_state *trsp)
 {
 	const unsigned long shortdelay_us = 2;
-	const unsigned long longdelay_us = 100;
+	const unsigned long longdelay_ms = 100;
 
 	/* We want a short delay mostly to emulate likely code, and
 	 * we want a long delay occasionally to force massive contention.
 	 */
 	if (!(torture_random(trsp) %
-	      (cxt.nrealwriters_stress * 2000 * longdelay_us)))
-		mdelay(longdelay_us);
+	      (cxt.nrealwriters_stress * 2000 * longdelay_ms)))
+		mdelay(longdelay_ms);
 	if (!(torture_random(trsp) %
 	      (cxt.nrealwriters_stress * 2 * shortdelay_us)))
 		udelay(shortdelay_us);
@@ -309,7 +309,7 @@ static int torture_rwlock_read_lock_irq(void) __acquires(torture_rwlock)
 static void torture_rwlock_read_unlock_irq(void)
 __releases(torture_rwlock)
 {
-	write_unlock_irqrestore(&torture_rwlock, cxt.cur_ops->flags);
+	read_unlock_irqrestore(&torture_rwlock, cxt.cur_ops->flags);
 }
 
 static struct lock_torture_ops rw_lock_irq_ops = {
kernel/rcu/rcutorture.c +72 -31

237 lines not on this page · raw message

kernel/rcu/srcu.c +5 -5
index cad76e76b4e7..fb33d35ee0b7 100644
@@ -151,7 +151,7 @@ static unsigned long srcu_readers_seq_idx(struct srcu_struct *sp, int idx)
 	unsigned long t;
 
 	for_each_possible_cpu(cpu) {
-		t = ACCESS_ONCE(per_cpu_ptr(sp->per_cpu_ref, cpu)->seq[idx]);
+		t = READ_ONCE(per_cpu_ptr(sp->per_cpu_ref, cpu)->seq[idx]);
 		sum += t;
 	}
 	return sum;
@@ -168,7 +168,7 @@ static unsigned long srcu_readers_active_idx(struct srcu_struct *sp, int idx)
 	unsigned long t;
 
 	for_each_possible_cpu(cpu) {
-		t = ACCESS_ONCE(per_cpu_ptr(sp->per_cpu_ref, cpu)->c[idx]);
+		t = READ_ONCE(per_cpu_ptr(sp->per_cpu_ref, cpu)->c[idx]);
 		sum += t;
 	}
 	return sum;
@@ -265,8 +265,8 @@ static int srcu_readers_active(struct srcu_struct *sp)
 	unsigned long sum = 0;
 
 	for_each_possible_cpu(cpu) {
-		sum += ACCESS_ONCE(per_cpu_ptr(sp->per_cpu_ref, cpu)->c[0]);
-		sum += ACCESS_ONCE(per_cpu_ptr(sp->per_cpu_ref, cpu)->c[1]);
+		sum += READ_ONCE(per_cpu_ptr(sp->per_cpu_ref, cpu)->c[0]);
+		sum += READ_ONCE(per_cpu_ptr(sp->per_cpu_ref, cpu)->c[1]);
 	}
 	return sum;
 }
@@ -296,7 +296,7 @@ int __srcu_read_lock(struct srcu_struct *sp)
 {
 	int idx;
 
-	idx = ACCESS_ONCE(sp->completed) & 0x1;
+	idx = READ_ONCE(sp->completed) & 0x1;
 	preempt_disable();
 	__this_cpu_inc(sp->per_cpu_ref->c[idx]);
 	smp_mb(); /* B */  /* Avoid leaking the critical section. */
kernel/rcu/tiny.c +5 -33
index 069742d61c68..591af0cb7b9f 100644
@@ -49,39 +49,6 @@ static void __call_rcu(struct rcu_head *head,
 
 #include "tiny_plugin.h"
 
-/*
- * Enter idle, which is an extended quiescent state if we have fully
- * entered that mode.
- */
-void rcu_idle_enter(void)
-{
-}
-EXPORT_SYMBOL_GPL(rcu_idle_enter);
-
-/*
- * Exit an interrupt handler towards idle.
- */
-void rcu_irq_exit(void)
-{
-}
-EXPORT_SYMBOL_GPL(rcu_irq_exit);
-
-/*
- * Exit idle, so that we are no longer in an extended quiescent state.
- */
-void rcu_idle_exit(void)
-{
-}
-EXPORT_SYMBOL_GPL(rcu_idle_exit);
-
-/*
- * Enter an interrupt handler, moving away from idle.
- */
-void rcu_irq_enter(void)
-{
-}
-EXPORT_SYMBOL_GPL(rcu_irq_enter);
-
 #if defined(CONFIG_DEBUG_LOCK_ALLOC) || defined(CONFIG_RCU_TRACE)
 
 /*
@@ -170,6 +137,11 @@ static void __rcu_process_callbacks(struct rcu_ctrlblk *rcp)
 
 	/* Move the ready-to-invoke callbacks to a local list. */
 	local_irq_save(flags);
+	if (rcp->donetail == &rcp->rcucblist) {
+		/* No callbacks ready, so just leave. */
+		local_irq_restore(flags);
+		return;
+	}
 	RCU_TRACE(trace_rcu_batch_start(rcp->name, 0, rcp->qlen, -1));
 	list = rcp->rcucblist;
 	rcp->rcucblist = *rcp->donetail;
kernel/rcu/tiny_plugin.h +7 -5
index f94e209a10d6..e492a5253e0f 100644
@@ -144,16 +144,17 @@ static void check_cpu_stall(struct rcu_ctrlblk *rcp)
 		return;
 	rcp->ticks_this_gp++;
 	j = jiffies;
-	js = ACCESS_ONCE(rcp->jiffies_stall);
+	js = READ_ONCE(rcp->jiffies_stall);
 	if (rcp->rcucblist && ULONG_CMP_GE(j, js)) {
 		pr_err("INFO: %s stall on CPU (%lu ticks this GP) idle=%llx (t=%lu jiffies q=%ld)\n",
 		       rcp->name, rcp->ticks_this_gp, DYNTICK_TASK_EXIT_IDLE,
 		       jiffies - rcp->gp_start, rcp->qlen);
 		dump_stack();
-		ACCESS_ONCE(rcp->jiffies_stall) = jiffies +
-			3 * rcu_jiffies_till_stall_check() + 3;
+		WRITE_ONCE(rcp->jiffies_stall,
+			   jiffies + 3 * rcu_jiffies_till_stall_check() + 3);
 	} else if (ULONG_CMP_GE(j, js)) {
-		ACCESS_ONCE(rcp->jiffies_stall) = jiffies + rcu_jiffies_till_stall_check();
+		WRITE_ONCE(rcp->jiffies_stall,
+			   jiffies + rcu_jiffies_till_stall_check());
 	}
 }
 
@@ -161,7 +162,8 @@ static void reset_cpu_stall_ticks(struct rcu_ctrlblk *rcp)
 {
 	rcp->ticks_this_gp = 0;
 	rcp->gp_start = jiffies;
-	ACCESS_ONCE(rcp->jiffies_stall) = jiffies + rcu_jiffies_till_stall_check();
+	WRITE_ONCE(rcp->jiffies_stall,
+		   jiffies + rcu_jiffies_till_stall_check());
 }
 
 static void check_cpu_stalls(void)
kernel/rcu/tree.c +212 -153

950 lines not on this page · raw message

kernel/rcu/tree.h +26 -9
index a69d3dab2ec4..4adb7ca0bf47 100644
@@ -35,11 +35,33 @@
  * In practice, this did work well going from three levels to four.
  * Of course, your mileage may vary.
  */
+
 #define MAX_RCU_LVLS 4
-#define RCU_FANOUT_1	      (CONFIG_RCU_FANOUT_LEAF)
-#define RCU_FANOUT_2	      (RCU_FANOUT_1 * CONFIG_RCU_FANOUT)
-#define RCU_FANOUT_3	      (RCU_FANOUT_2 * CONFIG_RCU_FANOUT)
-#define RCU_FANOUT_4	      (RCU_FANOUT_3 * CONFIG_RCU_FANOUT)
+
+#ifdef CONFIG_RCU_FANOUT
+#define RCU_FANOUT CONFIG_RCU_FANOUT
+#else /* #ifdef CONFIG_RCU_FANOUT */
+# ifdef CONFIG_64BIT
+# define RCU_FANOUT 64
+# else
+# define RCU_FANOUT 32
+# endif
+#endif /* #else #ifdef CONFIG_RCU_FANOUT */
+
+#ifdef CONFIG_RCU_FANOUT_LEAF
+#define RCU_FANOUT_LEAF CONFIG_RCU_FANOUT_LEAF
+#else /* #ifdef CONFIG_RCU_FANOUT_LEAF */
+# ifdef CONFIG_64BIT
+# define RCU_FANOUT_LEAF 64
+# else
+# define RCU_FANOUT_LEAF 32
+# endif
+#endif /* #else #ifdef CONFIG_RCU_FANOUT_LEAF */
+
+#define RCU_FANOUT_1	      (RCU_FANOUT_LEAF)
+#define RCU_FANOUT_2	      (RCU_FANOUT_1 * RCU_FANOUT)
+#define RCU_FANOUT_3	      (RCU_FANOUT_2 * RCU_FANOUT)
+#define RCU_FANOUT_4	      (RCU_FANOUT_3 * RCU_FANOUT)
 
 #if NR_CPUS <= RCU_FANOUT_1
 #  define RCU_NUM_LVLS	      1
@@ -170,7 +192,6 @@ struct rcu_node {
 				/*  if there is no such task.  If there */
 				/*  is no current expedited grace period, */
 				/*  then there can cannot be any such task. */
-#ifdef CONFIG_RCU_BOOST
 	struct list_head *boost_tasks;
 				/* Pointer to first task that needs to be */
 				/*  priority boosted, or NULL if no priority */
@@ -208,7 +229,6 @@ struct rcu_node {
 	unsigned long n_balk_nos;
 				/* Refused to boost: not sure why, though. */
 				/*  This can happen due to race conditions. */
-#endif /* #ifdef CONFIG_RCU_BOOST */
 #ifdef CONFIG_RCU_NOCB_CPU
 	wait_queue_head_t nocb_gp_wq[2];
 				/* Place for rcu_nocb_kthread() to wait GP. */
@@ -519,14 +539,11 @@ extern struct list_head rcu_struct_flavors;
  * RCU implementation internal declarations:
  */
 extern struct rcu_state rcu_sched_state;
-DECLARE_PER_CPU(struct rcu_data, rcu_sched_data);
 
 extern struct rcu_state rcu_bh_state;
-DECLARE_PER_CPU(struct rcu_data, rcu_bh_data);
 
 #ifdef CONFIG_PREEMPT_RCU
 extern struct rcu_state rcu_preempt_state;
-DECLARE_PER_CPU(struct rcu_data, rcu_preempt_data);
 #endif /* #ifdef CONFIG_PREEMPT_RCU */
 
 #ifdef CONFIG_RCU_BOOST
kernel/rcu/tree_plugin.h +113 -103

635 lines not on this page · raw message

kernel/rcu/tree_trace.c +3 -3
index f92361efd0f5..3ea7ffc7d5c4 100644
@@ -277,7 +277,7 @@ static void print_one_rcu_state(struct seq_file *m, struct rcu_state *rsp)
 	seq_printf(m, "nfqs=%lu/nfqsng=%lu(%lu) fqlh=%lu oqlen=%ld/%ld\n",
 		   rsp->n_force_qs, rsp->n_force_qs_ngp,
 		   rsp->n_force_qs - rsp->n_force_qs_ngp,
-		   ACCESS_ONCE(rsp->n_force_qs_lh), rsp->qlen_lazy, rsp->qlen);
+		   READ_ONCE(rsp->n_force_qs_lh), rsp->qlen_lazy, rsp->qlen);
 	for (rnp = &rsp->node[0]; rnp - &rsp->node[0] < rcu_num_nodes; rnp++) {
 		if (rnp->level != level) {
 			seq_puts(m, "\n");
@@ -323,8 +323,8 @@ static void show_one_rcugp(struct seq_file *m, struct rcu_state *rsp)
 	struct rcu_node *rnp = &rsp->node[0];
 
 	raw_spin_lock_irqsave(&rnp->lock, flags);
-	completed = ACCESS_ONCE(rsp->completed);
-	gpnum = ACCESS_ONCE(rsp->gpnum);
+	completed = READ_ONCE(rsp->completed);
+	gpnum = READ_ONCE(rsp->gpnum);
 	if (completed == gpnum)
 		gpage = 0;
 	else
kernel/rcu/update.c +15 -15
index 1f133350da01..afaecb7a799a 100644
@@ -150,14 +150,14 @@ void __rcu_read_unlock(void)
 		barrier();  /* critical section before exit code. */
 		t->rcu_read_lock_nesting = INT_MIN;
 		barrier();  /* assign before ->rcu_read_unlock_special load */
-		if (unlikely(ACCESS_ONCE(t->rcu_read_unlock_special.s)))
+		if (unlikely(READ_ONCE(t->rcu_read_unlock_special.s)))
 			rcu_read_unlock_special(t);
 		barrier();  /* ->rcu_read_unlock_special load before assign */
 		t->rcu_read_lock_nesting = 0;
 	}
 #ifdef CONFIG_PROVE_LOCKING
 	{
-		int rrln = ACCESS_ONCE(t->rcu_read_lock_nesting);
+		int rrln = READ_ONCE(t->rcu_read_lock_nesting);
 
 		WARN_ON_ONCE(rrln < 0 && rrln > INT_MIN / 2);
 	}
@@ -389,17 +389,17 @@ module_param(rcu_cpu_stall_timeout, int, 0644);
 
 int rcu_jiffies_till_stall_check(void)
 {
-	int till_stall_check = ACCESS_ONCE(rcu_cpu_stall_timeout);
+	int till_stall_check = READ_ONCE(rcu_cpu_stall_timeout);
 
 	/*
 	 * Limit check must be consistent with the Kconfig limits
 	 * for CONFIG_RCU_CPU_STALL_TIMEOUT.
 	 */
 	if (till_stall_check < 3) {
-		ACCESS_ONCE(rcu_cpu_stall_timeout) = 3;
+		WRITE_ONCE(rcu_cpu_stall_timeout, 3);
 		till_stall_check = 3;
 	} else if (till_stall_check > 300) {
-		ACCESS_ONCE(rcu_cpu_stall_timeout) = 300;
+		WRITE_ONCE(rcu_cpu_stall_timeout, 300);
 		till_stall_check = 300;
 	}
 	return till_stall_check * HZ + RCU_STALL_DELAY_DELTA;
@@ -550,12 +550,12 @@ static void check_holdout_task(struct task_struct *t,
 {
 	int cpu;
 
-	if (!ACCESS_ONCE(t->rcu_tasks_holdout) ||
-	    t->rcu_tasks_nvcsw != ACCESS_ONCE(t->nvcsw) ||
-	    !ACCESS_ONCE(t->on_rq) ||
+	if (!READ_ONCE(t->rcu_tasks_holdout) ||
+	    t->rcu_tasks_nvcsw != READ_ONCE(t->nvcsw) ||
+	    !READ_ONCE(t->on_rq) ||
 	    (IS_ENABLED(CONFIG_NO_HZ_FULL) &&
 	     !is_idle_task(t) && t->rcu_tasks_idle_cpu >= 0)) {
-		ACCESS_ONCE(t->rcu_tasks_holdout) = false;
+		WRITE_ONCE(t->rcu_tasks_holdout, false);
 		list_del_init(&t->rcu_tasks_holdout_list);
 		put_task_struct(t);
 		return;
@@ -639,11 +639,11 @@ static int __noreturn rcu_tasks_kthread(void *arg)
 		 */
 		rcu_read_lock();
 		for_each_process_thread(g, t) {
-			if (t != current && ACCESS_ONCE(t->on_rq) &&
+			if (t != current && READ_ONCE(t->on_rq) &&
 			    !is_idle_task(t)) {
 				get_task_struct(t);
-				t->rcu_tasks_nvcsw = ACCESS_ONCE(t->nvcsw);
-				ACCESS_ONCE(t->rcu_tasks_holdout) = true;
+				t->rcu_tasks_nvcsw = READ_ONCE(t->nvcsw);
+				WRITE_ONCE(t->rcu_tasks_holdout, true);
 				list_add(&t->rcu_tasks_holdout_list,
 					 &rcu_tasks_holdouts);
 			}
@@ -672,7 +672,7 @@ static int __noreturn rcu_tasks_kthread(void *arg)
 			struct task_struct *t1;
 
 			schedule_timeout_interruptible(HZ);
-			rtst = ACCESS_ONCE(rcu_task_stall_timeout);
+			rtst = READ_ONCE(rcu_task_stall_timeout);
 			needreport = rtst > 0 &&
 				     time_after(jiffies, lastreport + rtst);
 			if (needreport)
@@ -728,7 +728,7 @@ static void rcu_spawn_tasks_kthread(void)
 	static struct task_struct *rcu_tasks_kthread_ptr;
 	struct task_struct *t;
 
-	if (ACCESS_ONCE(rcu_tasks_kthread_ptr)) {
+	if (READ_ONCE(rcu_tasks_kthread_ptr)) {
 		smp_mb(); /* Ensure caller sees full kthread. */
 		return;
 	}
@@ -740,7 +740,7 @@ static void rcu_spawn_tasks_kthread(void)
 	t = kthread_run(rcu_tasks_kthread, NULL, "rcu_tasks_kthread");
 	BUG_ON(IS_ERR(t));
 	smp_mb(); /* Ensure others see full kthread. */
-	ACCESS_ONCE(rcu_tasks_kthread_ptr) = t;
+	WRITE_ONCE(rcu_tasks_kthread_ptr, t);
 	mutex_unlock(&rcu_tasks_kthread_mutex);
 }
 
kernel/torture.c +13 -13
index dd70993c266c..3e4840633d3e 100644
@@ -409,7 +409,7 @@ static void (*torture_shutdown_hook)(void);
  */
 void torture_shutdown_absorb(const char *title)
 {
-	while (ACCESS_ONCE(fullstop) == FULLSTOP_SHUTDOWN) {
+	while (READ_ONCE(fullstop) == FULLSTOP_SHUTDOWN) {
 		pr_notice("torture thread %s parking due to system shutdown\n",
 			  title);
 		schedule_timeout_uninterruptible(MAX_SCHEDULE_TIMEOUT);
@@ -480,9 +480,9 @@ static int torture_shutdown_notify(struct notifier_block *unused1,
 				   unsigned long unused2, void *unused3)
 {
 	mutex_lock(&fullstop_mutex);
-	if (ACCESS_ONCE(fullstop) == FULLSTOP_DONTSTOP) {
+	if (READ_ONCE(fullstop) == FULLSTOP_DONTSTOP) {
 		VERBOSE_TOROUT_STRING("Unscheduled system shutdown detected");
-		ACCESS_ONCE(fullstop) = FULLSTOP_SHUTDOWN;
+		WRITE_ONCE(fullstop, FULLSTOP_SHUTDOWN);
 	} else {
 		pr_warn("Concurrent rmmod and shutdown illegal!\n");
 	}
@@ -523,13 +523,13 @@ static int stutter;
  */
 void stutter_wait(const char *title)
 {
-	while (ACCESS_ONCE(stutter_pause_test) ||
-	       (torture_runnable && !ACCESS_ONCE(*torture_runnable))) {
+	while (READ_ONCE(stutter_pause_test) ||
+	       (torture_runnable && !READ_ONCE(*torture_runnable))) {
 		if (stutter_pause_test)
-			if (ACCESS_ONCE(stutter_pause_test) == 1)
+			if (READ_ONCE(stutter_pause_test) == 1)
 				schedule_timeout_interruptible(1);
 			else
-				while (ACCESS_ONCE(stutter_pause_test))
+				while (READ_ONCE(stutter_pause_test))
 					cond_resched();
 		else
 			schedule_timeout_interruptible(round_jiffies_relative(HZ));
@@ -549,14 +549,14 @@ static int torture_stutter(void *arg)
 		if (!torture_must_stop()) {
 			if (stutter > 1) {
 				schedule_timeout_interruptible(stutter - 1);
-				ACCESS_ONCE(stutter_pause_test) = 2;
+				WRITE_ONCE(stutter_pause_test, 2);
 			}
 			schedule_timeout_interruptible(1);
-			ACCESS_ONCE(stutter_pause_test) = 1;
+			WRITE_ONCE(stutter_pause_test, 1);
 		}
 		if (!torture_must_stop())
 			schedule_timeout_interruptible(stutter);
-		ACCESS_ONCE(stutter_pause_test) = 0;
+		WRITE_ONCE(stutter_pause_test, 0);
 		torture_shutdown_absorb("torture_stutter");
 	} while (!torture_must_stop());
 	torture_kthread_stopping("torture_stutter");
@@ -642,13 +642,13 @@ EXPORT_SYMBOL_GPL(torture_init_end);
 bool torture_cleanup_begin(void)
 {
 	mutex_lock(&fullstop_mutex);
-	if (ACCESS_ONCE(fullstop) == FULLSTOP_SHUTDOWN) {
+	if (READ_ONCE(fullstop) == FULLSTOP_SHUTDOWN) {
 		pr_warn("Concurrent rmmod and shutdown illegal!\n");
 		mutex_unlock(&fullstop_mutex);
 		schedule_timeout_uninterruptible(10);
[… more lines in the raw message]

Lines of this file are not shown. View the raw message.

lib/Kconfig.debug +64 -2

66 lines not on this page · raw message

tools/testing/selftests/rcutorture/bin/configinit.sh +1 -1
index 15f1a17ca96e..3f81a1095206 100755

Lines of this file are not shown. View the raw message.

tools/testing/selftests/rcutorture/bin/kvm-recheck.sh +4 -0
index 4f5b20f367a9..d86bdd6b6cc2 100755

Lines of this file are not shown. View the raw message.

tools/testing/selftests/rcutorture/bin/kvm.sh +19 -6
index dd2812ceb0ba..fbe2dbff1e21 100755

Lines of this file are not shown. View the raw message.

tools/testing/selftests/rcutorture/configs/rcu/CFcommon +2 -0
index 49701218dc62..f824b4c9d9d9 100644

Lines of this file are not shown. View the raw message.

tools/testing/selftests/rcutorture/configs/rcu/SRCU-N +1 -0
index 9fbb41b9b314..1a087c3c8bb8 100644

Lines of this file are not shown. View the raw message.

tools/testing/selftests/rcutorture/configs/rcu/SRCU-P +1 -0
index 4b6f272dba27..4837430a71c0 100644

Lines of this file are not shown. View the raw message.

tools/testing/selftests/rcutorture/configs/rcu/SRCU-P.boot +1 -1
index 238bfe3bd0cc..84a7d51b7481 100644

Lines of this file are not shown. View the raw message.

tools/testing/selftests/rcutorture/configs/rcu/TASKS01 +3 -2
index 97f0a0b27ef7..2cc0e60eba6e 100644

Lines of this file are not shown. View the raw message.

tools/testing/selftests/rcutorture/configs/rcu/TASKS02 +0 -1
index 696d2ea74d13..ad2be91e5ee7 100644

Lines of this file are not shown. View the raw message.

tools/testing/selftests/rcutorture/configs/rcu/TASKS03 +1 -1
index 9c60da5b5d1d..c70c51d5ded1 100644

Lines of this file are not shown. View the raw message.

tools/testing/selftests/rcutorture/configs/rcu/TINY02 +1 -1
index 36e41df3d27a..f1892e0371c9 100644

Lines of this file are not shown. View the raw message.

tools/testing/selftests/rcutorture/configs/rcu/TINY02.boot +1 -0
index 0f0802730014..6c1a292a65fb 100644

Lines of this file are not shown. View the raw message.

tools/testing/selftests/rcutorture/configs/rcu/TREE01 +1 -0
index f8a10a7500c6..8e9137f66831 100644

Lines of this file are not shown. View the raw message.

tools/testing/selftests/rcutorture/configs/rcu/TREE02 +1 -1
index 629122fb8b4a..aeea6a204d14 100644

Lines of this file are not shown. View the raw message.

tools/testing/selftests/rcutorture/configs/rcu/TREE02-T +0 -1
index a25de47888a4..2ac9e68ea3d1 100644

Lines of this file are not shown. View the raw message.

tools/testing/selftests/rcutorture/configs/rcu/TREE03 +4 -4
index 53f24e0a0ab6..72aa7d87ea99 100644

Lines of this file are not shown. View the raw message.

tools/testing/selftests/rcutorture/configs/rcu/TREE03.boot new file +1 -0
new file mode 100644
index 000000000000..120c0c88d100

Lines of this file are not shown. View the raw message.

tools/testing/selftests/rcutorture/configs/rcu/TREE04 +4 -4
index 0f84db35b36d..3f5112751cda 100644

Lines of this file are not shown. View the raw message.

tools/testing/selftests/rcutorture/configs/rcu/TREE05 +2 -2
index 212e3bfd2b2a..c04dfea6fd21 100644

Lines of this file are not shown. View the raw message.

tools/testing/selftests/rcutorture/configs/rcu/TREE06 +2 -2
index 7eee63b44218..f51d2c73a68e 100644

Lines of this file are not shown. View the raw message.

tools/testing/selftests/rcutorture/configs/rcu/TREE06.boot +1 -0
index da9a03a398db..dd90f28ed700 100644

Lines of this file are not shown. View the raw message.

tools/testing/selftests/rcutorture/configs/rcu/TREE07 +2 -2
index 92a97fa97dec..f422af4ff5a3 100644

Lines of this file are not shown. View the raw message.

tools/testing/selftests/rcutorture/configs/rcu/TREE08 +3 -3
index 5812027d6f9f..a24d2ca30646 100644

Lines of this file are not shown. View the raw message.

tools/testing/selftests/rcutorture/configs/rcu/TREE08-T +0 -1
index 3eaeccacb083..b2b8cea69dc9 100644

Lines of this file are not shown. View the raw message.

tools/testing/selftests/rcutorture/configs/rcu/TREE08-T.boot new file +1 -0
new file mode 100644
index 000000000000..883149b5f2d1

Lines of this file are not shown. View the raw message.

tools/testing/selftests/rcutorture/configs/rcu/TREE08.boot +1 -0
index 2561daf605ad..fb066dc82769 100644

Lines of this file are not shown. View the raw message.

tools/testing/selftests/rcutorture/configs/rcu/TREE09 +1 -0
index 6076b36f6c0b..aa4ed08d999d 100644

Lines of this file are not shown. View the raw message.

tools/testing/selftests/rcutorture/doc/TREE_RCU-kconfig.txt +13 -23
index ec03c883db00..b24c0004fc49 100644

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in Please read the FAQ at http://www.tux.org/lkml/

Part of the diff is not shown here. View the raw message.