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

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

 



>Subject: [PATCH 2/3] srcu: protect against concurrent srcu_gp_end()
>
>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

Hi Pingfan

This scenario shouldn't happen.
The srcu_gp_end() is invoked only in process_srcu() workfn.
for the same ssp->work, workqueue can guaranteed that the 
process_srcu() workfn is executed serially. (view __queue_work () details)


Thanks
Zqiang


>
>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