Skip to contentSkip to conversation

RCU changes for v3.18

GIT PULL Ingo Molnar 1 participant 1 message Oct 13, 2014

Subsystems (15)
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: fd19bda491207f66d39aeba93487197a087bc00b Merge branch 'rcu/next' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu into core/rcu

The main changes in this cycle were:

* Changes related to No-CBs CPUs and NO_HZ_FULL.

* RCU-tasks implementation.

* Torture-test updates.

* Miscellaneous fixes.

* Locktorture updates.

* RCU documentation updates.

Note, you'll get a conflict in init/main.c, interacting with the earlier timers/nohz tree, which will look like this if you combine v3.17 + timers/nohz + core/rcu:

++<<<<<<< HEAD
+ tick_nohz_init();
+ rcu_init_nohz();
++=======
++>>>>>>> timers/nohz

The correct resolution is to remove this pair:

+ tick_nohz_init();
+ rcu_init_nohz();

and to apply the following change:

        early_irq_init();
        init_IRQ();
        tick_init();
++      rcu_init_nohz();
        init_timers();
        hrtimers_init();
        softirq_init();

That's necessary because tick_nohz_init() must be called after tick_init() and rcu_init_nohz() must be called after tick_nohz_init(). tick_nohz_init() is now called at the end of tick_init() so everything should be fine in the end.

Thanks,

Ingo

------------------>
Ard Biesheuvel (1):
rcu: Define tracepoint strings only if CONFIG_TRACING is set

Davidlohr Bueso (13):
locktorture: Rename locktorture_runnable parameter
locktorture: Add documentation
locktorture: Support mutexes
locktorture: Teach about lock debugging
locktorture: Make statistics generic
torture: Address race in module cleanup
locktorture: Add infrastructure for torturing read locks
locktorture: Support rwsems
locktorture: Introduce torture context
locktorture: Support rwlocks
locktorture: Fix __acquire annotation for spinlock irq
locktorture: Cannot hold read and write lock
locktorture: Cleanup header usage

Joe Lawrence (2):
workqueue: Add quiescent state between work items
workqueue: Use cond_resched_rcu_qs macro

Joe Perches (1):
rcu: Use pr_alert/pr_cont for printing logs

Oleg Nesterov (1):
rcu: Uninline rcu_read_lock_held()

Paul E. McKenney (44):
memory-barriers: Fix control-ordering no-transitivity example
memory-barriers: Retain barrier() in fold-to-zero example
memory-barriers: Fix description of 2-legged-if-based control dependencies
rcu: Break more call_rcu() deadlock involving scheduler and perf
rcu: Make TINY_RCU tinier by putting error checks under #ifdef
rcu: Replace flush_signals() with WARN_ON(signal_pending())
rcu: Add step to initrd documentation
rcutorture: Test partial nohz_full= configuration
rcutorture: Specify MAXSMP=y for TREE01
rcutorture: Specify CONFIG_CPUMASK_OFFSTACK=y for TREE07
rcutorture: Add callback-flood test
torture: Print PID in hung-kernel diagnostic message
torture: Check for nul bytes in console output
rcu: Add call_rcu_tasks()
rcu: Provide cond_resched_rcu_qs() to force quiescent states in long loops
rcu: Add synchronous grace-period waiting for RCU-tasks
rcu: Make TASKS_RCU handle tasks that are almost done exiting
rcutorture: Add torture tests for RCU-tasks
rcutorture: Add RCU-tasks test cases
rcu: Add stall-warning checks for RCU-tasks
rcu: Improve RCU-tasks energy efficiency
documentation: Add verbiage on RCU-tasks stall warning messages
rcu: Defer rcu_tasks_kthread() creation till first call_rcu_tasks()
rcu: Make TASKS_RCU handle nohz_full= CPUs
rcu: Make rcu_tasks_kthread()'s GP-wait loop allow preemption
rcu: Remove redundant preempt_disable() from rcu_note_voluntary_context_switch()
rcu: Additional information on RCU-tasks stall-warning messages
rcu: Remove local_irq_disable() in rcu_preempt_note_context_switch()
rcu: Per-CPU operation cleanups to rcu_*_qs() functions
rcutorture: Add RCU-tasks tests to default rcutorture list
rcu: Fix attempt to avoid unsolicited offloading of callbacks
rcu: Rationalize kthread spawning
rcu: Create rcuo kthreads only for onlined CPUs
rcu: Eliminate redundant rcu_sysidle_state variable
rcu: Don't track sysidle state if no nohz_full= CPUs
rcu: Avoid misordering in __call_rcu_nocb_enqueue()
rcu: Handle NOCB callbacks from irq-disabled idle code
rcu: Avoid misordering in nocb_leader_wait()
locktorture: Make torture scripting account for new _runnable name
locktorture: Add test scenario for mutex_lock
locktorture: Add test scenario for rwsem_lock
rcutorture: Rename rcutorture_runnable parameter
locktorture: Document boot/module parameters
rcu: Eliminate deadlock between CPU hotplug and expedited grace periods

Pranith Kumar (18):
rcu: Remove remaining read-modify-write ACCESS_ONCE() calls
rcu: Fix sparse warning about rcu_batches_completed_preempt() being non-static
rcu: Use bool type for return value in rcu_is_watching()
rcu: Return bool type for rcu_try_advance_all_cbs()
rcu: Return bool type in rcu_lockdep_current_cpu_online()
rcu: Use true/false instead of 1/0 for a bool type
rcu: Update tiny.c references to tree.c
rcu: Remove stale comment in tree.c
rcu: Use rcu_gp_kthread_wake() to wake up grace period kthreads
rcutorture: Fix a sparse warning by marking boost_mutex static
rcutorture: Use bash shell for all the test scripts
rcutorture: Set executable bit and drop bash from Usage
rcu: Check the return value of zalloc_cpumask_var()
rcu: Use true/false for return in __call_rcu_nocb()
rcu: Use true/false for return in rcu_nocb_adopt_orphan_cbs()
rcu: Use false for return in __call_rcu_nocb()
rcu: Return false instead of 0 in rcu_nocb_adopt_orphan_cbs()
rcu: Check for have_rcu_nocb_mask instead of rcu_nocb_mask

Steven Rostedt (1):
rcu: Export RCU-tasks APIs to GPL modules

 Documentation/RCU/stallwarn.txt                    |  33 +-
 Documentation/kernel-parameters.txt                |  68 ++-
 Documentation/locking/locktorture.txt              | 147 ++++++
 Documentation/memory-barriers.txt                  | 128 ++---
 fs/file.c                                          |   2 +-
 include/linux/cpu.h                                |   2 +
 include/linux/init_task.h                          |  12 +-
 include/linux/lockdep.h                            |   1 +
 include/linux/rcupdate.h                           | 106 +++--
 include/linux/rcutiny.h                            |   2 +-
 include/linux/sched.h                              |  39 +-
 include/linux/torture.h                            |   5 +-
 include/trace/events/rcu.h                         |   3 +
 init/Kconfig                                       |  14 +-
 init/main.c                                        |   1 +
 kernel/cpu.c                                       |  16 +-
 kernel/exit.c                                      |   3 +
 kernel/locking/locktorture.c                       | 529 +++++++++++++++++----
 kernel/rcu/rcutorture.c                            | 278 +++++++----
 kernel/rcu/tiny.c                                  |  20 +-
 kernel/rcu/tree.c                                  | 115 +++--
 kernel/rcu/tree.h                                  |  18 +-
 kernel/rcu/tree_plugin.h                           | 404 +++++++++++-----
 kernel/rcu/update.c                                | 345 +++++++++++++-
 kernel/softirq.c                                   |   2 +-
 kernel/sysctl.c                                    |   9 -
 kernel/torture.c                                   |  32 +-
 kernel/workqueue.c                                 |   5 +-
 mm/mlock.c                                         |   2 +-
 .../selftests/rcutorture/bin/config2frag.sh        |   4 +-
 .../selftests/rcutorture/bin/configcheck.sh        |   4 +-
 .../testing/selftests/rcutorture/bin/configinit.sh |   4 +-
 .../testing/selftests/rcutorture/bin/functions.sh  |  20 +
 .../testing/selftests/rcutorture/bin/kvm-build.sh  |   2 +-
 .../selftests/rcutorture/bin/kvm-recheck-lock.sh   |   2 +-
 .../selftests/rcutorture/bin/kvm-recheck-rcu.sh    |   2 +-
 .../selftests/rcutorture/bin/kvm-recheck.sh        |   2 +-
 .../selftests/rcutorture/bin/kvm-test-1-run.sh     |   5 +-
 tools/testing/selftests/rcutorture/bin/kvm.sh      |   6 +-
 .../selftests/rcutorture/bin/parse-build.sh        |   5 +-
 .../selftests/rcutorture/bin/parse-console.sh      |   9 +-
 .../selftests/rcutorture/bin/parse-torture.sh      |   5 +-
 .../selftests/rcutorture/configs/lock/CFLIST       |   3 +
 .../selftests/rcutorture/configs/lock/LOCK02       |   6 +
 .../selftests/rcutorture/configs/lock/LOCK02.boot  |   1 +
 .../selftests/rcutorture/configs/lock/LOCK03       |   6 +
 .../selftests/rcutorture/configs/lock/LOCK03.boot  |   1 +
 .../selftests/rcutorture/configs/lock/LOCK04       |   6 +
 .../selftests/rcutorture/configs/lock/LOCK04.boot  |   1 +
 .../rcutorture/configs/lock/ver_functions.sh       |   2 +-
 .../selftests/rcutorture/configs/rcu/CFLIST        |   3 +
 .../selftests/rcutorture/configs/rcu/TASKS01       |   9 +
 .../selftests/rcutorture/configs/rcu/TASKS01.boot  |   1 +
 .../selftests/rcutorture/configs/rcu/TASKS02       |   5 +
 .../selftests/rcutorture/configs/rcu/TASKS02.boot  |   1 +
 .../selftests/rcutorture/configs/rcu/TASKS03       |  13 +
 .../selftests/rcutorture/configs/rcu/TASKS03.boot  |   1 +
 .../selftests/rcutorture/configs/rcu/TREE01        |   4 +-
 .../selftests/rcutorture/configs/rcu/TREE01.boot   |   2 +-
 .../selftests/rcutorture/configs/rcu/TREE07        |   3 +-
 .../selftests/rcutorture/configs/rcu/TREE07.boot   |   1 +
 .../rcutorture/configs/rcu/ver_functions.sh        |   2 +-
 tools/testing/selftests/rcutorture/doc/initrd.txt  |   1 +
 63 files changed, 1936 insertions(+), 547 deletions(-)
 create mode 100644 Documentation/locking/locktorture.txt
 mode change 100644 => 100755 tools/testing/selftests/rcutorture/bin/config2frag.sh
 mode change 100644 => 100755 tools/testing/selftests/rcutorture/bin/kvm.sh
 create mode 100644 tools/testing/selftests/rcutorture/configs/lock/LOCK02
 create mode 100644 tools/testing/selftests/rcutorture/configs/lock/LOCK02.boot
 create mode 100644 tools/testing/selftests/rcutorture/configs/lock/LOCK03
 create mode 100644 tools/testing/selftests/rcutorture/configs/lock/LOCK03.boot
 create mode 100644 tools/testing/selftests/rcutorture/configs/lock/LOCK04
 create mode 100644 tools/testing/selftests/rcutorture/configs/lock/LOCK04.boot
 create mode 100644 tools/testing/selftests/rcutorture/configs/rcu/TASKS01
 create mode 100644 tools/testing/selftests/rcutorture/configs/rcu/TASKS01.boot
 create mode 100644 tools/testing/selftests/rcutorture/configs/rcu/TASKS02
 create mode 100644 tools/testing/selftests/rcutorture/configs/rcu/TASKS02.boot
 create mode 100644 tools/testing/selftests/rcutorture/configs/rcu/TASKS03
 create mode 100644 tools/testing/selftests/rcutorture/configs/rcu/TASKS03.boot
 create mode 100644 tools/testing/selftests/rcutorture/configs/rcu/TREE07.boot
