Re: [PATCH rcu 2/7] rcu/nocb: Invert rcu_state.barrier_mutex VS hotplug lock locking order

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

 





On 6/21/2022 4:14 AM, Paul E. McKenney wrote:
From: Zqiang <qiang1.zhang@xxxxxxxxx>

In case of failure to spawn either rcuog or rcuo[p] kthreads for a given
rdp, rcu_nocb_rdp_deoffload() needs to be called with the hotplug
lock and the barrier_mutex held. However cpus write lock is already held
while calling rcutree_prepare_cpu(). It's not possible to call
rcu_nocb_rdp_deoffload() from there with just locking the barrier_mutex
or this would result in a locking inversion against
rcu_nocb_cpu_deoffload() which holds both locks in the reverse order.

Simply solve this with inverting the locking order inside
rcu_nocb_cpu_[de]offload(). This will be a pre-requisite to toggle NOCB
states toward cpusets anyway.

Signed-off-by: Zqiang <qiang1.zhang@xxxxxxxxx>
Cc: Neeraj Upadhyay <quic_neeraju@xxxxxxxxxxx>
Cc: Boqun Feng <boqun.feng@xxxxxxxxx>
Cc: Uladzislau Rezki <uladzislau.rezki@xxxxxxxx>
Cc: Joel Fernandes <joel@xxxxxxxxxxxxxxxxx>
Signed-off-by: Frederic Weisbecker <frederic@xxxxxxxxxx>
Signed-off-by: Paul E. McKenney <paulmck@xxxxxxxxxx>
---

Reviewed-by: Neeraj Upadhyay <quic_neeraju@xxxxxxxxxxx>


Thanks
Neeraj

  kernel/rcu/tree_nocb.h | 8 ++++----
  1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/kernel/rcu/tree_nocb.h b/kernel/rcu/tree_nocb.h
index dac74952e1d1b..f2f2cab6285a1 100644
--- a/kernel/rcu/tree_nocb.h
+++ b/kernel/rcu/tree_nocb.h
@@ -1055,8 +1055,8 @@ int rcu_nocb_cpu_deoffload(int cpu)
  	struct rcu_data *rdp = per_cpu_ptr(&rcu_data, cpu);
  	int ret = 0;
- mutex_lock(&rcu_state.barrier_mutex);
  	cpus_read_lock();
+	mutex_lock(&rcu_state.barrier_mutex);
  	if (rcu_rdp_is_offloaded(rdp)) {
  		if (cpu_online(cpu)) {
  			ret = work_on_cpu(cpu, rcu_nocb_rdp_deoffload, rdp);
@@ -1067,8 +1067,8 @@ int rcu_nocb_cpu_deoffload(int cpu)
  			ret = -EINVAL;
  		}
  	}
-	cpus_read_unlock();
  	mutex_unlock(&rcu_state.barrier_mutex);
+	cpus_read_unlock();
return ret;
  }
@@ -1134,8 +1134,8 @@ int rcu_nocb_cpu_offload(int cpu)
  	struct rcu_data *rdp = per_cpu_ptr(&rcu_data, cpu);
  	int ret = 0;
- mutex_lock(&rcu_state.barrier_mutex);
  	cpus_read_lock();
+	mutex_lock(&rcu_state.barrier_mutex);
  	if (!rcu_rdp_is_offloaded(rdp)) {
  		if (cpu_online(cpu)) {
  			ret = work_on_cpu(cpu, rcu_nocb_rdp_offload, rdp);
@@ -1146,8 +1146,8 @@ int rcu_nocb_cpu_offload(int cpu)
  			ret = -EINVAL;
  		}
  	}
-	cpus_read_unlock();
  	mutex_unlock(&rcu_state.barrier_mutex);
+	cpus_read_unlock();
return ret;
  }



[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