Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 28 additions & 13 deletions fs/fuse/dev_uring.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@ MODULE_PARM_DESC(enable_uring,
#define FUSE_RING_HEADER_PG 0
#define FUSE_RING_PAYLOAD_PG 1

/* Threshold that determines if a better queue should be searched for */
#define FUSE_URING_Q_THRESHOLD 2

/* Number of (re)tries to find a better queue */
#define FUSE_URING_Q_TRIES 3

/* redfs only to allow patch backports */
#define IO_URING_F_TASK_DEAD (1 << 13)

Expand Down Expand Up @@ -1557,7 +1561,7 @@ static struct fuse_ring_queue *fuse_uring_select_queue(struct fuse_ring *ring,
bool background)
{
unsigned int qid;
int node, retries = 0;
int node, tries = 0;
unsigned int nr_queues;
unsigned int cpu = task_cpu(current);
struct fuse_ring_queue *queue, *primary_queue = NULL;
Expand All @@ -1582,26 +1586,36 @@ static struct fuse_ring_queue *fuse_uring_select_queue(struct fuse_ring *ring,

nr_queues = READ_ONCE(ring->numa_q_map[node].nr_queues);
if (nr_queues) {
/* prefer the queue that corresponds to the current cpu */
queue = READ_ONCE(ring->queues[cpu]);
if (queue) {
if (queue->nr_reqs <= FUSE_URING_Q_THRESHOLD)
return queue;
primary_queue = queue;
}

qid = ring->numa_q_map[node].cpu_to_qid[cpu];
if (WARN_ON_ONCE(qid >= ring->max_nr_queues))
return NULL;
queue = READ_ONCE(ring->queues[qid]);
if (qid != cpu) {
queue = READ_ONCE(ring->queues[qid]);

/* Might happen on teardown */
if (unlikely(!queue))
return NULL;
/* Might happen on teardown */
if (unlikely(!queue))
return NULL;

if (queue->nr_reqs < FUSE_URING_Q_THRESHOLD)
return queue;
if (queue->nr_reqs <= FUSE_URING_Q_THRESHOLD)
return queue;
}

/* Retries help for load balancing */
if (retries < FUSE_URING_Q_THRESHOLD) {
if (!retries)
if (tries < FUSE_URING_Q_TRIES && tries + 1 < nr_queues) {
if (!primary_queue)
primary_queue = queue;

/* Increase cpu, assuming it will map to a differet qid*/
/* Increase cpu, assuming it will map to a different qid*/
cpu++;
retries++;
tries++;
goto retry;
}
}
Expand All @@ -1612,9 +1626,10 @@ static struct fuse_ring_queue *fuse_uring_select_queue(struct fuse_ring *ring,

/* global registered queue bitmap */
qid = ring->q_map.cpu_to_qid[cpu];
if (WARN_ON_ONCE(qid >= ring->max_nr_queues))
/* Might happen on teardown */
if (WARN_ON_ONCE(qid >= ring->max_nr_queues)) {
/* Might happen on teardown */
return NULL;
}
return READ_ONCE(ring->queues[qid]);
}

Expand Down