Documentation/RCU/stallwarn.txt +24 -9
index 68fe3ad27015..ef5a2fd4ff70 100644
@@ -56,8 +56,20 @@ RCU_STALL_RAT_DELAY
 	two jiffies.  (This is a cpp macro, not a kernel configuration
 	parameter.)
 
-When a CPU detects that it is stalling, it will print a message similar
-to the following:
+rcupdate.rcu_task_stall_timeout
+
+	This boot/sysfs parameter controls the RCU-tasks stall warning
+	interval.  A value of zero or less suppresses RCU-tasks stall
+	warnings.  A positive value sets the stall-warning interval
+	in jiffies.  An RCU-tasks stall warning starts wtih the line:
+
+		INFO: rcu_tasks detected stalls on tasks:
+
+	And continues with the output of sched_show_task() for each
+	task stalling the current RCU-tasks grace period.
+
+For non-RCU-tasks flavors of RCU, when a CPU detects that it is stalling,
+it will print a message similar to the following:
 
 INFO: rcu_sched_state detected stall on CPU 5 (t=2500 jiffies)
 
@@ -174,8 +186,12 @@ o	A CPU looping with preemption disabled.  This condition can
 o	A CPU looping with bottom halves disabled.  This condition can
 	result in RCU-sched and RCU-bh stalls.
 
-o	For !CONFIG_PREEMPT kernels, a CPU looping anywhere in the kernel
-	without invoking schedule().
+o	For !CONFIG_PREEMPT kernels, a CPU looping anywhere in the
+	kernel without invoking schedule().  Note that cond_resched()
+	does not necessarily prevent RCU CPU stall warnings.  Therefore,
+	if the looping in the kernel is really expected and desirable
+	behavior, you might need to replace some of the cond_resched()
+	calls with calls to cond_resched_rcu_qs().
 
 o	A CPU-bound real-time task in a CONFIG_PREEMPT kernel, which might
 	happen to preempt a low-priority task in the middle of an RCU
@@ -208,11 +224,10 @@ o	A hardware failure.  This is quite unlikely, but has occurred
 	This resulted in a series of RCU CPU stall warnings, eventually
 	leading the realization that the CPU had failed.
 
-The RCU, RCU-sched, and RCU-bh implementations have CPU stall warning.
-SRCU does not have its own CPU stall warnings, but its calls to
-synchronize_sched() will result in RCU-sched detecting RCU-sched-related
-CPU stalls.  Please note that RCU only detects CPU stalls when there is
-a grace period in progress.  No grace period, no CPU stall warnings.
+The RCU, RCU-sched, RCU-bh, and RCU-tasks implementations have CPU stall
+warning.  Note that SRCU does -not- have CPU stall warnings.  Please note
+that RCU only detects CPU stalls when there is a grace period in progress.
+No grace period, no CPU stall warnings.
 
 To diagnose the cause of the stall, inspect the stack traces.
 The offending function will usually be near the top of the stack.
Documentation/kernel-parameters.txt +67 -1

92 lines not on this page · raw message

Documentation/locking/locktorture.txt new file +147 -0

147 lines not on this page · raw message

Documentation/memory-barriers.txt +66 -62

202 lines not on this page · raw message

fs/file.c +1 -1
index 66923fe3176e..1cafc4c9275b 100644
@@ -367,7 +367,7 @@ static struct fdtable *close_files(struct files_struct * files)
 				struct file * file = xchg(&fdt->fd[i], NULL);
 				if (file) {
 					filp_close(file, files);
-					cond_resched();
+					cond_resched_rcu_qs();
 				}
 			}
 			i++;
include/linux/cpu.h +2 -0
index 95978ad7fcdd..b2d9a43012b2 100644
@@ -213,6 +213,7 @@ extern struct bus_type cpu_subsys;
 extern void cpu_hotplug_begin(void);
 extern void cpu_hotplug_done(void);
 extern void get_online_cpus(void);
