[PATCH 2/3] srcu: protect against concurrent srcu_gp_end()

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

 



At present, the code chunk "Transition to big if needed" is out of the
lock srcu_cb_mutex, which allows the following scene:

    srcu_gp_end() on cpu1                srcu_gp_end() on cpu2

    init_srcu_struct_nodes()
    ^^  scheduled out in the middle
                                         init_srcu_struct_nodes()
                                         ^^ overwrite the context set up by cpu1

Squashing out the race window by putting the code chunk under the
protection of srcu_cb_mutex.

Signed-off-by: Pingfan Liu <kernelfans@xxxxxxxxx>
Cc: Lai Jiangshan <jiangshanlai@xxxxxxxxx>
Cc: "Paul E. McKenney" <paulmck@xxxxxxxxxx>
Cc: Frederic Weisbecker <frederic@xxxxxxxxxx>
Cc: Josh Triplett <josh@xxxxxxxxxxxxxxxx>
Cc: Steven Rostedt <rostedt@xxxxxxxxxxx>
Cc: Mathieu Desnoyers <mathieu.desnoyers@xxxxxxxxxxxx>
Cc: "Zhang, Qiang1" <qiang1.zhang@xxxxxxxxx>
To: rcu@xxxxxxxxxxxxxxx
---
 kernel/rcu/srcutree.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c
index fe0759d89c2d..281cd69fe804 100644
--- a/kernel/rcu/srcutree.c
+++ b/kernel/rcu/srcutree.c
@@ -811,6 +811,13 @@ static void srcu_gp_end(struct srcu_struct *ssp)
 			spin_unlock_irqrestore_rcu_node(sdp, flags);
 		}
 
+	/* Transition to big if needed. */
+	if (ss_state != SRCU_SIZE_SMALL && ss_state != SRCU_SIZE_BIG) {
+		if (ss_state == SRCU_SIZE_ALLOC)
+			init_srcu_struct_nodes(ssp, GFP_KERNEL);
+		else
+			smp_store_release(&ssp->srcu_size_state, ss_state + 1);
+	}
 	/* Callback initiation done, allow grace periods after next. */
 	mutex_unlock(&ssp->srcu_cb_mutex);
 
@@ -826,13 +833,6 @@ static void srcu_gp_end(struct srcu_struct *ssp)
 		spin_unlock_irq_rcu_node(ssp);
 	}
 
-	/* Transition to big if needed. */
-	if (ss_state != SRCU_SIZE_SMALL && ss_state != SRCU_SIZE_BIG) {
-		if (ss_state == SRCU_SIZE_ALLOC)
-			init_srcu_struct_nodes(ssp, GFP_KERNEL);
-		else
-			smp_store_release(&ssp->srcu_size_state, ss_state + 1);
-	}
 }
 
 /*
-- 
2.31.1




[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