All of lore.kernel.org
 help / color / mirror / Atom feed
From: Luis Henriques <luis@igalia.com>
To: Bernd Schubert <bschubert@ddn.com>
Cc: Miklos Szeredi <miklos@szeredi.hu>,
	 Ingo Molnar <mingo@redhat.com>,
	Peter Zijlstra <peterz@infradead.org>,
	 Juri Lelli <juri.lelli@redhat.com>,
	 Vincent Guittot <vincent.guittot@linaro.org>,
	Dietmar Eggemann <dietmar.eggemann@arm.com>,
	 Steven Rostedt <rostedt@goodmis.org>,
	 Ben Segall <bsegall@google.com>,  Mel Gorman <mgorman@suse.de>,
	 Valentin Schneider <vschneid@redhat.com>,
	 Joanne Koong <joannelkoong@gmail.com>,
	 linux-fsdevel@vger.kernel.org
Subject: Re: [PATCH v2 3/7] fuse: {io-uring} Use bitmaps to track registered queues
Date: Mon, 06 Oct 2025 10:51:19 +0100	[thread overview]
Message-ID: <87ikgse4tk.fsf@wotan.olymp> (raw)
In-Reply-To: <20251003-reduced-nr-ring-queues_3-v2-3-742ff1a8fc58@ddn.com> (Bernd Schubert's message of "Fri, 03 Oct 2025 12:06:44 +0200")

On Fri, Oct 03 2025, Bernd Schubert wrote:

> Add per-CPU and per-NUMA node bitmasks to track which
> io-uring queues are registered.
>
> Signed-off-by: Bernd Schubert <bschubert@ddn.com>
> ---
>  fs/fuse/dev_uring.c   | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  fs/fuse/dev_uring_i.h |  9 +++++++++
>  2 files changed, 63 insertions(+)
>
> diff --git a/fs/fuse/dev_uring.c b/fs/fuse/dev_uring.c
> index 0f5ab27dacb66c9f5f10eac2713d9bd3eb4c26da..dacc07f5b5b1a48acefa278279f851c3ae2b1489 100644
> --- a/fs/fuse/dev_uring.c
> +++ b/fs/fuse/dev_uring.c
> @@ -18,6 +18,8 @@ MODULE_PARM_DESC(enable_uring,
>  
>  #define FUSE_URING_IOV_SEGS 2 /* header and payload */
>  
> +/* Number of queued fuse requests until a queue is considered full */
> +#define FUSE_URING_QUEUE_THRESHOLD 5

Nit: I guess this hunk can be removed from this patch as this constant is
never used and is removed in the next patch.

Cheers,
-- 
Luís

>  bool fuse_uring_enabled(void)
>  {
> @@ -184,6 +186,18 @@ bool fuse_uring_request_expired(struct fuse_conn *fc)
>  	return false;
>  }
>  
> +static void fuse_ring_destruct_q_masks(struct fuse_ring *ring)
> +{
> +	int node;
> +
> +	free_cpumask_var(ring->registered_q_mask);
> +	if (ring->numa_registered_q_mask) {
> +		for (node = 0; node < ring->nr_numa_nodes; node++)
> +			free_cpumask_var(ring->numa_registered_q_mask[node]);
> +		kfree(ring->numa_registered_q_mask);
> +	}
> +}
> +
>  void fuse_uring_destruct(struct fuse_conn *fc)
>  {
>  	struct fuse_ring *ring = fc->ring;
> @@ -215,11 +229,32 @@ void fuse_uring_destruct(struct fuse_conn *fc)
>  		ring->queues[qid] = NULL;
>  	}
>  
> +	fuse_ring_destruct_q_masks(ring);
>  	kfree(ring->queues);
>  	kfree(ring);
>  	fc->ring = NULL;
>  }
>  
> +static int fuse_ring_create_q_masks(struct fuse_ring *ring)
> +{
> +	int node;
> +
> +	if (!zalloc_cpumask_var(&ring->registered_q_mask, GFP_KERNEL_ACCOUNT))
> +		return -ENOMEM;
> +
> +	ring->numa_registered_q_mask = kcalloc(
> +		ring->nr_numa_nodes, sizeof(cpumask_var_t), GFP_KERNEL_ACCOUNT);
> +	if (!ring->numa_registered_q_mask)
> +		return -ENOMEM;
> +	for (node = 0; node < ring->nr_numa_nodes; node++) {
> +		if (!zalloc_cpumask_var(&ring->numa_registered_q_mask[node],
> +					GFP_KERNEL_ACCOUNT))
> +			return -ENOMEM;
> +	}
> +
> +	return 0;
> +}
> +
>  /*
>   * Basic ring setup for this connection based on the provided configuration
>   */
> @@ -229,11 +264,14 @@ static struct fuse_ring *fuse_uring_create(struct fuse_conn *fc)
>  	size_t nr_queues = num_possible_cpus();
>  	struct fuse_ring *res = NULL;
>  	size_t max_payload_size;
> +	int err;
>  
>  	ring = kzalloc(sizeof(*fc->ring), GFP_KERNEL_ACCOUNT);
>  	if (!ring)
>  		return NULL;
>  
> +	ring->nr_numa_nodes = num_online_nodes();
> +
>  	ring->queues = kcalloc(nr_queues, sizeof(struct fuse_ring_queue *),
>  			       GFP_KERNEL_ACCOUNT);
>  	if (!ring->queues)
> @@ -242,6 +280,10 @@ static struct fuse_ring *fuse_uring_create(struct fuse_conn *fc)
>  	max_payload_size = max(FUSE_MIN_READ_BUFFER, fc->max_write);
>  	max_payload_size = max(max_payload_size, fc->max_pages * PAGE_SIZE);
>  
> +	err = fuse_ring_create_q_masks(ring);
> +	if (err)
> +		goto out_err;
> +
>  	spin_lock(&fc->lock);
>  	if (fc->ring) {
>  		/* race, another thread created the ring in the meantime */
> @@ -261,6 +303,7 @@ static struct fuse_ring *fuse_uring_create(struct fuse_conn *fc)
>  	return ring;
>  
>  out_err:
> +	fuse_ring_destruct_q_masks(ring);
>  	kfree(ring->queues);
>  	kfree(ring);
>  	return res;
> @@ -423,6 +466,7 @@ static void fuse_uring_log_ent_state(struct fuse_ring *ring)
>  			pr_info(" ent-commit-queue ring=%p qid=%d ent=%p state=%d\n",
>  				ring, qid, ent, ent->state);
>  		}
> +
>  		spin_unlock(&queue->lock);
>  	}
>  	ring->stop_debug_log = 1;
> @@ -469,6 +513,7 @@ static void fuse_uring_async_stop_queues(struct work_struct *work)
>  void fuse_uring_stop_queues(struct fuse_ring *ring)
>  {
>  	int qid;
> +	int node;
>  
>  	for (qid = 0; qid < ring->max_nr_queues; qid++) {
>  		struct fuse_ring_queue *queue = READ_ONCE(ring->queues[qid]);
> @@ -479,6 +524,11 @@ void fuse_uring_stop_queues(struct fuse_ring *ring)
>  		fuse_uring_teardown_entries(queue);
>  	}
>  
> +	/* Reset all queue masks, we won't process any more IO */
> +	cpumask_clear(ring->registered_q_mask);
> +	for (node = 0; node < ring->nr_numa_nodes; node++)
> +		cpumask_clear(ring->numa_registered_q_mask[node]);
> +
>  	if (atomic_read(&ring->queue_refs) > 0) {
>  		ring->teardown_time = jiffies;
>  		INIT_DELAYED_WORK(&ring->async_teardown_work,
> @@ -982,6 +1032,7 @@ static void fuse_uring_do_register(struct fuse_ring_ent *ent,
>  	struct fuse_ring *ring = queue->ring;
>  	struct fuse_conn *fc = ring->fc;
>  	struct fuse_iqueue *fiq = &fc->iq;
> +	int node = cpu_to_node(queue->qid);
>  
>  	fuse_uring_prepare_cancel(cmd, issue_flags, ent);
>  
> @@ -990,6 +1041,9 @@ static void fuse_uring_do_register(struct fuse_ring_ent *ent,
>  	fuse_uring_ent_avail(ent, queue);
>  	spin_unlock(&queue->lock);
>  
> +	cpumask_set_cpu(queue->qid, ring->registered_q_mask);
> +	cpumask_set_cpu(queue->qid, ring->numa_registered_q_mask[node]);
> +
>  	if (!ring->ready) {
>  		bool ready = is_ring_ready(ring, queue->qid);
>  
> diff --git a/fs/fuse/dev_uring_i.h b/fs/fuse/dev_uring_i.h
> index 708412294982566919122a1a0d7f741217c763ce..35e3b6808b60398848965afd3091b765444283ff 100644
> --- a/fs/fuse/dev_uring_i.h
> +++ b/fs/fuse/dev_uring_i.h
> @@ -115,6 +115,9 @@ struct fuse_ring {
>  	/* number of ring queues */
>  	size_t max_nr_queues;
>  
> +	/* number of numa nodes */
> +	int nr_numa_nodes;
> +
>  	/* maximum payload/arg size */
>  	size_t max_payload_sz;
>  
> @@ -125,6 +128,12 @@ struct fuse_ring {
>  	 */
>  	unsigned int stop_debug_log : 1;
>  
> +	/* Tracks which queues are registered */
> +	cpumask_var_t registered_q_mask;
> +
> +	/* Tracks which queues are registered per NUMA node */
> +	cpumask_var_t *numa_registered_q_mask;
> +
>  	wait_queue_head_t stop_waitq;
>  
>  	/* async tear down */
>
> -- 
> 2.43.0
>
>


  reply	other threads:[~2025-10-06 10:12 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-10-03 10:06 [PATCH v2 0/7] fuse: {io-uring} Allow to reduce the number of queues and request distribution Bernd Schubert
2025-10-03 10:06 ` [PATCH v2 1/7] fuse: {io-uring} Add queue length counters Bernd Schubert
2025-10-03 10:06 ` [PATCH v2 2/7] fuse: {io-uring} Rename ring->nr_queues to max_nr_queues Bernd Schubert
2025-10-03 10:06 ` [PATCH v2 3/7] fuse: {io-uring} Use bitmaps to track registered queues Bernd Schubert
2025-10-06  9:51   ` Luis Henriques [this message]
2025-10-03 10:06 ` [PATCH v2 4/7] fuse: {io-uring} Distribute load among queues Bernd Schubert
2025-10-03 10:06 ` [PATCH v2 5/7] fuse: {io-uring} Allow reduced number of ring queues Bernd Schubert
2025-10-06 10:35   ` Bernd Schubert
2025-10-03 10:06 ` [PATCH v2 6/7] fuse: {io-uring} Queue background requests on a different core Bernd Schubert
2025-10-06  9:53   ` Luis Henriques
2025-10-06 10:31     ` Bernd Schubert
2025-10-03 10:06 ` [PATCH v2 7/7] fuse: Wake requests on the same cpu Bernd Schubert

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87ikgse4tk.fsf@wotan.olymp \
    --to=luis@igalia.com \
    --cc=bschubert@ddn.com \
    --cc=bsegall@google.com \
    --cc=dietmar.eggemann@arm.com \
    --cc=joannelkoong@gmail.com \
    --cc=juri.lelli@redhat.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=mgorman@suse.de \
    --cc=miklos@szeredi.hu \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=vincent.guittot@linaro.org \
    --cc=vschneid@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.