+extern bool try_get_online_cpus(void);
 extern void put_online_cpus(void);
 extern void cpu_hotplug_disable(void);
 extern void cpu_hotplug_enable(void);
@@ -230,6 +231,7 @@ int cpu_down(unsigned int cpu);
 static inline void cpu_hotplug_begin(void) {}
 static inline void cpu_hotplug_done(void) {}
 #define get_online_cpus()	do { } while (0)
+#define try_get_online_cpus()	true
 #define put_online_cpus()	do { } while (0)
 #define cpu_hotplug_disable()	do { } while (0)
 #define cpu_hotplug_enable()	do { } while (0)
include/linux/init_task.h +11 -1
index 2bb4c4f3531a..77fc43f8fb72 100644
@@ -111,12 +111,21 @@ extern struct group_info init_groups;
 #ifdef CONFIG_PREEMPT_RCU
 #define INIT_TASK_RCU_PREEMPT(tsk)					\
 	.rcu_read_lock_nesting = 0,					\
-	.rcu_read_unlock_special = 0,					\
+	.rcu_read_unlock_special.s = 0,					\
 	.rcu_node_entry = LIST_HEAD_INIT(tsk.rcu_node_entry),		\
 	INIT_TASK_RCU_TREE_PREEMPT()
 #else
 #define INIT_TASK_RCU_PREEMPT(tsk)
 #endif
+#ifdef CONFIG_TASKS_RCU
+#define INIT_TASK_RCU_TASKS(tsk)					\
+	.rcu_tasks_holdout = false,					\
+	.rcu_tasks_holdout_list =					\
+		LIST_HEAD_INIT(tsk.rcu_tasks_holdout_list),		\
+	.rcu_tasks_idle_cpu = -1,
+#else
+#define INIT_TASK_RCU_TASKS(tsk)
+#endif
 
 extern struct cred init_cred;
 
@@ -224,6 +233,7 @@ extern struct task_group root_task_group;
 	INIT_FTRACE_GRAPH						\
 	INIT_TRACE_RECURSION						\
 	INIT_TASK_RCU_PREEMPT(tsk)					\
+	INIT_TASK_RCU_TASKS(tsk)					\
 	INIT_CPUSET_SEQ(tsk)						\
 	INIT_RT_MUTEXES(tsk)						\
 	INIT_VTIME(tsk)							\
include/linux/lockdep.h +1 -0
index 008388f920d7..4f86465cc317 100644
@@ -505,6 +505,7 @@ static inline void print_irqtrace_events(struct task_struct *curr)
 
 #define lock_map_acquire(l)			lock_acquire_exclusive(l, 0, 0, NULL, _THIS_IP_)
 #define lock_map_acquire_read(l)		lock_acquire_shared_recursive(l, 0, 0, NULL, _THIS_IP_)
+#define lock_map_acquire_tryread(l)		lock_acquire_shared_recursive(l, 0, 1, NULL, _THIS_IP_)
 #define lock_map_release(l)			lock_release(l, 1, _THIS_IP_)
 
 #ifdef CONFIG_PROVE_LOCKING
include/linux/rcupdate.h +65 -41

153 lines not on this page · raw message

