From: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Date: Mon, 7 Mar 2022 17:08:23 +0100 Subject: [PATCH] rcu-tasks: Use schedule_hrtimeout_range() while waiting for the gp. The RCU selftest is using schedule_timeout_idle() which fails on PREEMPT_RT because it is used early in boot-up phase an which point ksoftirqd is not yet ready and is required for the timer to expire. To avoid this lockup, use schedule_hrtimeout() and let the timer expire in hardirq context. This is ensures that the timer fires even on PREEMPT_RT without any further requirement. The timer is set to expire between fract and fract + HZ / 2 jiffies in order to minimize the amount of extra wake ups and to allign with possible other timer which expire within this window. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> --- kernel/rcu/tasks.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) --- a/kernel/rcu/tasks.h +++ b/kernel/rcu/tasks.h @@ -630,12 +630,15 @@ static void rcu_tasks_wait_gp(struct rcu while (!list_empty(&holdouts)) { bool firstreport; bool needreport; + ktime_t exp; int rtst; /* Slowly back off waiting for holdouts */ set_tasks_gp_state(rtp, RTGS_WAIT_SCAN_HOLDOUTS); - schedule_timeout_idle(fract); - + exp = jiffies_to_nsecs(fract); + __set_current_state(TASK_IDLE); + schedule_hrtimeout_range(&exp, jiffies_to_nsecs(HZ / 2), + HRTIMER_MODE_REL_HARD); if (fract < HZ) fract++;