RCU: Question rcu_preempt_blocked_readers_cgp in rcu_gp_fqs_loop func

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux