rcu-tasks: Provide boot parameter to delay IPIs until late in grace period
authorPaul E. McKenney <paulmck@kernel.org>
Tue, 17 Mar 2020 18:39:26 +0000 (11:39 -0700)
committerPaul E. McKenney <paulmck@kernel.org>
Mon, 27 Apr 2020 18:03:52 +0000 (11:03 -0700)
This commit provides a rcupdate.rcu_task_ipi_delay kernel boot parameter
that specifies how old the RCU tasks trace grace period must be before
the grace-period kthread starts sending IPIs.  This delay allows more
tasks to pass through rcu_tasks_qs() quiescent states, thus reducing
(or even eliminating) the number of IPIs that must be sent.

On a short rcutorture test setting this kernel boot parameter to HZ/2
resulted in zero IPIs for all 877 RCU-tasks trace grace periods that
elapsed during that test.

Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
Documentation/admin-guide/kernel-parameters.txt
kernel/rcu/tasks.h

index f2a93c8679e889151aea5261262d1c7dc13635e6..aaa867860433eda13b8dddcb87f5b46a9ceebc67 100644 (file)
                        only normal grace-period primitives.  No effect
                        on CONFIG_TINY_RCU kernels.
 
+       rcupdate.rcu_task_ipi_delay= [KNL]
+                       Set time in jiffies during which RCU tasks will
+                       avoid sending IPIs, starting with the beginning
+                       of a given grace period.  Setting a large
+                       number avoids disturbing real-time workloads,
+                       but lengthens grace periods.
+
        rcupdate.rcu_task_stall_timeout= [KNL]
                        Set timeout in jiffies for RCU task stall warning
                        messages.  Disable with a value less than or equal
index 71462cf3d4bd32b0611964cb2292057016bd7063..eeac4a1222344ea1365bafaec07808ff44a16e4b 100644 (file)
@@ -74,6 +74,11 @@ static struct rcu_tasks rt_name =                                    \
 /* Track exiting tasks in order to allow them to be waited for. */
 DEFINE_STATIC_SRCU(tasks_rcu_exit_srcu);
 
+/* Avoid IPIing CPUs early in the grace period. */
+#define RCU_TASK_IPI_DELAY (HZ / 2)
+static int rcu_task_ipi_delay __read_mostly = RCU_TASK_IPI_DELAY;
+module_param(rcu_task_ipi_delay, int, 0644);
+
 /* Control stall timeouts.  Disable with <= 0, otherwise jiffies till stall. */
 #define RCU_TASK_STALL_TIMEOUT (HZ * 60 * 10)
 static int rcu_task_stall_timeout __read_mostly = RCU_TASK_STALL_TIMEOUT;
@@ -713,6 +718,10 @@ DECLARE_WAIT_QUEUE_HEAD(trc_wait); // List of holdout tasks.
 // Record outstanding IPIs to each CPU.  No point in sending two...
 static DEFINE_PER_CPU(bool, trc_ipi_to_cpu);
 
+void call_rcu_tasks_trace(struct rcu_head *rhp, rcu_callback_t func);
+DEFINE_RCU_TASKS(rcu_tasks_trace, rcu_tasks_wait_gp, call_rcu_tasks_trace,
+                "RCU Tasks Trace");
+
 /* If we are the last reader, wake up the grace-period kthread. */
 void rcu_read_unlock_trace_special(struct task_struct *t)
 {
@@ -998,10 +1007,6 @@ void exit_tasks_rcu_finish_trace(struct task_struct *t)
                rcu_read_unlock_trace_special(t);
 }
 
-void call_rcu_tasks_trace(struct rcu_head *rhp, rcu_callback_t func);
-DEFINE_RCU_TASKS(rcu_tasks_trace, rcu_tasks_wait_gp, call_rcu_tasks_trace,
-                "RCU Tasks Trace");
-
 /**
  * call_rcu_tasks_trace() - Queue a callback trace task-based grace period
  * @rhp: structure to be used for queueing the RCU updates.