Linux block layer
 help / color / mirror / Atom feed
* Re: [PATCH v6 1/1] block/blk-mq: use atomic_t for quiesce_depth to avoid lock contention on RT
From: Bart Van Assche @ 2026-05-06  9:43 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: Ionut Nechita (Wind River), axboe, linux-block, clrkwllms,
	rostedt, ming.lei, muchun.song, mkhalfella, chris.friesen,
	linux-kernel, linux-rt-devel, linux-rt-users, stable, ionut_n2001,
	sunlightlinux
In-Reply-To: <20260506074758.8zEg1ZBh@linutronix.de>

On 5/6/26 9:47 AM, Sebastian Andrzej Siewior wrote:
> On 2026-05-06 09:14:33 [+0200], Bart Van Assche wrote:
>> If the atomic_inc() in blk_mq_quiesce_queue_nowait() is protected by
>> hctx->queue->queue_lock then the above code doesn't have to be modified.
> 
> But wouldn't the atomic_inc + barrier avoid the need to have the lock?
> Isn't this a normal pattern? If the lock is kept, we could use
> non-atomic ops here then. But this avoids having the lock.

I strongly prefer a spinlock + non-atomic variables rather than using an
atomic variable and barriers because algorithms that use a spinlock are
easier to verify.

Thanks,

Bart.

^ permalink raw reply

* [PATCH v2] block: add NULL checks for bic in bfq_bfqq_save_state function
From: yanlonglong @ 2026-05-06  9:04 UTC (permalink / raw)
  To: axboe; +Cc: linux-block, linux-kernel, yanlonglong, yukuai
In-Reply-To: <db3d516f-6ad2-469a-9bd8-1a9b61eb12a0@kernel.dk>

When the `bic` variable is null, referencing `bfqq_data` through `bic` will
cause the program to crash. Therefore, the null check for `bic` should be
moved to the beginning of the function to prevent referencing a null pointer.

Fixed:fd571df0ac5b289af8("block, bfq: turn bfqq_data into an array in bfq_io_cq")
Signed-off-by: yanlonglong <yanlonglong@kylinos.cn>
---
 block/bfq-iosched.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
