From 742077de899ef6c6d074b2b6945a82dc61003d91 Mon Sep 17 00:00:00 2001 From: Bernd Schubert Date: Wed, 4 Feb 2026 18:47:37 +0100 Subject: [PATCH] fuse: Fix the reduced queue assignment The use of bitmap_weight() didn't give the actual index, but always returned the current cpu, which resulted in a totally wrong mapping. It now just increases a counter for every mapping and ignores cores not in the given (numa) map and then find the index for that. Also added is a pr_debug(), which can be activated for example with echo "module redfs +p" >/proc/dynamic_debug/control (Pity that upstream is not open for such debug messages). (cherry picked from commit bcbb684ad26c86cc77c04fdab1584ff1ed6bc270) --- fs/fuse/dev_uring.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/fs/fuse/dev_uring.c b/fs/fuse/dev_uring.c index c7ab882fefa4b8..e4959875658422 100644 --- a/fs/fuse/dev_uring.c +++ b/fs/fuse/dev_uring.c @@ -406,26 +406,25 @@ static struct fuse_ring *fuse_uring_create(struct fuse_conn *fc) } static void fuse_uring_cpu_qid_mapping(struct fuse_ring *ring, int qid, - struct fuse_queue_map *q_map) + struct fuse_queue_map *q_map, + int node) { - int cpu, qid_idx; + int cpu, qid_idx, mapping_count = 0; size_t nr_queues; cpumask_set_cpu(qid, q_map->registered_q_mask); nr_queues = cpumask_weight(q_map->registered_q_mask); for (cpu = 0; cpu < ring->max_nr_queues; cpu++) { - if (!q_map->cpu_to_qid) - return; - - /* - * Position of this CPU within the registered queue mask, - * handles non-contiguous CPU distributions across NUMA nodes. - */ - qid_idx = bitmap_weight( - cpumask_bits(q_map->registered_q_mask), cpu); + if (node != -1 && cpu_to_node(cpu) != node) + continue; - q_map->cpu_to_qid[cpu] = cpumask_nth(qid_idx % nr_queues, + qid_idx = mapping_count % nr_queues; + q_map->cpu_to_qid[cpu] = cpumask_nth(qid_idx, q_map->registered_q_mask); + mapping_count++; + pr_debug("%s node=%d qid=%d qid_idx=%d nr_queues=%zu %d->%d\n", + __func__, node, qid, qid_idx, nr_queues, cpu, + q_map->cpu_to_qid[cpu]); } } @@ -476,7 +475,7 @@ static struct fuse_ring_queue *fuse_uring_create_queue(struct fuse_ring *ring, /* Static mapping from cpu to per numa queues */ node = cpu_to_node(qid); - fuse_uring_cpu_qid_mapping(ring, qid, &ring->numa_q_map[node]); + fuse_uring_cpu_qid_mapping(ring, qid, &ring->numa_q_map[node], node); /* * smp_store_release, as the variable is read without fc->lock and @@ -487,7 +486,7 @@ static struct fuse_ring_queue *fuse_uring_create_queue(struct fuse_ring *ring, ring->numa_q_map[node].nr_queues + 1); /* global mapping */ - fuse_uring_cpu_qid_mapping(ring, qid, &ring->q_map); + fuse_uring_cpu_qid_mapping(ring, qid, &ring->q_map, -1); spin_unlock(&fc->lock);