include/linux/rcutiny.h +1 -1
index d40a6a451330..38cc5b1e252d 100644
@@ -80,7 +80,7 @@ static inline void kfree_call_rcu(struct rcu_head *head,
 
 static inline void rcu_note_context_switch(int cpu)
 {
-	rcu_sched_qs(cpu);
+	rcu_sched_qs();
 }
 
 /*
include/linux/sched.h +22 -17
index 5c2c885ee52b..42888d715fb1 100644
@@ -1212,6 +1212,13 @@ struct sched_dl_entity {
 	struct hrtimer dl_timer;
 };
 
+union rcu_special {
+	struct {
+		bool blocked;
+		bool need_qs;
+	} b;
+	short s;
+};
 struct rcu_node;
 
 enum perf_event_task_context {
@@ -1264,12 +1271,18 @@ struct task_struct {
 
 #ifdef CONFIG_PREEMPT_RCU
 	int rcu_read_lock_nesting;
-	char rcu_read_unlock_special;
+	union rcu_special rcu_read_unlock_special;
 	struct list_head rcu_node_entry;
 #endif /* #ifdef CONFIG_PREEMPT_RCU */
 #ifdef CONFIG_TREE_PREEMPT_RCU
 	struct rcu_node *rcu_blocked_node;
 #endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */
+#ifdef CONFIG_TASKS_RCU
+	unsigned long rcu_tasks_nvcsw;
+	bool rcu_tasks_holdout;
+	struct list_head rcu_tasks_holdout_list;
+	int rcu_tasks_idle_cpu;
+#endif /* #ifdef CONFIG_TASKS_RCU */
 
 #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
 	struct sched_info sched_info;
@@ -1999,29 +2012,21 @@ extern void task_clear_jobctl_trapping(struct task_struct *task);
 extern void task_clear_jobctl_pending(struct task_struct *task,
 				      unsigned int mask);
 
-#ifdef CONFIG_PREEMPT_RCU
-
-#define RCU_READ_UNLOCK_BLOCKED (1 << 0) /* blocked while in RCU read-side. */
-#define RCU_READ_UNLOCK_NEED_QS (1 << 1) /* RCU core needs CPU response. */
-
 static inline void rcu_copy_process(struct task_struct *p)
 {
+#ifdef CONFIG_PREEMPT_RCU
 	p->rcu_read_lock_nesting = 0;
-	p->rcu_read_unlock_special = 0;
-#ifdef CONFIG_TREE_PREEMPT_RCU
+	p->rcu_read_unlock_special.s = 0;
 	p->rcu_blocked_node = NULL;
-#endif /* #ifdef CONFIG_TREE_PREEMPT_RCU */
 	INIT_LIST_HEAD(&p->rcu_node_entry);
+#endif /* #ifdef CONFIG_PREEMPT_RCU */
+#ifdef CONFIG_TASKS_RCU
+	p->rcu_tasks_holdout = false;
+	INIT_LIST_HEAD(&p->rcu_tasks_holdout_list);
+	p->rcu_tasks_idle_cpu = -1;
+#endif /* #ifdef CONFIG_TASKS_RCU */
 }
 
-#else
-
-static inline void rcu_copy_process(struct task_struct *p)
-{
-}
-
-#endif
-
 static inline void tsk_restore_flags(struct task_struct *task,
 				unsigned long orig_flags, unsigned long flags)
 {
include/linux/torture.h +3 -2
index 5ca58fcbaf1b..7759fc3c622d 100644
@@ -51,7 +51,7 @@
 
 /* Definitions for online/offline exerciser. */
 int torture_onoff_init(long ooholdoff, long oointerval);
-char *torture_onoff_stats(char *page);
+void torture_onoff_stats(void);
 bool torture_onoff_failures(void);
 
 /* Low-rider random number generator. */
@@ -77,7 +77,8 @@ int torture_stutter_init(int s);
 /* Initialization and cleanup. */
 bool torture_init_begin(char *ttype, bool v, int *runnable);
 void torture_init_end(void);
-bool torture_cleanup(void);
+bool torture_cleanup_begin(void);
+void torture_cleanup_end(void);
 bool torture_must_stop(void);
 bool torture_must_stop_irq(void);
 void torture_kthread_stopping(char *title);
include/trace/events/rcu.h +3 -0
index aca382266411..9b56f37148cf 100644
@@ -180,9 +180,12 @@ TRACE_EVENT(rcu_grace_period_init,
  * argument is a string as follows:
  *
  *	"WakeEmpty": Wake rcuo kthread, first CB to empty list.
+ *	"WakeEmptyIsDeferred": Wake rcuo kthread later, first CB to empty list.
  *	"WakeOvf": Wake rcuo kthread, CB list is huge.
+ *	"WakeOvfIsDeferred": Wake rcuo kthread later, CB list is huge.
  *	"WakeNot": Don't wake rcuo kthread.
  *	"WakeNotPoll": Don't wake rcuo kthread because it is polling.
+ *	"DeferredWake": Carried out the "IsDeferred" wakeup.
  *	"Poll": Start of new polling cycle for rcu_nocb_poll.
  *	"Sleep": Sleep waiting for CBs for !rcu_nocb_poll.
  *	"WokeEmpty": rcuo kthread woke to find empty list.
init/Kconfig +12 -2
index e84c6423a2e5..4fe5500b998f 100644
@@ -507,6 +507,16 @@ config PREEMPT_RCU
 	  This option enables preemptible-RCU code that is common between
 	  TREE_PREEMPT_RCU and, in the old days, TINY_PREEMPT_RCU.
 
+config TASKS_RCU
+	bool "Task_based RCU implementation using voluntary context switch"
+	default n
+	help
+	  This option enables a task-based RCU implementation that uses
+	  only voluntary context switch (not preemption!), idle, and
+	  user-mode execution as quiescent states.
+
+	  If unsure, say N.
+
 config RCU_STALL_COMMON
 	def_bool ( TREE_RCU || TREE_PREEMPT_RCU || RCU_TRACE )
 	help
@@ -737,7 +747,7 @@ choice
 
 config RCU_NOCB_CPU_NONE
 	bool "No build_forced no-CBs CPUs"
-	depends on RCU_NOCB_CPU && !NO_HZ_FULL_ALL
+	depends on RCU_NOCB_CPU
 	help
 	  This option does not force any of the CPUs to be no-CBs CPUs.
 	  Only CPUs designated by the rcu_nocbs= boot parameter will be
@@ -751,7 +761,7 @@ config RCU_NOCB_CPU_NONE
 
 config RCU_NOCB_CPU_ZERO
 	bool "CPU 0 is a build_forced no-CBs CPU"
-	depends on RCU_NOCB_CPU && !NO_HZ_FULL_ALL
+	depends on RCU_NOCB_CPU
 	help
 	  This option forces CPU 0 to be a no-CBs CPU, so that its RCU
 	  callbacks are invoked by a per-CPU kthread whose name begins
init/main.c +1 -0
index bb1aed928f21..e3c4cdd94d5b 100644
@@ -578,6 +578,7 @@ asmlinkage __visible void __init start_kernel(void)
 	idr_init_cache();
 	rcu_init();
 	tick_nohz_init();
+	rcu_init_nohz();
 	context_tracking_init();
 	radix_tree_init();
 	/* init some links before init_ISA_irqs() */
kernel/cpu.c +15 -1
index 81e2a388a0f6..356450f09c1f 100644
@@ -79,6 +79,8 @@ static struct {
 
 /* Lockdep annotations for get/put_online_cpus() and cpu_hotplug_begin/end() */
 #define cpuhp_lock_acquire_read() lock_map_acquire_read(&cpu_hotplug.dep_map)
+#define cpuhp_lock_acquire_tryread() \
+				  lock_map_acquire_tryread(&cpu_hotplug.dep_map)
 #define cpuhp_lock_acquire()      lock_map_acquire(&cpu_hotplug.dep_map)
 #define cpuhp_lock_release()      lock_map_release(&cpu_hotplug.dep_map)
 
@@ -91,10 +93,22 @@ void get_online_cpus(void)
 	mutex_lock(&cpu_hotplug.lock);
 	cpu_hotplug.refcount++;
 	mutex_unlock(&cpu_hotplug.lock);
-
 }
 EXPORT_SYMBOL_GPL(get_online_cpus);
 
+bool try_get_online_cpus(void)
+{
+	if (cpu_hotplug.active_writer == current)
+		return true;
+	if (!mutex_trylock(&cpu_hotplug.lock))
+		return false;
+	cpuhp_lock_acquire_tryread();
+	cpu_hotplug.refcount++;
+	mutex_unlock(&cpu_hotplug.lock);
+	return true;
+}
+EXPORT_SYMBOL_GPL(try_get_online_cpus);
+
 void put_online_cpus(void)
 {
 	if (cpu_hotplug.active_writer == current)
kernel/exit.c +3 -0
index 32c58f7433a3..d13f2eec4bb8 100644
@@ -667,6 +667,7 @@ void do_exit(long code)
 {
 	struct task_struct *tsk = current;
 	int group_dead;
+	TASKS_RCU(int tasks_rcu_i);
 
 	profile_task_exit(tsk);
 
@@ -775,6 +776,7 @@ void do_exit(long code)
 	 */
 	flush_ptrace_hw_breakpoint(tsk);
 
+	TASKS_RCU(tasks_rcu_i = __srcu_read_lock(&tasks_rcu_exit_srcu));
 	exit_notify(tsk, group_dead);
 	proc_exit_connector(tsk);
 #ifdef CONFIG_NUMA
@@ -814,6 +816,7 @@ void do_exit(long code)
 	if (tsk->nr_dirtied)
 		__this_cpu_add(dirty_throttle_leaks, tsk->nr_dirtied);
 	exit_rcu();
+	TASKS_RCU(__srcu_read_unlock(&tasks_rcu_exit_srcu, tasks_rcu_i));
 
 	/*
 	 * The setting of TASK_RUNNING by try_to_wake_up() may be delayed
kernel/locking/locktorture.c +445 -84

759 lines not on this page · raw message

kernel/rcu/rcutorture.c +198 -80

441 lines not on this page · raw message

kernel/rcu/tiny.c +11 -9
index d9efcc13008c..c0623fc47125 100644
@@ -51,7 +51,7 @@ static long long rcu_dynticks_nesting = DYNTICK_TASK_EXIT_IDLE;
 
 #include "tiny_plugin.h"
 
-/* Common code for rcu_idle_enter() and rcu_irq_exit(), see kernel/rcutree.c. */
+/* Common code for rcu_idle_enter() and rcu_irq_exit(), see kernel/rcu/tree.c. */
 static void rcu_idle_enter_common(long long newval)
 {
 	if (newval) {
@@ -62,7 +62,7 @@ static void rcu_idle_enter_common(long long newval)
 	}
 	RCU_TRACE(trace_rcu_dyntick(TPS("Start"),
 				    rcu_dynticks_nesting, newval));
-	if (!is_idle_task(current)) {
+	if (IS_ENABLED(CONFIG_RCU_TRACE) && !is_idle_task(current)) {
 		struct task_struct *idle __maybe_unused = idle_task(smp_processor_id());
 
 		RCU_TRACE(trace_rcu_dyntick(TPS("Entry error: not idle task"),
@@ -72,7 +72,7 @@ static void rcu_idle_enter_common(long long newval)
 			  current->pid, current->comm,
 			  idle->pid, idle->comm); /* must be idle task! */
 	}
-	rcu_sched_qs(0); /* implies rcu_bh_qsctr_inc(0) */
+	rcu_sched_qs(); /* implies rcu_bh_inc() */
 	barrier();
 	rcu_dynticks_nesting = newval;
 }
@@ -114,7 +114,7 @@ void rcu_irq_exit(void)
 }
 EXPORT_SYMBOL_GPL(rcu_irq_exit);
 
-/* Common code for rcu_idle_exit() and rcu_irq_enter(), see kernel/rcutree.c. */
+/* Common code for rcu_idle_exit() and rcu_irq_enter(), see kernel/rcu/tree.c. */
 static void rcu_idle_exit_common(long long oldval)
 {
 	if (oldval) {
@@ -123,7 +123,7 @@ static void rcu_idle_exit_common(long long oldval)
 		return;
 	}
 	RCU_TRACE(trace_rcu_dyntick(TPS("End"), oldval, rcu_dynticks_nesting));
-	if (!is_idle_task(current)) {
+	if (IS_ENABLED(CONFIG_RCU_TRACE) && !is_idle_task(current)) {
 		struct task_struct *idle __maybe_unused = idle_task(smp_processor_id());
 
 		RCU_TRACE(trace_rcu_dyntick(TPS("Exit error: not idle task"),
@@ -217,7 +217,7 @@ static int rcu_qsctr_help(struct rcu_ctrlblk *rcp)
  * are at it, given that any rcu quiescent state is also an rcu_bh
  * quiescent state.  Use "+" instead of "||" to defeat short circuiting.
  */
-void rcu_sched_qs(int cpu)
+void rcu_sched_qs(void)
 {
 	unsigned long flags;
 
@@ -231,7 +231,7 @@ void rcu_sched_qs(int cpu)
 /*
  * Record an rcu_bh quiescent state.
  */
-void rcu_bh_qs(int cpu)
+void rcu_bh_qs(void)
 {
 	unsigned long flags;
 
@@ -251,9 +251,11 @@ void rcu_check_callbacks(int cpu, int user)
 {
 	RCU_TRACE(check_cpu_stalls());
 	if (user || rcu_is_cpu_rrupt_from_idle())
-		rcu_sched_qs(cpu);
+		rcu_sched_qs();
 	else if (!in_softirq())
-		rcu_bh_qs(cpu);
+		rcu_bh_qs();
+	if (user)
+		rcu_note_voluntary_context_switch(current);
 }
 
 /*
kernel/rcu/tree.c +69 -46

296 lines not on this page · raw message

kernel/rcu/tree.h +15 -3
index 6a86eb7bac45..d03764652d91 100644
@@ -350,7 +350,7 @@ struct rcu_data {
 	int nocb_p_count_lazy;		/*  (approximate). */
 	wait_queue_head_t nocb_wq;	/* For nocb kthreads to sleep on. */
 	struct task_struct *nocb_kthread;
-	bool nocb_defer_wakeup;		/* Defer wakeup of nocb_kthread. */
+	int nocb_defer_wakeup;		/* Defer wakeup of nocb_kthread. */
 
 	/* The following fields are used by the leader, hence own cacheline. */
 	struct rcu_head *nocb_gp_head ____cacheline_internodealigned_in_smp;
@@ -383,6 +383,11 @@ struct rcu_data {
 #define RCU_FORCE_QS		3	/* Need to force quiescent state. */
 #define RCU_SIGNAL_INIT		RCU_SAVE_DYNTICK
 
+/* Values for nocb_defer_wakeup field in struct rcu_data. */
+#define RCU_NOGP_WAKE_NOT	0
+#define RCU_NOGP_WAKE		1
+#define RCU_NOGP_WAKE_FORCE	2
+
 #define RCU_JIFFIES_TILL_FORCE_QS (1 + (HZ > 250) + (HZ > 500))
 					/* For jiffies_till_first_fqs and */
 					/*  and jiffies_till_next_fqs. */
@@ -572,6 +577,7 @@ static void rcu_preempt_do_callbacks(void);
 static int rcu_spawn_one_boost_kthread(struct rcu_state *rsp,
 						 struct rcu_node *rnp);
 #endif /* #ifdef CONFIG_RCU_BOOST */
+static void __init rcu_spawn_boost_kthreads(void);
 static void rcu_prepare_kthreads(int cpu);
 static void rcu_cleanup_after_idle(int cpu);
 static void rcu_prepare_for_idle(int cpu);
@@ -589,10 +595,14 @@ static bool __call_rcu_nocb(struct rcu_data *rdp, struct rcu_head *rhp,
 static bool rcu_nocb_adopt_orphan_cbs(struct rcu_state *rsp,
 				      struct rcu_data *rdp,
 				      unsigned long flags);
-static bool rcu_nocb_need_deferred_wakeup(struct rcu_data *rdp);
+static int rcu_nocb_need_deferred_wakeup(struct rcu_data *rdp);
 static void do_nocb_deferred_wakeup(struct rcu_data *rdp);
 static void rcu_boot_init_nocb_percpu_data(struct rcu_data *rdp);
-static void rcu_spawn_nocb_kthreads(struct rcu_state *rsp);
+static void rcu_spawn_all_nocb_kthreads(int cpu);
+static void __init rcu_spawn_nocb_kthreads(void);
+#ifdef CONFIG_RCU_NOCB_CPU
+static void __init rcu_organize_nocb_kthreads(struct rcu_state *rsp);
+#endif /* #ifdef CONFIG_RCU_NOCB_CPU */
 static void __maybe_unused rcu_kick_nohz_cpu(int cpu);
 static bool init_nocb_callback_list(struct rcu_data *rdp);
 static void rcu_sysidle_enter(struct rcu_dynticks *rdtp, int irq);
@@ -605,6 +615,8 @@ static void rcu_sysidle_report_gp(struct rcu_state *rsp, int isidle,
 static void rcu_bind_gp_kthread(void);
 static void rcu_sysidle_init_percpu_data(struct rcu_dynticks *rdtp);
 static bool rcu_nohz_full_cpu(struct rcu_state *rsp);
+static void rcu_dynticks_task_enter(void);
+static void rcu_dynticks_task_exit(void);
 
 #endif /* #ifndef RCU_TREE_NONCORE */
 
kernel/rcu/tree_plugin.h +273 -131

485 lines not on this page · raw message

kernel/rcu/update.c +344 -1

345 lines not on this page · raw message

kernel/softirq.c +1 -1
index 5918d227730f..348ec763b104 100644

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

kernel/sysctl.c +0 -9
index 75875a741b5e..ab456664609d 100644

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

kernel/torture.c +20 -12
index d600af21f022..dd70993c266c 100644

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

kernel/workqueue.c +3 -2
index 5dbe22aa3efd..09b685daee3d 100644

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

mm/mlock.c +1 -1
index ce84cb0b83ef..ab3150c26711 100644

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

tools/testing/selftests/rcutorture/bin/config2frag.sh +2 -2
old mode 100644
new mode 100755
index 9f9ffcd427d3..56f51ae13d73

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

tools/testing/selftests/rcutorture/bin/configcheck.sh +2 -2
index d686537dd55c..eee31e261bf7 100755

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

tools/testing/selftests/rcutorture/bin/configinit.sh +2 -2
index 9c3f3d39b934..15f1a17ca96e 100755

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

tools/testing/selftests/rcutorture/bin/functions.sh +20 -0
index d01b865bb100..b325470c01b3 100644

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

tools/testing/selftests/rcutorture/bin/kvm-build.sh +1 -1
index 7c1e56b46de4..00cb0db2643d 100755

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

tools/testing/selftests/rcutorture/bin/kvm-recheck-lock.sh +1 -1
index 7f1ff1a8fc4b..43f764098e50 100755

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

tools/testing/selftests/rcutorture/bin/kvm-recheck-rcu.sh +1 -1
index 307c4b95f325..d6cc07fc137f 100755

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

tools/testing/selftests/rcutorture/bin/kvm-recheck.sh +1 -1
index 3f6c9b78d177..4f5b20f367a9 100755

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

tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh +3 -2
index 0f69dcbf9def..f6b2b4771b78 100755

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

tools/testing/selftests/rcutorture/bin/kvm.sh +4 -2
old mode 100644
new mode 100755
index 589e9c38413b..e527dc952eb0

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

tools/testing/selftests/rcutorture/bin/parse-build.sh +2 -3
index 543230951c38..499d1e598e42 100755

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

tools/testing/selftests/rcutorture/bin/parse-console.sh +6 -3
index 4185d4cab32e..f962ba4cf68b 100755

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

tools/testing/selftests/rcutorture/bin/parse-torture.sh +2 -3
index 3455560ab4e4..e3c5f0705696 100755

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

tools/testing/selftests/rcutorture/configs/lock/CFLIST +3 -0
index a061b22d1892..6910b7370761 100644

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

tools/testing/selftests/rcutorture/configs/lock/LOCK02 new file +6 -0
new file mode 100644
index 000000000000..1d1da1477fc3

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

tools/testing/selftests/rcutorture/configs/lock/LOCK02.boot new file +1 -0
new file mode 100644
index 000000000000..5aa44b4f1b51

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

tools/testing/selftests/rcutorture/configs/lock/LOCK03 new file +6 -0
new file mode 100644
index 000000000000..1d1da1477fc3

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

tools/testing/selftests/rcutorture/configs/lock/LOCK03.boot new file +1 -0
new file mode 100644
index 000000000000..a67bbe0245c9

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

tools/testing/selftests/rcutorture/configs/lock/LOCK04 new file +6 -0
new file mode 100644
index 000000000000..1d1da1477fc3

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

tools/testing/selftests/rcutorture/configs/lock/LOCK04.boot new file +1 -0
new file mode 100644
index 000000000000..48c04fe47fb4

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

tools/testing/selftests/rcutorture/configs/lock/ver_functions.sh +1 -1
index 9746ea1cd6c7..252aae618984 100644

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

tools/testing/selftests/rcutorture/configs/rcu/CFLIST +3 -0
index cd3d29cb0a47..a3a1a05a2b5c 100644

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

tools/testing/selftests/rcutorture/configs/rcu/TASKS01 new file +9 -0
new file mode 100644
index 000000000000..97f0a0b27ef7

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

tools/testing/selftests/rcutorture/configs/rcu/TASKS01.boot new file +1 -0
new file mode 100644
index 000000000000..cd2a188eeb6d

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

tools/testing/selftests/rcutorture/configs/rcu/TASKS02 new file +5 -0
new file mode 100644
index 000000000000..696d2ea74d13

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

tools/testing/selftests/rcutorture/configs/rcu/TASKS02.boot new file +1 -0
new file mode 100644
index 000000000000..cd2a188eeb6d

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

tools/testing/selftests/rcutorture/configs/rcu/TASKS03 new file +13 -0
new file mode 100644
index 000000000000..9c60da5b5d1d

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

tools/testing/selftests/rcutorture/configs/rcu/TASKS03.boot new file +1 -0
new file mode 100644
index 000000000000..cd2a188eeb6d

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

tools/testing/selftests/rcutorture/configs/rcu/TREE01 +1 -3
index 063b7079c621..38e3895759dd 100644

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

tools/testing/selftests/rcutorture/configs/rcu/TREE01.boot +1 -1
index 0fc8a3428938..adc3abc82fb8 100644

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

tools/testing/selftests/rcutorture/configs/rcu/TREE07 +2 -1
index ab6225506909..8f1017666aa7 100644

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

tools/testing/selftests/rcutorture/configs/rcu/TREE07.boot new file +1 -0
new file mode 100644
index 000000000000..d44609937503

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

tools/testing/selftests/rcutorture/configs/rcu/ver_functions.sh +1 -1
index 8977d8d31b19..ffb85ed786fa 100644

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

tools/testing/selftests/rcutorture/doc/initrd.txt +1 -0
index 49d134c25c04..4170e714f044 100644

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

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

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