[PATCH 3/3] Revert "lib/group_cpus.c: avoid acquiring cpu hotplug lock in group_cpus_evenly"
From: Daniel Wagner
Date: Thu Feb 26 2026 - 08:42:48 EST
This reverts commit 0263f92fadbb9d294d5971ac57743f882c93b2b3.
The reason the lock was removed was that the nvme-pci driver reset
handler attempted to acquire the CPU read lock during CPU hotplug
offlining (holds the CPU write lock). Consequently, the block layer
offline notifier callback could not progress because in-flight requests
were detected.
Since then, in-flight detection has been improved, and the nvme-pci
driver now explicitly updates the hctx state when it is safe to ignore
detected in-flight requests. As a result, it's possible to reintroduce
the CPU read lock in group_cpus_evenly.
Signed-off-by: Daniel Wagner <wagi@xxxxxxxxxx>
---
lib/group_cpus.c | 21 +++++----------------
1 file changed, 5 insertions(+), 16 deletions(-)
diff --git a/lib/group_cpus.c b/lib/group_cpus.c
index e6e18d7a49bb..533c722b5c2c 100644
--- a/lib/group_cpus.c
+++ b/lib/group_cpus.c
@@ -510,25 +510,13 @@ struct cpumask *group_cpus_evenly(unsigned int numgrps, unsigned int *nummasks)
if (!masks)
goto fail_node_to_cpumask;
+ /* Stabilize the cpumasks */
+ cpus_read_lock();
build_node_to_cpumask(node_to_cpumask);
- /*
- * Make a local cache of 'cpu_present_mask', so the two stages
- * spread can observe consistent 'cpu_present_mask' without holding
- * cpu hotplug lock, then we can reduce deadlock risk with cpu
- * hotplug code.
- *
- * Here CPU hotplug may happen when reading `cpu_present_mask`, and
- * we can live with the case because it only affects that hotplug
- * CPU is handled in the 1st or 2nd stage, and either way is correct
- * from API user viewpoint since 2-stage spread is sort of
- * optimization.
- */
- cpumask_copy(npresmsk, data_race(cpu_present_mask));
-
/* grouping present CPUs first */
ret = __group_cpus_evenly(curgrp, numgrps, node_to_cpumask,
- npresmsk, nmsk, masks);
+ cpu_present_mask, nmsk, masks);
if (ret < 0)
goto fail_node_to_cpumask;
nr_present = ret;
@@ -543,13 +531,14 @@ struct cpumask *group_cpus_evenly(unsigned int numgrps, unsigned int *nummasks)
curgrp = 0;
else
curgrp = nr_present;
- cpumask_andnot(npresmsk, cpu_possible_mask, npresmsk);
+ cpumask_andnot(npresmsk, cpu_possible_mask, cpu_present_mask);
ret = __group_cpus_evenly(curgrp, numgrps, node_to_cpumask,
npresmsk, nmsk, masks);
if (ret >= 0)
nr_others = ret;
fail_node_to_cpumask:
+ cpus_read_unlock();
free_node_to_cpumask(node_to_cpumask);
fail_npresmsk:
--
2.53.0