lkml.org 
[lkml]   [2020]   [Sep]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
SubjectRCU: Question rcu_preempt_blocked_readers_cgp in rcu_gp_fqs_loop func
Date

When config preempt RCU, and then there are multiple levels node, the current task is preempted in rcu read critical region.
the current task be add to "rnp->blkd_tasks" link list, and the "rnp->gp_tasks" may be assigned a value . these rnp is leaf node in RCU tree.

But in "rcu_gp_fqs_loop" func, we check blocked readers in root node.

static void rcu_gp_fqs_loop(void)
{
.....
struct rcu_node *rnp = rcu_get_root();
.....
if (!READ_ONCE(rnp->qsmask) &&
!rcu_preempt_blocked_readers_cgp(rnp)) ------> rnp is root node
break;
....
}

the root node's blkd_tasks never add task, the "rnp->gp_tasks" is never be assigned value, this check is invailed.
Should we check leaf nodes like this

--- a/kernel/rcu/tree.c
+++ b/kernel/rcu/tree.c
@@ -1846,6 +1846,25 @@ static bool rcu_gp_init(void)
return true;
}

+static bool rcu_preempt_blocked_readers(void)
+{
+ struct rcu_node *rnp;
+ unsigned long flags;
+ bool ret = false;
+
+ rcu_for_each_leaf_node(rnp) {
+ raw_spin_lock_irqsave_rcu_node(rnp, flags);
+ if (rcu_preempt_blocked_readers_cgp(rnp)) {
+ ret = true;
+ raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
+ break;
+ }
+ raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
+ }
+
+ return ret;
+}
+
/*
* Helper function for swait_event_idle_exclusive() wakeup at force-quiescent-state
* time.
@@ -1864,7 +1883,7 @@ static bool rcu_gp_fqs_check_wake(int *gfp)
return true;

// The current grace period has completed.
- if (!READ_ONCE(rnp->qsmask) && !rcu_preempt_blocked_readers_cgp(rnp))
+ if (!READ_ONCE(rnp->qsmask) && !rcu_preempt_blocked_readers())
return true;

return false;
@@ -1927,7 +1946,7 @@ static void rcu_gp_fqs_loop(void)
/* Locking provides needed memory barriers. */
/* If grace period done, leave loop. */
if (!READ_ONCE(rnp->qsmask) &&
- !rcu_preempt_blocked_readers_cgp(rnp))
+ !rcu_preempt_blocked_readers())
break;
/* If time for quiescent-state forcing, do it. */
if (!time_after(rcu_state.jiffies_force_qs, jiffies) ||
--

thanks
Qiang
\
 
 \ /
  Last update: 2020-09-09 09:04    [W:0.130 / U:6.060 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site