index 141c602d5e85..e952e4ea2dd4 100644
--- a/block/bfq-iosched.c
+++ b/block/bfq-iosched.c
@@ -3035,9 +3035,8 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
 static void bfq_bfqq_save_state(struct bfq_queue *bfqq)
 {
 	struct bfq_io_cq *bic = bfqq->bic;
-	unsigned int a_idx = bfqq->actuator_idx;
-	struct bfq_iocq_bfqq_data *bfqq_data = &bic->bfqq_data[a_idx];
-
+	unsigned int a_idx = 0;
+	struct bfq_iocq_bfqq_data *bfqq_data = NULL;
 	/*
 	 * If !bfqq->bic, the queue is already shared or its requests
 	 * have already been redirected to a shared queue; both idle window
@@ -3046,6 +3045,9 @@ static void bfq_bfqq_save_state(struct bfq_queue *bfqq)
 	if (!bic)
 		return;
 
+	a_idx = bfqq->actuator_idx;
+	bfqq_data = &bic->bfqq_data[a_idx];
+
 	bfqq_data->saved_last_serv_time_ns = bfqq->last_serv_time_ns;
 	bfqq_data->saved_inject_limit =	bfqq->inject_limit;
 	bfqq_data->saved_decrease_time_jif = bfqq->decrease_time_jif;
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH v3 00/10] Add dmabuf read/write via io_uring
From: Pavel Begunkov @ 2026-05-06  9:02 UTC (permalink / raw)
  To: Ming Lei
  Cc: Jens Axboe, Keith Busch, Christoph Hellwig, Sagi Grimberg,
	Alexander Viro, Christian Brauner, Andrew Morton, Sumit Semwal,
	Christian König, linux-block, linux-kernel, linux-nvme,
	linux-fsdevel, io-uring, linux-media, dri-devel, linaro-mm-sig,
	Nitesh Shetty, Kanchan Joshi, Anuj Gupta, Tushar Gohad,
	William Power, Phil Cayton, Jason Gunthorpe
In-Reply-To: <afi7c-VUJWOLlC1m@fedora>

Hey Ming,

On 5/4/26 16:29, Ming Lei wrote:
> On Wed, Apr 29, 2026 at 04:25:46PM +0100, Pavel Begunkov wrote:
>> The patch set allows to register a dmabuf to an io_uring instance for
>> a specified file and use it with io_uring read / write requests. The
>> infrastructure is not tied to io_uring and there could be more users
>> in the future. A similar idea was attempted some years ago by Keith [1],
>> from where I borrowed a good number of changes, and later was brough up
>> by Tushar and Vishal from Intel.
>>
>> It's an opt-in feature for files, and they need to implement a new
>> file operation to use it. Only NVMe block devices are supported in this
>> series. The user API is built on top of io_uring's "registered buffers",
>> where a dmabuf is registered in a special way, but after it can be used
>> as any other "registered buffer" with IORING_OP_{READ,WRITE}_FIXED
>> requests. It's created via a new file operation and the resulted map is
>> then passed through the I/O stack in a new iterator type. There is some
>> additional infrastructure to bind it all, which also counts requests
>> using a dmabuf map and managing lifetimes, which is used to implement
>> map invalidation.
>>
>> It was tested for GPU <-> NVMe transfers. Also, as it maintains a
>> long-term dma mapping, it helps with the IOMMU cost. The numbers
>> below are for udmabuf reads previously run by Anuj for different
>> IOMMU modes:
> 
> Plain registered buffer is long-live too, which raises question: does this
> framework need to take it into account from beginning?

Not sure I follow, mind expanding on what should be accounted?
Are you suggesting that we might want to use normal registered
buffers in a similar way? I.e. giving the driver an ability to
pre-register them?

> BTW, inspired by this approach, I adds similar feature to ublk via UBLK_IO_F_SHMEM_ZC
> which can maintain long-term vfio dma mapping over registered user-place aligned buffer.

Interesting, just too a glance, and it looks like what David Wei
was thinking to add to fuse, but IIUC he gave up exactly because the
client will need to cooperate and that could be troublesome.

Should we try to push everything under the same interface instead of
keeping a ublk specific one? Again to the point that it requires
a cooperative client, but if it's something more generic, the user
might just try to use it as a general optimisation. In the same way
it'll be helpful to fuse, and as a bonus you wouldn't need tree look
ups (but mandates clients using registered buffers as a downside).

It'd need to shaped to somehow work better with host memory as I
assume you want to be able to map it into server in common case.
Switch case'ing if it's a udmabuf is not the greatest approach,
but maybe we can figure out something else.
  
-- 
Pavel Begunkov


^ permalink raw reply

* [PATCH v2] ublk: validate physical_bs_shift, io_min_shift and io_opt_shift
From: Ming Lei @ 2026-05-06  8:22 UTC (permalink / raw)
  To: Jens Axboe, linux-block; +Cc: Caleb Sander Mateos, Uday Shankar, Ming Lei

ublk_validate_params() checks logical_bs_shift is within
[9, PAGE_SHIFT] but has no upper bound for physical_bs_shift,
io_min_shift, or io_opt_shift. A malicious userspace can set any
of these to a large value (e.g., 44), causing undefined behavior
from `1 << shift` in ublk_ctrl_start_dev() since the result is
stored in 32-bit unsigned int.

Cap all three at ilog2(SZ_256M) (28). 256M is big enough to cover
all practical block sizes, and originates from the maximum physical
block size possible in NVMe (lba_size * (1 + npwg), where npwg is
16-bit).

Also zero out ub->params with memset() when copy_from_user() fails
or ublk_validate_params() returns error, so that no stale or partial
params survive for a subsequent START_DEV to consume.

Fixes: 71f28f3136af ("ublk_drv: add io_uring based userspace block driver")
Signed-off-by: Ming Lei <tom.leiming@gmail.com>
---
V2:
	- zero out ub->params in case of partial copy or validation failure

 drivers/block/ublk_drv.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
index d10460d29e4a..57ec900f0ce0 100644
--- a/drivers/block/ublk_drv.c
+++ b/drivers/block/ublk_drv.c
@@ -900,6 +900,20 @@ static int ublk_validate_params(const struct ublk_device *ub)
 		if (p->logical_bs_shift > PAGE_SHIFT || p->logical_bs_shift < 9)
 			return -EINVAL;
 
+		/*
+		 * 256M is a reasonable upper bound for physical block size,
+		 * io_min and io_opt; it aligns with the maximum physical
+		 * block size possible in NVMe.
+		 */
+		if (p->physical_bs_shift > ilog2(SZ_256M))
+			return -EINVAL;
+
+		if (p->io_min_shift > ilog2(SZ_256M))
+			return -EINVAL;
+
+		if (p->io_opt_shift > ilog2(SZ_256M))
+			return -EINVAL;
+
 		if (p->logical_bs_shift > p->physical_bs_shift)
 			return -EINVAL;
 
@@ -4992,13 +5006,15 @@ static int ublk_ctrl_set_params(struct ublk_device *ub,
 		 */
 		ret = -EACCES;
 	} else if (copy_from_user(&ub->params, argp, ph.len)) {
+		/* zero out partial copy so no stale params survive */
+		memset(&ub->params, 0, sizeof(ub->params));
 		ret = -EFAULT;
 	} else {
 		/* clear all we don't support yet */
 		ub->params.types &= UBLK_PARAM_TYPE_ALL;
 		ret = ublk_validate_params(ub);
 		if (ret)
-			ub->params.types = 0;
+			memset(&ub->params, 0, sizeof(ub->params));
 	}
 	mutex_unlock(&ub->mutex);
 
-- 
2.53.0


^ permalink raw reply related

* Re: [PATCH v6 1/1] block/blk-mq: use atomic_t for quiesce_depth to avoid lock contention on RT
From: Sebastian Andrzej Siewior @ 2026-05-06  7:47 UTC (permalink / raw)
  To: Bart Van Assche
  Cc: Ionut Nechita (Wind River), axboe, linux-block, clrkwllms,
	rostedt, ming.lei, muchun.song, mkhalfella, chris.friesen,
	linux-kernel, linux-rt-devel, linux-rt-users, stable, ionut_n2001,
	sunlightlinux
In-Reply-To: <50187fa5-03a9-4ca3-bcaf-a36ed75bda2c@acm.org>

On 2026-05-06 09:14:33 [+0200], Bart Van Assche wrote:
> On 5/6/26 8:56 AM, Ionut Nechita (Wind River) wrote:
> >   void blk_mq_quiesce_queue_nowait(struct request_queue *q)
> >   {
> > -	unsigned long flags;
> > -
> > -	spin_lock_irqsave(&q->queue_lock, flags);
> > -	if (!q->quiesce_depth++)
> > -		blk_queue_flag_set(QUEUE_FLAG_QUIESCED, q);
> > -	spin_unlock_irqrestore(&q->queue_lock, flags);
> > +	atomic_inc(&q->quiesce_depth);
> > +	/*
> > +	 * Pairs with smp_rmb() in blk_mq_run_hw_queue(): make the
> > +	 * incremented quiesce_depth observable to readers re-checking
> > +	 * the quiesce state, so they don't dispatch on a quiesced queue.
> > +	 */
> > +	smp_mb__after_atomic();
> >   }
> 
> No, this is not sufficient to guarantee that blk_mq_run_hw_queue() sees
> the latest value of q->quiesce_depth. If you want to achieve that I
> think the only option is to protect the atomic_inc() above with
> hctx->queue->queue_lock.
> 
> > @@ -2362,17 +2365,15 @@ void blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async)
> >   	need_run = blk_mq_hw_queue_need_run(hctx);
> >   	if (!need_run) {
> > -		unsigned long flags;
> > -
> >   		/*
> > -		 * Synchronize with blk_mq_unquiesce_queue(), because we check
> > -		 * if hw queue is quiesced locklessly above, we need the use
> > -		 * ->queue_lock to make sure we see the up-to-date status to
> > -		 * not miss rerunning the hw queue.
> > +		 * Re-check the quiesce state after a read barrier. Pairs with
> > +		 * smp_mb__after_atomic() in blk_mq_quiesce_queue_nowait() and
> > +		 * blk_mq_unquiesce_queue() so we don't miss rerunning the hw
> > +		 * queue when a concurrent unquiesce has just dropped the
> > +		 * quiesce_depth to zero.
> >   		 */
> > -		spin_lock_irqsave(&hctx->queue->queue_lock, flags);
> > +		smp_rmb();
> >   		need_run = blk_mq_hw_queue_need_run(hctx);
> > -		spin_unlock_irqrestore(&hctx->queue->queue_lock, flags);
> 
> If the atomic_inc() in blk_mq_quiesce_queue_nowait() is protected by
> hctx->queue->queue_lock then the above code doesn't have to be modified.

But wouldn't the atomic_inc + barrier avoid the need to have the lock?
Isn't this a normal pattern? If the lock is kept, we could use
non-atomic ops here then. But this avoids having the lock.

> Thanks,
> 
> Bart.

Sebastian

^ permalink raw reply

* 回复: Re: [PATCH] block: bic maybe null pointer dereference
From: 晏龙龙 @ 2026-05-06  7:17 UTC (permalink / raw)
  To: yukuai, Jens Axboe; +Cc: linux-block, linux-kernel

[-- Attachment #1: Type: text/html, Size: 2892 bytes --]

^ permalink raw reply

* Re: [PATCH v6 1/1] block/blk-mq: use atomic_t for quiesce_depth to avoid lock contention on RT
From: Bart Van Assche @ 2026-05-06  7:14 UTC (permalink / raw)
  To: Ionut Nechita (Wind River), axboe, linux-block
  Cc: bigeasy, clrkwllms, rostedt, ming.lei, muchun.song, mkhalfella,
	chris.friesen, linux-kernel, linux-rt-devel, linux-rt-users,
	stable, ionut_n2001, sunlightlinux
In-Reply-To: <406f424c0a718bf492d40c206983e355e600945a.1778048987.git.ionut.nechita@windriver.com>

On 5/6/26 8:56 AM, Ionut Nechita (Wind River) wrote:
>   void blk_mq_quiesce_queue_nowait(struct request_queue *q)
>   {
> -	unsigned long flags;
> -
> -	spin_lock_irqsave(&q->queue_lock, flags);
> -	if (!q->quiesce_depth++)
> -		blk_queue_flag_set(QUEUE_FLAG_QUIESCED, q);
> -	spin_unlock_irqrestore(&q->queue_lock, flags);
> +	atomic_inc(&q->quiesce_depth);
> +	/*
> +	 * Pairs with smp_rmb() in blk_mq_run_hw_queue(): make the
> +	 * incremented quiesce_depth observable to readers re-checking
> +	 * the quiesce state, so they don't dispatch on a quiesced queue.
> +	 */
> +	smp_mb__after_atomic();
>   }

No, this is not sufficient to guarantee that blk_mq_run_hw_queue() sees
the latest value of q->quiesce_depth. If you want to achieve that I
think the only option is to protect the atomic_inc() above with
hctx->queue->queue_lock.

> @@ -2362,17 +2365,15 @@ void blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async)
>   
>   	need_run = blk_mq_hw_queue_need_run(hctx);
>   	if (!need_run) {
> -		unsigned long flags;
> -
>   		/*
> -		 * Synchronize with blk_mq_unquiesce_queue(), because we check
> -		 * if hw queue is quiesced locklessly above, we need the use
> -		 * ->queue_lock to make sure we see the up-to-date status to
> -		 * not miss rerunning the hw queue.
> +		 * Re-check the quiesce state after a read barrier. Pairs with
> +		 * smp_mb__after_atomic() in blk_mq_quiesce_queue_nowait() and
> +		 * blk_mq_unquiesce_queue() so we don't miss rerunning the hw
> +		 * queue when a concurrent unquiesce has just dropped the
> +		 * quiesce_depth to zero.
>   		 */
> -		spin_lock_irqsave(&hctx->queue->queue_lock, flags);
> +		smp_rmb();
>   		need_run = blk_mq_hw_queue_need_run(hctx);
> -		spin_unlock_irqrestore(&hctx->queue->queue_lock, flags);

If the atomic_inc() in blk_mq_quiesce_queue_nowait() is protected by
hctx->queue->queue_lock then the above code doesn't have to be modified.

Thanks,

Bart.

^ permalink raw reply

* Re: [PATCH] block: bic maybe null pointer dereference
From: Jens Axboe @ 2026-05-06  7:09 UTC (permalink / raw)
  To: yanlonglong, yukuai; +Cc: linux-block, linux-kernel
In-Reply-To: <20260506055655.32276-1-yanlonglong@kylinos.cn>

On 5/5/26 11:56 PM, yanlonglong wrote:
> Signed-off-by: yanlonglong <yanlonglong@kylinos.cn>

Your subject line is incomplete, and your commit message is even more
incomplete.

> diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
> index 141c602d5e85..27ef736085b1 100644
> --- a/block/bfq-iosched.c
> +++ b/block/bfq-iosched.c
> @@ -3035,9 +3035,6 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
>  static void bfq_bfqq_save_state(struct bfq_queue *bfqq)
>  {
>  	struct bfq_io_cq *bic = bfqq->bic;
> -	unsigned int a_idx = bfqq->actuator_idx;
> -	struct bfq_iocq_bfqq_data *bfqq_data = &bic->bfqq_data[a_idx];
> -
>  	/*
>  	 * If !bfqq->bic, the queue is already shared or its requests
>  	 * have already been redirected to a shared queue; both idle window
> @@ -3046,6 +3043,9 @@ static void bfq_bfqq_save_state(struct bfq_queue *bfqq)
>  	if (!bic)
>  		return;
>  
> +	unsigned int a_idx = bfqq->actuator_idx;
> +	struct bfq_iocq_bfqq_data *bfqq_data = &bic->bfqq_data[a_idx];
> +
>  	bfqq_data->saved_last_serv_time_ns = bfqq->last_serv_time_ns;
>  	bfqq_data->saved_inject_limit =	bfqq->inject_limit;
>  	bfqq_data->saved_decrease_time_jif = bfqq->decrease_time_jif;

Ehm no, variable declarations go at the top.

Please try again, correcting the title/subject and ACTUALLY write a
commit message. See:

Documentation/process/submitting-patches.rst

-- 
Jens Axboe

^ permalink raw reply

* [PATCH v6 0/1] block/blk-mq: use atomic_t for quiesce_depth to avoid lock contention on RT
From: Ionut Nechita (Wind River) @ 2026-05-06  6:56 UTC (permalink / raw)
  To: axboe, linux-block
  Cc: bigeasy, bvanassche, clrkwllms, rostedt, ming.lei, muchun.song,
	mkhalfella, chris.friesen, linux-kernel, linux-rt-devel,
	linux-rt-users, stable, ionut_n2001, sunlightlinux

Hi Jens,

This is v6 of the fix for the RT kernel performance regression caused by
commit 6bda857bcbb86 ("block: fix ordering between checking
QUEUE_FLAG_QUIESCED request adding").

Changes since v5 (Mar 3):
- Rewrote the memory-ordering comments per Bart Van Assche's review.
  The previous wording incorrectly described smp_mb__after_atomic() as
  ordering against "subsequent loads in blk_mq_run_hw_queue()". The
  comments now describe the actual reader/writer pairing: writer-side
  smp_mb__after_atomic() in blk_mq_quiesce_queue_nowait() and
  blk_mq_unquiesce_queue() pairs with reader-side smp_rmb() in
  blk_mq_run_hw_queue() so the re-check observes the latest
  quiesce_depth value.
- Rebased on top of linux-next (next-20260505).
- No functional / code-generation changes.

Changes since v4 (Feb 13):
- Rebased on top of linux-next (20260302)
- No code changes

Changes since v3 (Feb 11):
- Rebased on top of axboe/for-7.0/block
- Fixed Fixes tag commit hash to match upstream (6bda857bcbb86)
- Added Reviewed-by from Sebastian Andrzej Siewior
- No code changes

Changes since v2 (Feb 10):
- Replaced raw_spinlock_t quiesce_sync_lock with atomic_t for
  quiesce_depth, as suggested by Sebastian Andrzej Siewior
- Eliminated QUEUE_FLAG_QUIESCED entirely; blk_queue_quiesced() now
  checks atomic_read(&q->quiesce_depth) > 0
- Use atomic_dec_if_positive() in blk_mq_unquiesce_queue() to avoid
  race between WARN check and decrement
- Removed the unrelated blk_mq_run_hw_queues() async=true change
- Removed blk-mq-debugfs.c QUIESCED flag entry
- Uses smp_mb__after_atomic() / smp_rmb() for memory ordering instead
  of any spinlock in the hot path

Changes since v1 (RESEND, Jan 9):
- Rebased on top of axboe/for-7.0/block
- No code changes

The problem: on PREEMPT_RT kernels, the spinlock_t queue_lock added in
blk_mq_run_hw_queue() converts to a sleeping rt_mutex, causing all IRQ
threads (one per MSI-X vector) to serialize. On megaraid_sas with 128
MSI-X vectors and 120 hw queues, throughput drops from 640 MB/s to
153 MB/s.

The fix converts quiesce_depth to atomic_t, which serves as both the
depth tracker and the quiesce indicator (depth > 0 means quiesced).
This eliminates QUEUE_FLAG_QUIESCED and removes the need for any lock
in the hot path. Memory ordering is ensured by smp_mb__after_atomic()
on the writer side (after modifying quiesce_depth) paired with
smp_rmb() on the reader side (before re-checking quiesce state in
blk_mq_run_hw_queue()).

Link: https://lore.kernel.org/linux-block/20260303073744.20585-1-ionut.nechita@windriver.com/

Ionut Nechita (1):
  block/blk-mq: use atomic_t for quiesce_depth to avoid lock contention
    on RT

 block/blk-core.c       |  1 +
 block/blk-mq-debugfs.c |  1 -
 block/blk-mq.c         | 53 +++++++++++++++++++++---------------------
 include/linux/blkdev.h |  9 ++++---
 4 files changed, 34 insertions(+), 30 deletions(-)

--
2.54.0


^ permalink raw reply

* [PATCH v6 1/1] block/blk-mq: use atomic_t for quiesce_depth to avoid lock contention on RT
From: Ionut Nechita (Wind River) @ 2026-05-06  6:56 UTC (permalink / raw)
  To: axboe, linux-block
  Cc: bigeasy, bvanassche, clrkwllms, rostedt, ming.lei, muchun.song,
	mkhalfella, chris.friesen, linux-kernel, linux-rt-devel,
	linux-rt-users, stable, ionut_n2001, sunlightlinux
In-Reply-To: <cover.1778048987.git.ionut.nechita@windriver.com>

In RT kernel (PREEMPT_RT), commit 6bda857bcbb86 ("block: fix ordering
between checking QUEUE_FLAG_QUIESCED request adding") causes severe
performance regression on systems with multiple MSI-X interrupt
vectors.

The above change introduced spinlock_t queue_lock usage in
blk_mq_run_hw_queue() to synchronize QUEUE_FLAG_QUIESCED checks
with blk_mq_unquiesce_queue(). While this works correctly in
standard kernel, it causes catastrophic serialization in RT kernel
where spinlock_t converts to sleeping rt_mutex.

Problem in RT kernel:
- blk_mq_run_hw_queue() is called from IRQ thread context
- With multiple MSI-X vectors, all IRQ threads contend on
  the same queue_lock
- queue_lock becomes rt_mutex (sleeping) in RT kernel
- IRQ threads serialize and enter D-state waiting for lock
- Throughput drops from 640 MB/s to 153 MB/s

Solution:
Convert quiesce_depth to atomic_t and use it directly for quiesce
state checking, eliminating QUEUE_FLAG_QUIESCED entirely. This
removes the need for any locking in the hot path.

The atomic counter serves as both the depth tracker and the quiesce
indicator (depth > 0 means quiesced). This eliminates the race
window that existed between updating the depth and the flag.

Memory ordering is ensured by:
- smp_mb__after_atomic() after modifying quiesce_depth in
  blk_mq_quiesce_queue_nowait() and blk_mq_unquiesce_queue()
- smp_rmb() in blk_mq_run_hw_queue() before re-checking the
  quiesce state, paired with the writer-side barriers above

Performance impact:
- RT kernel: eliminates lock contention, restores full throughput
- Non-RT kernel: atomic ops are similar cost to the previous
  spinlock acquire/release, no regression expected

Test results on RT kernel:
Hardware: Broadcom/LSI MegaRAID 12GSAS/PCIe Secure SAS39xx
  (megaraid_sas driver, 128 MSI-X vectors, 120 hw queues)
- Before: 153 MB/s, IRQ threads in D-state
- After:  640 MB/s, no IRQ threads blocked

Suggested-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Fixes: 6bda857bcbb86 ("block: fix ordering between checking QUEUE_FLAG_QUIESCED request adding")
Cc: stable@vger.kernel.org
Signed-off-by: Ionut Nechita <ionut.nechita@windriver.com>
---
 block/blk-core.c       |  1 +
 block/blk-mq-debugfs.c |  1 -
 block/blk-mq.c         | 53 +++++++++++++++++++++---------------------
 include/linux/blkdev.h |  9 ++++---
 4 files changed, 34 insertions(+), 30 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index 17450058ea6d..1cafcca0975a 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -434,6 +434,7 @@ struct request_queue *blk_alloc_queue(struct queue_limits *lim, int node_id)
 	mutex_init(&q->limits_lock);
 	mutex_init(&q->rq_qos_mutex);
 	spin_lock_init(&q->queue_lock);
+	atomic_set(&q->quiesce_depth, 0);
 
 	init_waitqueue_head(&q->mq_freeze_wq);
 	mutex_init(&q->mq_freeze_lock);
diff --git a/block/blk-mq-debugfs.c b/block/blk-mq-debugfs.c
index 047ec887456b..1b0aec3036e6 100644
--- a/block/blk-mq-debugfs.c
+++ b/block/blk-mq-debugfs.c
@@ -89,7 +89,6 @@ static const char *const blk_queue_flag_name[] = {
 	QUEUE_FLAG_NAME(INIT_DONE),
 	QUEUE_FLAG_NAME(STATS),
 	QUEUE_FLAG_NAME(REGISTERED),
-	QUEUE_FLAG_NAME(QUIESCED),
 	QUEUE_FLAG_NAME(RQ_ALLOC_TIME),
 	QUEUE_FLAG_NAME(HCTX_ACTIVE),
 	QUEUE_FLAG_NAME(SQ_SCHED),
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 4c5c16cce4f8..c1281e4d4d83 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -260,12 +260,13 @@ EXPORT_SYMBOL_GPL(blk_mq_unfreeze_queue_non_owner);
  */
 void blk_mq_quiesce_queue_nowait(struct request_queue *q)
 {
-	unsigned long flags;
-
-	spin_lock_irqsave(&q->queue_lock, flags);
-	if (!q->quiesce_depth++)
-		blk_queue_flag_set(QUEUE_FLAG_QUIESCED, q);
-	spin_unlock_irqrestore(&q->queue_lock, flags);
+	atomic_inc(&q->quiesce_depth);
+	/*
+	 * Pairs with smp_rmb() in blk_mq_run_hw_queue(): make the
+	 * incremented quiesce_depth observable to readers re-checking
+	 * the quiesce state, so they don't dispatch on a quiesced queue.
+	 */
+	smp_mb__after_atomic();
 }
 EXPORT_SYMBOL_GPL(blk_mq_quiesce_queue_nowait);
 
@@ -314,21 +315,23 @@ EXPORT_SYMBOL_GPL(blk_mq_quiesce_queue);
  */
 void blk_mq_unquiesce_queue(struct request_queue *q)
 {
-	unsigned long flags;
-	bool run_queue = false;
+	int depth;
 
-	spin_lock_irqsave(&q->queue_lock, flags);
-	if (WARN_ON_ONCE(q->quiesce_depth <= 0)) {
-		;
-	} else if (!--q->quiesce_depth) {
-		blk_queue_flag_clear(QUEUE_FLAG_QUIESCED, q);
-		run_queue = true;
-	}
-	spin_unlock_irqrestore(&q->queue_lock, flags);
+	depth = atomic_dec_if_positive(&q->quiesce_depth);
+	if (WARN_ON_ONCE(depth < 0))
+		return;
 
-	/* dispatch requests which are inserted during quiescing */
-	if (run_queue)
+	if (depth == 0) {
+		/*
+		 * Pairs with smp_rmb() in blk_mq_run_hw_queue(): make the
+		 * decrement of quiesce_depth observable before we kick the
+		 * hw queues, so a concurrent blk_mq_run_hw_queue() that
+		 * re-checks the state sees the queue as no longer quiesced.
+		 */
+		smp_mb__after_atomic();
+		/* dispatch requests which are inserted during quiescing */
 		blk_mq_run_hw_queues(q, true);
+	}
 }
 EXPORT_SYMBOL_GPL(blk_mq_unquiesce_queue);
 
@@ -2362,17 +2365,15 @@ void blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async)
 
 	need_run = blk_mq_hw_queue_need_run(hctx);
 	if (!need_run) {
-		unsigned long flags;
-
 		/*
-		 * Synchronize with blk_mq_unquiesce_queue(), because we check
-		 * if hw queue is quiesced locklessly above, we need the use
-		 * ->queue_lock to make sure we see the up-to-date status to
-		 * not miss rerunning the hw queue.
+		 * Re-check the quiesce state after a read barrier. Pairs with
+		 * smp_mb__after_atomic() in blk_mq_quiesce_queue_nowait() and
+		 * blk_mq_unquiesce_queue() so we don't miss rerunning the hw
+		 * queue when a concurrent unquiesce has just dropped the
+		 * quiesce_depth to zero.
 		 */
-		spin_lock_irqsave(&hctx->queue->queue_lock, flags);
+		smp_rmb();
 		need_run = blk_mq_hw_queue_need_run(hctx);
-		spin_unlock_irqrestore(&hctx->queue->queue_lock, flags);
 
 		if (!need_run)
 			return;
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 890128cdea1c..5d582c70fb8a 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -521,7 +521,8 @@ struct request_queue {
 
 	spinlock_t		queue_lock;
 
-	int			quiesce_depth;
+	/* Atomic quiesce depth - also serves as quiesced indicator (depth > 0) */
+	atomic_t		quiesce_depth;
 
 	struct gendisk		*disk;
 
@@ -666,7 +667,6 @@ enum {
 	QUEUE_FLAG_INIT_DONE,		/* queue is initialized */
 	QUEUE_FLAG_STATS,		/* track IO start and completion times */
 	QUEUE_FLAG_REGISTERED,		/* queue has been registered to a disk */
-	QUEUE_FLAG_QUIESCED,		/* queue has been quiesced */
 	QUEUE_FLAG_RQ_ALLOC_TIME,	/* record rq->alloc_time_ns */
 	QUEUE_FLAG_HCTX_ACTIVE,		/* at least one blk-mq hctx is active */
 	QUEUE_FLAG_SQ_SCHED,		/* single queue style io dispatch */
@@ -704,7 +704,10 @@ void blk_queue_flag_clear(unsigned int flag, struct request_queue *q);
 #define blk_noretry_request(rq) \
 	((rq)->cmd_flags & (REQ_FAILFAST_DEV|REQ_FAILFAST_TRANSPORT| \
 			     REQ_FAILFAST_DRIVER))
-#define blk_queue_quiesced(q)	test_bit(QUEUE_FLAG_QUIESCED, &(q)->queue_flags)
+static inline bool blk_queue_quiesced(struct request_queue *q)
+{
+	return atomic_read(&q->quiesce_depth) > 0;
+}
 #define blk_queue_pm_only(q)	atomic_read(&(q)->pm_only)
 #define blk_queue_registered(q)	test_bit(QUEUE_FLAG_REGISTERED, &(q)->queue_flags)
 #define blk_queue_sq_sched(q)	test_bit(QUEUE_FLAG_SQ_SCHED, &(q)->queue_flags)
-- 
2.54.0


^ permalink raw reply related

* Re: [PATCH] dept: update documentation function names to match implementation
From: Byungchul Park @ 2026-05-06  6:27 UTC (permalink / raw)
  To: Yunseong Kim
  Cc: bagasdotme, 2407018371, Dai.Ngo, Liam.Howlett, a.hindborg,
	ada.coupriediaz, adilger.kernel, akpm, alex.gaynor,
	alexander.shishkin, aliceryhl, amir73il, andi.shyti, andrii, anna,
	arnd, ast, baolin.wang, bigeasy, bjorn3_gh, boqun.feng, bp,
	brauner, broonie, bsegall, catalin.marinas, chenhuacai,
	chris.p.wilson, christian.koenig, chuck.lever, cl, clrkwllms,
	corbet, da.gomez, dakr, damien.lemoal, dan.j.williams,
	daniel.vetter, dave.hansen, david, dennis, dietmar.eggemann,
	djwong, dri-devel, duyuyang, dwmw, francesco, frederic, gary,
	geert+renesas, geert, gregkh, guoweikang.kernel, gustavo,
	gwan-gyeong.mun, hamohammed.sa, hannes, harry.yoo, hch,
	her0gyugyu, hpa, jack, jglisse, jiangshanlai, jlayton,
	joel.granados, joel, joelagnelf, johannes.berg, josef, josh,
	jpoimboe, juri.lelli, kees, kernel-team, kernel_team,
	kevin.brodsky, kristina.martsenko, lillian, linaro-mm-sig, link,
	linux-arch, linux-arm-kernel, linux-block, linux-doc, linux-ext4,
	linux-fsdevel, linux-i2c, linux-ide, linux-kernel, linux-media,
	linux-mm, linux-modules, linux-nfs, linux-rt-devel, linux,
	longman, lorenzo.stoakes, lossin, luto, mark.rutland, masahiroy,
	mathieu.desnoyers, matthew.brost, max.byungchul.park, mcgrof,
	melissa.srw, mgorman, mhocko, miguel.ojeda.sandonis, minchan,
	mingo, mjguzik, neeraj.upadhyay, neil, neilb, netdev, ngupta,
	ojeda, okorniev, oleg, paulmck, penberg, peterz, petr.pavlu,
	qiang.zhang, rcu, richard.weiyang, rientjes, rodrigosiqueiramelo,
	rostedt, rppt, rust-for-linux, samitolvanen, sashal, shakeel.butt,
	sj, sumit.semwal, surenb, tglx, thomas.weissschuh, tim.c.chen, tj,
	tmgross, tom, torvalds, trondmy, tytso, urezki, usamaarif642,
	vbabka, vdavydov.dev, vincent.guittot, vschneid, wangfushuai,
	wangkefeng.wang, will, willy, wsa+renesas, x86, yeoreum.yun, ysk,
	yunseong.kim, yuzhao, ziy
In-Reply-To: <20260428162614.786365-2-yunseong.kim@est.tech>

On Tue, Apr 28, 2026 at 06:26:15PM +0200, Yunseong Kim wrote:
> Synchronize function names in the documentation with the actual
> implementation to fix naming inconsistencies.

Good catch!  Thanks Yunseong.  I will apply it on the top.

	Byungchul

> Signed-off-by: Yunseong Kim <yunseong.kim@est.tech>
> ---
>  Documentation/dev-tools/dept.rst     | 2 +-
>  Documentation/dev-tools/dept_api.rst | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/dev-tools/dept.rst b/Documentation/dev-tools/dept.rst
> index 333166464543..31b2fe629fab 100644
> --- a/Documentation/dev-tools/dept.rst
> +++ b/Documentation/dev-tools/dept.rst
> @@ -97,7 +97,7 @@ No.  What about the following?
> 
>                            mutex_lock A
>     mutex_lock A <- DEADLOCK
> -                          wait_for_complete B <- DEADLOCK
> +                          wait_for_completion B <- DEADLOCK
>     complete B
>                            mutex_unlock A
>     mutex_unlock A
> diff --git a/Documentation/dev-tools/dept_api.rst b/Documentation/dev-tools/dept_api.rst
> index 409116a62849..74e7b1424ad5 100644
> --- a/Documentation/dev-tools/dept_api.rst
> +++ b/Documentation/dev-tools/dept_api.rst
> @@ -113,7 +113,7 @@ Do not use these APIs directly.  The raw APIs of dept are:
>     dept_stage_wait(map, key, ip, wait_func, time);
>     dept_request_event_wait_commit();
>     dept_clean_stage();
> -   dept_stage_event(task, ip);
> +   dept_ttwu_stage_wait(task, ip);
>     dept_ecxt_enter(map, evt_flags, ip, ecxt_func, evt_func, sub_local);
>     dept_ecxt_holding(map, evt_flags);
>     dept_request_event(map, ext_wgen);
> --
> 2.53.0

^ permalink raw reply

* Re: [PATCH v2 3/3] mmc: sdhci-esdhc-imx: consolidate imx25/35 data and add Kingston CID
From: Adrian Hunter @ 2026-05-06  6:04 UTC (permalink / raw)
  To: Adrián García Casado, Ulf Hansson, Andreas Hindborg,
	Jens Axboe, Miri Korenblit
  Cc: Miguel Ojeda, Haibo Chen, Frank Li, Sascha Hauer, Boqun Feng,
	linux-mmc, imx, linux-arm-kernel, linux-block, rust-for-linux,
	linux-wireless, linux-kernel, Adrián García Casado
In-Reply-To: <20260315172746.270734-4-adriangarciacasado42@gmail.com>

On 15/03/2026 19:26, Adrián García Casado wrote:
> Consolidate esdhc_imx25 and esdhc_imx35 soc data into a single shared
> struct since they share the same flags. This reduces redundancy. Also
> add the CID_MANFID_KINGSTON definition to quirks.h for centralized
> management.
> 
> Signed-off-by: Adrián García Casado <adriangarciacicuelo@gmail.com>

scripts/checkpatch.pl warning:

WARNING: From:/Signed-off-by: email address mismatch: 'From: "Adrián García Casado" <adriangarciacasado42@gmail.com>' != 'Signed-off-by: Adrián García Casado <adriangarciacicuelo@gmail.com>'

> ---
>  drivers/mmc/core/quirks.h          |  4 ++++
>  drivers/mmc/host/sdhci-esdhc-imx.c | 12 ++++--------
>  2 files changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h
> index c417ed34c..d736bb4be 100644
> --- a/drivers/mmc/core/quirks.h
> +++ b/drivers/mmc/core/quirks.h
> @@ -15,6 +15,10 @@
>  
>  #include "card.h"
>  
> +#ifndef CID_MANFID_KINGSTON
> +#define CID_MANFID_KINGSTON	0x70
> +#endif

CID_MANFID_KINGSTON is already defined in "card.h"
so the change is not needed.

> +
>  static const struct mmc_fixup __maybe_unused mmc_sd_fixups[] = {
>  	/*
>  	 * Kingston Canvas Go! Plus microSD cards never finish SD cache flush.
> diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
> index a7a5df673..9cfa26722 100644
> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> @@ -256,11 +256,7 @@ struct esdhc_soc_data {
>  	u32 quirks;
>  };
>  
> -static const struct esdhc_soc_data esdhc_imx25_data = {
> -	.flags = ESDHC_FLAG_ERR004536,
> -};
> -
> -static const struct esdhc_soc_data esdhc_imx35_data = {
> +static const struct esdhc_soc_data esdhc_imx25_35_data = {
>  	.flags = ESDHC_FLAG_ERR004536,
>  };
>  
> @@ -391,8 +387,8 @@ struct pltfm_imx_data {
>  };
>  
>  static const struct of_device_id imx_esdhc_dt_ids[] = {
> -	{ .compatible = "fsl,imx25-esdhc", .data = &esdhc_imx25_data, },
> -	{ .compatible = "fsl,imx35-esdhc", .data = &esdhc_imx35_data, },
> +	{ .compatible = "fsl,imx25-esdhc", .data = &esdhc_imx25_35_data, },
> +	{ .compatible = "fsl,imx35-esdhc", .data = &esdhc_imx25_35_data, },
>  	{ .compatible = "fsl,imx51-esdhc", .data = &esdhc_imx51_data, },
>  	{ .compatible = "fsl,imx53-esdhc", .data = &esdhc_imx53_data, },
>  	{ .compatible = "fsl,imx6sx-usdhc", .data = &usdhc_imx6sx_data, },
> @@ -414,7 +410,7 @@ MODULE_DEVICE_TABLE(of, imx_esdhc_dt_ids);
>  
>  static inline int is_imx25_esdhc(struct pltfm_imx_data *data)
>  {
> -	return data->socdata == &esdhc_imx25_data;
> +	return data->socdata == &esdhc_imx25_35_data;
>  }

Doesn't look right.
Previously this matched only "fsl,imx25-esdhc".
Now it also matches "fsl,imx35-esdhc".  So this change
has unintended consequences.

>  
>  static inline int is_imx53_esdhc(struct pltfm_imx_data *data)


^ permalink raw reply

* [PATCH] block: bic maybe null pointer dereference
From: yanlonglong @ 2026-05-06  5:56 UTC (permalink / raw)
  To: yukuai, axboe; +Cc: linux-block, linux-kernel, yanlonglong

Signed-off-by: yanlonglong <yanlonglong@kylinos.cn>
---
 block/bfq-iosched.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
index 141c602d5e85..27ef736085b1 100644
--- a/block/bfq-iosched.c
+++ b/block/bfq-iosched.c
@@ -3035,9 +3035,6 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
 static void bfq_bfqq_save_state(struct bfq_queue *bfqq)
 {
 	struct bfq_io_cq *bic = bfqq->bic;
-	unsigned int a_idx = bfqq->actuator_idx;
-	struct bfq_iocq_bfqq_data *bfqq_data = &bic->bfqq_data[a_idx];
-
 	/*
 	 * If !bfqq->bic, the queue is already shared or its requests
 	 * have already been redirected to a shared queue; both idle window
@@ -3046,6 +3043,9 @@ static void bfq_bfqq_save_state(struct bfq_queue *bfqq)
 	if (!bic)
 		return;
 
+	unsigned int a_idx = bfqq->actuator_idx;
+	struct bfq_iocq_bfqq_data *bfqq_data = &bic->bfqq_data[a_idx];
+
 	bfqq_data->saved_last_serv_time_ns = bfqq->last_serv_time_ns;
 	bfqq_data->saved_inject_limit =	bfqq->inject_limit;
 	bfqq_data->saved_decrease_time_jif = bfqq->decrease_time_jif;
-- 
2.43.0


^ permalink raw reply related

* [PATCH v2] block/blk-iolatency: Add the processing flow of the chained bio in the QoS and define the related types to solve the problem of incorrect inflight processing in the QoS. The usage of the done_split_bio abstract function in the blk-iolatency project.
From: Li kunyu @ 2026-05-06  2:42 UTC (permalink / raw)
  To: axboe, tj, josef; +Cc: linux-block, linux-kernel, Li kunyu

Signed-off-by: Li kunyu <likunyu10@163.com>
---
v2: Fix the use of 'split' in the 'bio_set_flag' function to 'bio'

 block/bio.c               |  2 ++
 block/blk-iolatency.c     | 34 ++++++++++++++++++++++++++++++++++
 block/blk-merge.c         |  7 ++++++-
 block/blk-rq-qos.h        | 11 +++++++++++
 include/linux/blk_types.h |  2 ++
 5 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/block/bio.c b/block/bio.c
index b8972dba68a0..7740701afc7f 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1733,6 +1733,8 @@ static inline bool bio_remaining_done(struct bio *bio)
 		return true;
 	}
 
+	rq_qos_done_split_bio(bio);
+
 	return false;
 }
 
diff --git a/block/blk-iolatency.c b/block/blk-iolatency.c
index 53e8dd2dfa8a..ba5870bf14c5 100644
--- a/block/blk-iolatency.c
+++ b/block/blk-iolatency.c
@@ -632,6 +632,39 @@ static void blkcg_iolatency_done_bio(struct rq_qos *rqos, struct bio *bio)
 	}
 }
 
+static void blkcg_iolatency_done_split_bio(struct rq_qos *rqos, struct bio *bio)
+{
+	struct blkcg_gq *blkg;
+	struct rq_wait *rqw;
+	struct iolatency_grp *iolat;
+	int inflight = 0;
+
+	blkg = bio->bi_blkg;
+	if (!blkg || !bio_flagged(bio, BIO_QOS_CHAIN_CHILD))
+		return;
+
+	iolat = blkg_to_lat(bio->bi_blkg);
+	if (!iolat)
+		return;
+
+	if (!iolat->blkiolat->enabled)
+		return;
+
+	while (blkg && blkg->parent) {
+		iolat = blkg_to_lat(blkg);
+		if (!iolat) {
+			blkg = blkg->parent;
+			continue;
+		}
+		rqw = &iolat->rq_wait;
+
+		inflight = atomic_dec_return(&rqw->inflight);
+		WARN_ON_ONCE(inflight < 0);
+
+		blkg = blkg->parent;
+	}
+}
+
 static void blkcg_iolatency_exit(struct rq_qos *rqos)
 {
 	struct blk_iolatency *blkiolat = BLKIOLATENCY(rqos);
@@ -645,6 +678,7 @@ static void blkcg_iolatency_exit(struct rq_qos *rqos)
 static const struct rq_qos_ops blkcg_iolatency_ops = {
 	.throttle = blkcg_iolatency_throttle,
 	.done_bio = blkcg_iolatency_done_bio,
+	.done_split_bio = blkcg_iolatency_done_split_bio,
 	.exit = blkcg_iolatency_exit,
 };
 
diff --git a/block/blk-merge.c b/block/blk-merge.c
index fcf09325b22e..84373e3e1bbe 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -151,8 +151,13 @@ static struct bio *bio_submit_split(struct bio *bio, int split_sectors)
 	if (split_sectors) {
 		bio = bio_submit_split_bioset(bio, split_sectors,
 				&bio->bi_bdev->bd_disk->bio_split);
-		if (bio)
+		if (bio) {
 			bio->bi_opf |= REQ_NOMERGE;
+			/* Fix the issue where the inflight statistics
+			 * of the chained bio in the QoS are incorrect.
+			 */
+			bio_set_flag(bio, BIO_QOS_CHAIN_CHILD);
+		}
 	}
 
 	return bio;
diff --git a/block/blk-rq-qos.h b/block/blk-rq-qos.h
index a747a504fe42..496a27b9d412 100644
--- a/block/blk-rq-qos.h
+++ b/block/blk-rq-qos.h
@@ -45,6 +45,7 @@ struct rq_qos_ops {
 	void (*cleanup)(struct rq_qos *, struct bio *);
 	void (*queue_depth_changed)(struct rq_qos *);
 	void (*exit)(struct rq_qos *);
+	void (*done_split_bio)(struct rq_qos *, struct bio *);
 	const struct blk_mq_debugfs_attr *debugfs_attrs;
 };
 
@@ -108,6 +109,7 @@ void __rq_qos_throttle(struct rq_qos *rqos, struct bio *bio);
 void __rq_qos_track(struct rq_qos *rqos, struct request *rq, struct bio *bio);
 void __rq_qos_merge(struct rq_qos *rqos, struct request *rq, struct bio *bio);
 void __rq_qos_done_bio(struct rq_qos *rqos, struct bio *bio);
+void __rq_qos_done_split_bio(struct rq_qos *rqos, struct bio *bio);
 void __rq_qos_queue_depth_changed(struct rq_qos *rqos);
 
 static inline void rq_qos_cleanup(struct request_queue *q, struct bio *bio)
@@ -157,6 +159,15 @@ static inline void rq_qos_done_bio(struct bio *bio)
 		__rq_qos_done_bio(q->rq_qos, bio);
 }
 
+static inline void rq_qos_done_split_bio(struct bio *bio)
+{
+	if (bio->bi_bdev && bio_flagged(bio, BIO_QOS_CHAIN_CHILD)) {
+		struct request_queue *q = bdev_get_queue(bio->bi_bdev);
+		if (q->rq_qos)
+			__rq_qos_done_split_bio(q->rq_qos, bio);
+	}
+}
+
 static inline void rq_qos_throttle(struct request_queue *q, struct bio *bio)
 {
 	if (test_bit(QUEUE_FLAG_QOS_ENABLED, &q->queue_flags) && q->rq_qos) {
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 8808ee76e73c..63fee89ecc14 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -322,6 +322,8 @@ enum {
 	BIO_REMAPPED,
 	BIO_ZONE_WRITE_PLUGGING, /* bio handled through zone write plugging */
 	BIO_EMULATES_ZONE_APPEND, /* bio emulates a zone append operation */
+	BIO_QOS_CHAIN_CHILD,    /* chained bio child, used for segmenting out
+				* the bio */
 	BIO_FLAG_LAST
 };
 
-- 
2.47.3


^ permalink raw reply related

* Re: [PATCH 6/9] dt-bindings: bluetooth: qcom: Add NVMEM BD address cell
From: Rob Herring (Arm) @ 2026-05-06  1:33 UTC (permalink / raw)
  To: Loic Poulain
  Cc: Bjorn Andersson, devicetree, Krzysztof Kozlowski, linux-arm-msm,
	Marcel Holtmann, Konrad Dybcio, David S. Miller, linux-mmc,
	Jens Axboe, netdev, Simon Horman, Rocky Liao, daniel,
	linux-wireless, Ulf Hansson, Eric Dumazet, Balakrishna Godavarthi,
	linux-kernel, Bartosz Golaszewski, Jakub Kicinski, Paolo Abeni,
	linux-bluetooth, Conor Dooley, Luiz Augusto von Dentz,
	Jeff Johnson, ath10k, linux-block, Johannes Berg
In-Reply-To: <20260428-block-as-nvmem-v1-6-6ad23e75190a@oss.qualcomm.com>


On Tue, 28 Apr 2026 16:23:11 +0200, Loic Poulain wrote:
> Add support for an NVMEM cell provider for "local-bd-address",
> allowing the Bluetooth stack to retrieve controller's BD address
> from non-volatile storage such as an EEPROM or an eMMC partition.
> 
> Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
> ---
>  .../bindings/net/bluetooth/qcom,bluetooth-common.yaml          | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 

Reviewed-by: Rob Herring (Arm) <robh@kernel.org>


^ permalink raw reply

* [PATCH] floppy: force media-change checks when clearing events
From: Cen Zhang @ 2026-05-06  1:02 UTC (permalink / raw)
  To: efremov, axboe; +Cc: linux-block, linux-kernel, baijiaju1990, Cen Zhang

floppy_open() tries to make blocking read/write opens perform a fresh
media-change check by clearing drive_state[drive].last_checked before
calling disk_check_media_change().  That timestamp is also updated by
disk_change() when another FDC operation observes that the disk-change
line is clear.

The worker path that calls disk_change() is not serialized by the
floppy_mutex/open_lock pair held by floppy_open().  A worker can therefore
store a recent jiffies value after floppy_open() stores zero and before the
synchronous disk_check_media_change() call reaches floppy_check_events().
The checkfreq throttle can then treat the media-change state as fresh and
skip the hardware poll that the open path explicitly tried to force.

Use the block layer's clearing mask instead of a racy timestamp sentinel.
When DISK_EVENT_MEDIA_CHANGE is being synchronously cleared, bypass the
checkfreq throttle and poll the drive.  Periodic event checks still use
last_checked to avoid unnecessary polling, and floppy_open() no longer
needs to write last_checked itself.

Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
---
 drivers/block/floppy.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 92e446a643712..7217db0b907b3 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -4051,7 +4051,6 @@ static int floppy_open(struct gendisk *disk, blk_mode_t mode)
 		fdc_state[FDC(drive)].rawcmd = 2;
 	if (!(mode & BLK_OPEN_NDELAY)) {
 		if (mode & (BLK_OPEN_READ | BLK_OPEN_WRITE)) {
-			drive_state[drive].last_checked = 0;
 			clear_bit(FD_OPEN_SHOULD_FAIL_BIT,
 				  &drive_state[drive].flags);
 			if (disk_check_media_change(disk))
@@ -4092,7 +4091,9 @@ static unsigned int floppy_check_events(struct gendisk *disk,
 	    test_bit(FD_VERIFY_BIT, &drive_state[drive].flags))
 		return DISK_EVENT_MEDIA_CHANGE;
 
-	if (time_after(jiffies, drive_state[drive].last_checked + drive_params[drive].checkfreq)) {
+	if ((clearing & DISK_EVENT_MEDIA_CHANGE) ||
+	    time_after(jiffies, drive_state[drive].last_checked +
+			       drive_params[drive].checkfreq)) {
 		if (lock_fdc(drive))
 			return 0;
 		poll_drive(false, 0);
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH v12 05/13] blk-mq: add blk_mq_{online|possible}_queue_affinity
From: Aaron Tomlin @ 2026-05-05 20:55 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: axboe, kbusch, hch, sagi, mst, aacraid, James.Bottomley,
	martin.petersen, liyihang9, kashyap.desai, sumit.saxena,
	shivasharan.srikanteshwara, chandrakanth.patil, sathya.prakash,
	sreekanth.reddy, suganath-prabu.subramani, ranjan.kumar,
	jinpu.wang, tglx, mingo, peterz, juri.lelli, vincent.guittot,
	akpm, maz, ruanjinjie, yphbchou0911, wagi, frederic, longman,
	chenridong, hare, kch, ming.lei, tom.leiming, steve, sean,
	chjohnst, neelx, mproche, nick.lange, marco.crivellari,
	linux-block, linux-kernel, virtualization, linux-nvme, linux-scsi,
	megaraidlinux.pdl, mpi3mr-linuxdrv.pdl, MPT-FusionLinux.pdl
In-Reply-To: <20260427153416.MeVS8yxF@linutronix.de>

[-- Attachment #1: Type: text/plain, Size: 1935 bytes --]

On Mon, Apr 27, 2026 at 05:34:16PM +0200, Sebastian Andrzej Siewior wrote:
> On 2026-04-22 14:52:07 [-0400], Aaron Tomlin wrote:
> > From: Daniel Wagner <wagi@kernel.org>
> > 
> > Introduce blk_mq_{online|possible}_queue_affinity, which returns the
> > queue-to-CPU mapping constraints defined by the block layer. This allows
> > other subsystems (e.g., IRQ affinity setup) to respect block layer
> > requirements.
> > 
> > It is necessary to provide versions for both the online and possible CPU
> > masks because some drivers want to spread their I/O queues only across
> > online CPUs, while others prefer to use all possible CPUs. And the mask
> > used needs to match with the number of queues requested
> > (see blk_num_{online|possible}_queues).
> 
> Which driver uses cpu_possible_mask? This mask is assigned at boot time
> once the kernel figured how many CPUs are possible based on ACPI or
> whatever the system uses. This mask does not change.
> 
> I only see drivers/scsi/lpfc/lpfc_init.c using it. Looking at
> cpu_possible_mask might not be the right thing. It is usually the same
> thing as "online" except on system where ACPI thinks that something
> could be added via hotplug _or_ if the admin shuts down a CPU via
> cpuhotplug _or_ boots with less (there a command line option for that). 
> 
> In case cpu_possible_mask != cpu_online_mask the intention is to
> allocate memory and setup irqs for the offline CPUs?
> 
> > Signed-off-by: Daniel Wagner <wagi@kernel.org>
> > Reviewed-by: Hannes Reinecke <hare@suse.de>
> > Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
> 
Hi Sebastian,

In the next iteration, this patch will be dropped. Moving forward, there
will be no more consumers of blk_mq_[online|possible]_queue_affinity().

Please see here [1]. 

[1]: https://lore.kernel.org/lkml/bnklzljfve53m33xdxv4mlu75kqrkpc3xooxgd3pnbvwjst5hr@btomkooj4crh/

-- 
Aaron Tomlin

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH v12 04/13] genirq/affinity: Add cpumask to struct irq_affinity
From: Aaron Tomlin @ 2026-05-05 20:40 UTC (permalink / raw)
  To: axboe, kbusch, hch, sagi, mst
  Cc: aacraid, James.Bottomley, martin.petersen, liyihang9,
	kashyap.desai, sumit.saxena, shivasharan.srikanteshwara,
	chandrakanth.patil, sathya.prakash, sreekanth.reddy,
	suganath-prabu.subramani, ranjan.kumar, jinpu.wang, tglx, mingo,
	peterz, juri.lelli, vincent.guittot, akpm, maz, ruanjinjie,
	bigeasy, yphbchou0911, wagi, frederic, longman, chenridong, hare,
	kch, ming.lei, tom.leiming, steve, sean, chjohnst, neelx, mproche,
	nick.lange, marco.crivellari, linux-block, linux-kernel,
	virtualization, linux-nvme, linux-scsi, megaraidlinux.pdl,
	mpi3mr-linuxdrv.pdl, MPT-FusionLinux.pdl
In-Reply-To: <20260422185215.100929-5-atomlin@atomlin.com>

[-- Attachment #1: Type: text/plain, Size: 967 bytes --]

On Wed, Apr 22, 2026 at 02:52:06PM -0400, Aaron Tomlin wrote:
> From: Daniel Wagner <wagi@kernel.org>
> 
> Pass a cpumask to irq_create_affinity_masks as an additional constraint
> to consider when creating the affinity masks. This allows the caller to
> exclude specific CPUs, e.g., isolated CPUs (see the 'isolcpus' kernel
> command-line parameter).
> 
> Signed-off-by: Daniel Wagner <wagi@kernel.org>
> Reviewed-by: Hannes Reinecke <hare@suse.de>
> Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
> ---
>  include/linux/interrupt.h | 16 ++++++++++------
>  kernel/irq/affinity.c     | 12 ++++++++++--
>  2 files changed, 20 insertions(+), 8 deletions(-)

Hi Daniel, Hannes,

Following on from here [1], this patch will be dropped too in the next
iteration. Moving forward, drivers no longer need to pass a custom mask.

[1]: https://lore.kernel.org/lkml/bnklzljfve53m33xdxv4mlu75kqrkpc3xooxgd3pnbvwjst5hr@btomkooj4crh/

-- 
Aaron Tomlin

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH v12 06/13] nvme-pci: use block layer helpers to constrain queue affinity
From: Aaron Tomlin @ 2026-05-05 19:47 UTC (permalink / raw)
  To: axboe, kbusch, hch, sagi, mst
  Cc: aacraid, James.Bottomley, martin.petersen, liyihang9,
	kashyap.desai, sumit.saxena, shivasharan.srikanteshwara,
	chandrakanth.patil, sathya.prakash, sreekanth.reddy,
	suganath-prabu.subramani, ranjan.kumar, jinpu.wang, tglx, mingo,
	peterz, juri.lelli, vincent.guittot, akpm, maz, ruanjinjie,
	bigeasy, yphbchou0911, wagi, frederic, longman, chenridong, hare,
	kch, ming.lei, tom.leiming, steve, sean, chjohnst, neelx, mproche,
	nick.lange, marco.crivellari, linux-block, linux-kernel,
	virtualization, linux-nvme, linux-scsi, megaraidlinux.pdl,
	mpi3mr-linuxdrv.pdl, MPT-FusionLinux.pdl
In-Reply-To: <20260422185215.100929-7-atomlin@atomlin.com>

[-- Attachment #1: Type: text/plain, Size: 1894 bytes --]

On Wed, Apr 22, 2026 at 02:52:08PM -0400, Aaron Tomlin wrote:
> From: Daniel Wagner <wagi@kernel.org>
> 
> Ensure that IRQ affinity setup also respects the queue-to-CPU mapping
> constraints provided by the block layer. This allows the NVMe driver
> to avoid assigning interrupts to CPUs that the block layer has excluded
> (e.g., isolated CPUs).
> 
> Signed-off-by: Daniel Wagner <wagi@kernel.org>
> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
> Reviewed-by: Hannes Reinecke <hare@suse.de>
> Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
> ---
>  drivers/nvme/host/pci.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
> index db5fc9bf6627..daa041d15d3c 100644
> --- a/drivers/nvme/host/pci.c
> +++ b/drivers/nvme/host/pci.c
> @@ -2862,6 +2862,7 @@ static int nvme_setup_irqs(struct nvme_dev *dev, unsigned int nr_io_queues)
>  		.pre_vectors	= 1,
>  		.calc_sets	= nvme_calc_irq_sets,
>  		.priv		= dev,
> +		.mask		= blk_mq_possible_queue_affinity(),
>  	};
>  	unsigned int irq_queues, poll_queues;
>  	unsigned int flags = PCI_IRQ_ALL_TYPES | PCI_IRQ_AFFINITY;
> -- 
> 2.51.0

Hi Daniel, Martin, Hannes,

I think we can drop this patch, including other similar changes [1][2].

The next iteration of patch 12 [3] in my queue, irq_create_affinity_masks()
has been modified to respect the housekeeping CPU mask. By intersecting the
base affinity mask with the HK_TYPE_IO_QUEUE mask prior to topological
distribution (group_mask_cpus_evenly()), we ensure that managed interrupts
are kept off isolated CPUs.

[1]: https://lore.kernel.org/lkml/20260422185215.100929-8-atomlin@atomlin.com/
[2]: https://lore.kernel.org/lkml/20260422185215.100929-9-atomlin@atomlin.com/
[3]: https://lore.kernel.org/lkml/20260422185215.100929-13-atomlin@atomlin.com/

-- 
Aaron Tomlin

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH v12 01/13] scsi: aacraid: use block layer helpers to calculate num of queues
From: Aaron Tomlin @ 2026-05-05 18:42 UTC (permalink / raw)
  To: axboe, kbusch, hch, sagi, mst
  Cc: aacraid, James.Bottomley, martin.petersen, liyihang9,
	kashyap.desai, sumit.saxena, shivasharan.srikanteshwara,
	chandrakanth.patil, sathya.prakash, sreekanth.reddy,
	suganath-prabu.subramani, ranjan.kumar, jinpu.wang, tglx, mingo,
	peterz, juri.lelli, vincent.guittot, akpm, maz, ruanjinjie,
	bigeasy, yphbchou0911, wagi, frederic, longman, chenridong, hare,
	kch, ming.lei, tom.leiming, steve, sean, chjohnst, neelx, mproche,
	nick.lange, marco.crivellari, linux-block, linux-kernel,
	virtualization, linux-nvme, linux-scsi, megaraidlinux.pdl,
	mpi3mr-linuxdrv.pdl, MPT-FusionLinux.pdl
In-Reply-To: <20260422185215.100929-2-atomlin@atomlin.com>

[-- Attachment #1: Type: text/plain, Size: 915 bytes --]

On Wed, Apr 22, 2026 at 02:52:03PM -0400, Aaron Tomlin wrote:
> From: Daniel Wagner <wagi@kernel.org>
> 
> The calculation of the upper limit for queues does not depend solely on
> the number of online CPUs; for example, the isolcpus kernel
> command-line option must also be considered.
> 
> To account for this, the block layer provides a helper function to
> retrieve the maximum number of queues. Use it to set an appropriate
> upper queue number limit.
> 
> Fixes: 94970cfb5f10 ("scsi: use block layer helpers to calculate num of queues")

Commit 94970cfb5f10 was a refactoring patch but it did not modify or break
aacraid. I believe we should drop the "Fixes:" tag and use the following:

    This brings aacraid in line with the API migration initiated for other
    SCSI drivers in commit 94970cfb5f10 ("scsi: use block layer helpers to
    calculate num of queues")

-- 
Aaron Tomlin

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH] zram: fix use-after-free in zram_writeback_endio
From: Minchan Kim @ 2026-05-05 16:37 UTC (permalink / raw)
  To: Richard Chang
  Cc: Sergey Senozhatsky, Jens Axboe, Andrew Morton, bgeffon, liumartin,
	linux-kernel, linux-block, linux-mm
In-Reply-To: <20260504123230.3833765-1-richardycc@google.com>

On Mon, May 04, 2026 at 12:32:30PM +0000, Richard Chang wrote:
> A crash was observed in zram_writeback_endio due to a NULL pointer
> dereference in wake_up. The root cause is a race condition between the
> bio completion handler (zram_writeback_endio) and the writeback task.
> 
> In zram_writeback_endio, wake_up() is called on &wb_ctl->done_wait after
> releasing wb_ctl->done_lock. This creates a race window where the
> writeback task can see num_inflight become 0, return, and free wb_ctl
> before zram_writeback_endio calls wake_up().
> 
> CPU 0 (zram_writeback_endio)       CPU 1 (zram_complete_done_reqs)
> ============================       ============================
> spin_lock(&wb_ctl->done_lock);
> list_add(&req->entry, &wb_ctl->done_reqs);
> spin_unlock(&wb_ctl->done_lock);
>                                    while (&wb_ctl->num_inflight) > 0)
>                                    spin_lock(&wb_ctl->done_lock);
>                                    list_del(&req->entry);
>                                    spin_unlock(&wb_ctl->done_lock);
> 				   // num_inflight becomes 0
>                                    atomic_dec(&wb_ctl->num_inflight);
>                                    returns to writeback_store();
> 				   // frees wb_ctl
>                                    release_wb_ctl(wb_ctl);
> 
> // UAF crash!
> wake_up(&wb_ctl->done_wait);
> 
> Fix this by moving wake_up() inside the done_lock critical section.
> This ensures that zram_complete_done_reqs cannot consume the request
> and decrement num_inflight until zram_writeback_endio has finished
> calling wake_up() and released the lock.
> 
> Fixes: f405066a1f0d ("zram: introduce writeback bio batching")
> Signed-off-by: Richard Chang <richardycc@google.com>
> ---
>  drivers/block/zram/zram_drv.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
> index aebc710f0d6a..a457fdf564f8 100644
> --- a/drivers/block/zram/zram_drv.c
> +++ b/drivers/block/zram/zram_drv.c
> @@ -966,9 +966,8 @@ static void zram_writeback_endio(struct bio *bio)
>  
>  	spin_lock_irqsave(&wb_ctl->done_lock, flags);
>  	list_add(&req->entry, &wb_ctl->done_reqs);
> -	spin_unlock_irqrestore(&wb_ctl->done_lock, flags);
> -
>  	wake_up(&wb_ctl->done_wait);
> +	spin_unlock_irqrestore(&wb_ctl->done_lock, flags);
>  }
>  

I agree this will fix the issue, but using a lock to extend the lifetime of
an object to avoid a UAF is not a good pattern. Object lifetime shared between
process and interrupt contexts should be managed explicitly using refcount.

Furthermore, keeping wake_up() outside the critical section minimizes
interrupt-disabled latency and avoids nesting spinlocks
(done_lock -> done_wait.lock), reducing the risk of future lockdep
issues, just in case.

It definitely will add more overhead for the submission/completion paths to deal
with the refcount, but I think we should go that way at the cost of runtime.

^ permalink raw reply

* Re: [PATCH v2 3/3] mmc: sdhci-esdhc-imx: consolidate imx25/35 data and add Kingston CID
From: Frank Li @ 2026-05-05 16:28 UTC (permalink / raw)
  To: Adrián García Casado
  Cc: Ulf Hansson, Adrian Hunter, Andreas Hindborg, Jens Axboe,
	Miri Korenblit, Miguel Ojeda, Haibo Chen, Sascha Hauer,
	Boqun Feng, linux-mmc, imx, linux-arm-kernel, linux-block,
	rust-for-linux, linux-wireless, linux-kernel,
	Adrián García Casado
In-Reply-To: <20260315172746.270734-4-adriangarciacasado42@gmail.com>

On Sun, Mar 15, 2026 at 06:26:40PM +0100, Adrián García Casado wrote:
> Consolidate esdhc_imx25 and esdhc_imx35 soc data into a single shared
> struct since they share the same flags. This reduces redundancy. Also
> add the CID_MANFID_KINGSTON definition to quirks.h for centralized
> management.
>
> Signed-off-by: Adrián García Casado <adriangarciacicuelo@gmail.com>
> ---
>  drivers/mmc/core/quirks.h          |  4 ++++
>  drivers/mmc/host/sdhci-esdhc-imx.c | 12 ++++--------
>  2 files changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/mmc/core/quirks.h b/drivers/mmc/core/quirks.h
> index c417ed34c..d736bb4be 100644
> --- a/drivers/mmc/core/quirks.h
> +++ b/drivers/mmc/core/quirks.h
> @@ -15,6 +15,10 @@
>
>  #include "card.h"
>
> +#ifndef CID_MANFID_KINGSTON
> +#define CID_MANFID_KINGSTON	0x70
> +#endif
> +

Where use it? It is un-related change with sdhci-esdhc-imx.c. Please split
it.

Frank

>  static const struct mmc_fixup __maybe_unused mmc_sd_fixups[] = {
>  	/*
>  	 * Kingston Canvas Go! Plus microSD cards never finish SD cache flush.
> diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
> index a7a5df673..9cfa26722 100644
> --- a/drivers/mmc/host/sdhci-esdhc-imx.c
> +++ b/drivers/mmc/host/sdhci-esdhc-imx.c
> @@ -256,11 +256,7 @@ struct esdhc_soc_data {
>  	u32 quirks;
>  };
>
> -static const struct esdhc_soc_data esdhc_imx25_data = {
> -	.flags = ESDHC_FLAG_ERR004536,
> -};
> -
> -static const struct esdhc_soc_data esdhc_imx35_data = {
> +static const struct esdhc_soc_data esdhc_imx25_35_data = {
>  	.flags = ESDHC_FLAG_ERR004536,
>  };
>
> @@ -391,8 +387,8 @@ struct pltfm_imx_data {
>  };
>
>  static const struct of_device_id imx_esdhc_dt_ids[] = {
> -	{ .compatible = "fsl,imx25-esdhc", .data = &esdhc_imx25_data, },
> -	{ .compatible = "fsl,imx35-esdhc", .data = &esdhc_imx35_data, },
> +	{ .compatible = "fsl,imx25-esdhc", .data = &esdhc_imx25_35_data, },
> +	{ .compatible = "fsl,imx35-esdhc", .data = &esdhc_imx25_35_data, },
>  	{ .compatible = "fsl,imx51-esdhc", .data = &esdhc_imx51_data, },
>  	{ .compatible = "fsl,imx53-esdhc", .data = &esdhc_imx53_data, },
>  	{ .compatible = "fsl,imx6sx-usdhc", .data = &usdhc_imx6sx_data, },
> @@ -414,7 +410,7 @@ MODULE_DEVICE_TABLE(of, imx_esdhc_dt_ids);
>
>  static inline int is_imx25_esdhc(struct pltfm_imx_data *data)
>  {
> -	return data->socdata == &esdhc_imx25_data;
> +	return data->socdata == &esdhc_imx25_35_data;
>  }
>
>  static inline int is_imx53_esdhc(struct pltfm_imx_data *data)
> --
> 2.47.3
>

^ permalink raw reply

* Re: [PATCH v5 1/1] block/blk-mq: use atomic_t for quiesce_depth to avoid lock contention on RT
From: Bart Van Assche @ 2026-05-05 15:41 UTC (permalink / raw)
  To: Ionut Nechita (Wind River), linux-block, axboe
  Cc: bigeasy, clrkwllms, rostedt, ming.lei, muchun.song, mkhalfella,
	chris.friesen, linux-kernel, linux-rt-devel, linux-rt-users,
	stable, ionut_n2001, sunlightlinux
In-Reply-To: <20260303073744.20585-2-ionut.nechita@windriver.com>

On 3/3/26 8:37 AM, Ionut Nechita (Wind River) wrote:
> +	/*
> +	 * Ensure the store to quiesce_depth is visible before any
> +	 * subsequent loads in blk_mq_run_hw_queue().
> +	 */
This comment does not make sense to me. How could there be a dependency
of blk_mq_run_hw_queue() on *loads* that happen in 
blk_mq_quiesce_queue_nowait() after atomic_inc(&q->quiesce_depth)?

Bart.

^ permalink raw reply

* Re: [PATCH v2] block: only read from sqe on initial invocation of blkdev_uring_cmd()
From: Caleb Sander Mateos @ 2026-05-05 15:32 UTC (permalink / raw)
  To: Jens Axboe; +Cc: linux-block@vger.kernel.org
In-Reply-To: <64e053e4-24aa-434d-9b35-794d3b292628@kernel.dk>

On Tue, May 5, 2026 at 12:38 AM Jens Axboe <axboe@kernel.dk> wrote:
>
> This passthrough helper currently only supports discards. Part of that
> command is the start and length, which is read from the SQE. It does
> so on every invocation, where it really should just make it stable
> on the first invocation. This avoids needing to copy the SQE upfront,
> as we only really need those two 8b values stored in our per-req
> payload.

Maybe I'm missing something, but how does this avoid the SQE copy?
Won't io_uring_cmd_sqe_copy() still copy the SQE if the command issue
is delayed by links/drain/forced async or if the initial issue returns
EAGAIN? The code change looks fine to me, but I'm not sure I
understand the motivation.

Best,
Caleb

>
> Cc: stable@vger.kernel.org # 6.17+
> Signed-off-by: Jens Axboe <axboe@kernel.dk>
>
> ---
>
> Changes since v1:
> - Use IORING_URING_CMD_REISSUE flag (Caleb)
>
> diff --git a/block/ioctl.c b/block/ioctl.c
> index fc3be0549aa7..ab2c9ed79946 100644
> --- a/block/ioctl.c
> +++ b/block/ioctl.c
> @@ -857,6 +857,8 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
>  #endif
>
>  struct blk_iou_cmd {
> +       u64 start;
> +       u64 len;
>         int res;
>         bool nowait;
>  };
> @@ -946,23 +948,27 @@ int blkdev_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags)
>  {
>         struct block_device *bdev = I_BDEV(cmd->file->f_mapping->host);
>         struct blk_iou_cmd *bic = io_uring_cmd_to_pdu(cmd, struct blk_iou_cmd);
> -       const struct io_uring_sqe *sqe = cmd->sqe;
>         u32 cmd_op = cmd->cmd_op;
> -       uint64_t start, len;
>
> -       if (unlikely(sqe->ioprio || sqe->__pad1 || sqe->len ||
> -                    sqe->rw_flags || sqe->file_index))
> -               return -EINVAL;
> +       /* Read what we need from the SQE on the first issue */
> +       if (!(issue_flags & IORING_URING_CMD_REISSUE)) {
> +               const struct io_uring_sqe *sqe = cmd->sqe;
> +
> +               if (unlikely(sqe->ioprio || sqe->__pad1 || sqe->len ||
> +                            sqe->rw_flags || sqe->file_index))
> +                       return -EINVAL;
> +
> +               bic->start = READ_ONCE(sqe->addr);
> +               bic->len = READ_ONCE(sqe->addr3);
> +       }
>
>         bic->res = 0;
>         bic->nowait = issue_flags & IO_URING_F_NONBLOCK;
>
> -       start = READ_ONCE(sqe->addr);
> -       len = READ_ONCE(sqe->addr3);
> -
>         switch (cmd_op) {
>         case BLOCK_URING_CMD_DISCARD:
> -               return blkdev_cmd_discard(cmd, bdev, start, len, bic->nowait);
> +               return blkdev_cmd_discard(cmd, bdev, bic->start, bic->len,
> +                                         bic->nowait);
>         }
>         return -EINVAL;
>  }
>
> --
> Jens Axboe
>

^ permalink raw reply

* Re: [PATCH v5 0/1] block/blk-mq: use atomic_t for quiesce_depth to avoid lock contention on RT
From: Sebastian Andrzej Siewior @ 2026-05-05 15:03 UTC (permalink / raw)
  To: Ionut Nechita (Wind River), axboe
  Cc: linux-block, clrkwllms, rostedt, ming.lei, muchun.song,
	mkhalfella, chris.friesen, linux-kernel, linux-rt-devel,
	linux-rt-users, stable, ionut_n2001, sunlightlinux
In-Reply-To: <20260303073744.20585-1-ionut.nechita@windriver.com>

On 2026-03-03 09:37:43 [+0200], Ionut Nechita (Wind River) wrote:
> Hi Jens,

Hi Jens,

> This is v5 of the fix for the RT kernel performance regression caused by
> commit 6bda857bcbb86 ("block: fix ordering between checking
> QUEUE_FLAG_QUIESCED request adding").
> 
> Changes since v4 (Feb 13):
> - Rebased on top of linux-next (20260302)
> - No code changes

Anything wrong with this?

Sebastian

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox