Blocked tasks need to be promoted before rdp QS reporting, so that the QS reporting infrastructure considers this and does not prematurely end the GP.
Therefore, this patch adds support for the same. Signed-off-by: Joel Fernandes <[email protected]> --- kernel/rcu/tree.c | 7 +++++++ kernel/rcu/tree.h | 2 ++ 2 files changed, 9 insertions(+) diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index f8f43f94adbb..2a20b1a8c5d3 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -2500,6 +2500,13 @@ rcu_report_qs_rdp(struct rcu_data *rdp) WARN_ON_ONCE(rcu_accelerate_cbs(rnp, rdp)); } + /* + * Promote any late-arriving blocked tasks before reporting QS. + * This handles the case where a task blocks just as a GP is + * starting, missing the initial promotion in rcu_gp_init(). + */ + rcu_promote_blocked_tasks_rdp(rdp, rnp); + rcu_disable_urgency_upon_qs(rdp); rcu_report_qs_rnp(mask, rnp, rnp->gp_seq, flags); /* ^^^ Released rnp->lock */ diff --git a/kernel/rcu/tree.h b/kernel/rcu/tree.h index 25eb9200e6ef..809aa77f57f8 100644 --- a/kernel/rcu/tree.h +++ b/kernel/rcu/tree.h @@ -502,6 +502,8 @@ static void rcu_cpu_kthread_setup(unsigned int cpu); static void rcu_spawn_one_boost_kthread(struct rcu_node *rnp); static bool rcu_preempt_has_tasks(struct rcu_node *rnp); static void rcu_promote_blocked_tasks(struct rcu_node *rnp); +static void rcu_promote_blocked_tasks_rdp(struct rcu_data *rdp, + struct rcu_node *rnp); static bool rcu_preempt_need_deferred_qs(struct task_struct *t); static void zero_cpu_stall_ticks(struct rcu_data *rdp); static struct swait_queue_head *rcu_nocb_gp_get(struct rcu_node *rnp); -- 2.34.1

