Re: [PATCH RFC v3] nbd: skip queue limits update for size-only reconfigure
Krystian Kaniewski <[email protected]> Thu, 23 Jul 2026 11:50:30 +0200
| Newsgroups | dev.linux.lists.syzbot |
|---|---|
| Message-ID | <[email protected]> |
Keep the code diff unchanged and correct the commit message in the
replacement patch.
Make these required changes:
1. Replace:
Fixes: 2dc691cc4ac2 ("nbd: refactor size updates")
with:
Fixes: 242a49e5c878 ("nbd: freeze the queue for queue limits updates")
Commit 2dc691cc4ac2 merged the NBD size helpers, but it did not freeze
the request queue. Commit 242a49e5c878 added queue freezing around live
nbd_set_size() calls and is the first commit which made the reported
capacity-only hang possible. Commit f3dec61d7544 later changed the
implementation to queue_limits_commit_update_frozen(), but retained the
wait.
2. Remove the two shortened stack traces from the commit message. They
use the task names nbd-client:6285 and generic-netlink:6030, while the
report identifies syz.0.17:6086 and syz.3.27:6088. Several function
offsets are also different. Do not present reconstructed text as report
output. The prose explanation already describes the relevant call path.
3. Replace "system-wide deadlock" with "global generic netlink stall".
The blocked genl_mutex prevents unrelated generic netlink operations
from progressing, but the report does not show that the whole system is
deadlocked.
Preserve the subject and the current implementation. In particular, keep
the no-freeze path limited to generic netlink capacity-only updates with
an unchanged effective block size. Keep zero block-size normalization
and validation, initial startup, real block-size changes, and all legacy
size ioctls on their current paths. Do not reintroduce the
nbd_total_devices counter change or any generic netlink parallelism.
Produce a complete replacement patch with the corrected commit message
and the unchanged code diff.
On 7/22/2026 8:40 PM, syzbot wrote:
> Commit 242a49e5c878 ("nbd: freeze the queue for queue limits updates")
> correctly added queue freezing for live updates of real queue limits.
> However, nbd_set_size() is also used for capacity-only generic netlink
> updates, so the freeze is unnecessarily broad for the reported request.
>
> When an NBD server becomes unresponsive, it leaves I/O in flight. An
> unnecessary queue freeze during a size-only reconfigure will wait forever
> for these in-flight I/Os to complete while the global genl_mutex is held,
> leading to a system-wide deadlock.
>
> A size-only reconfigure can update config->bytesize and disk capacity
> directly because the effective block size and all other queue limits stay
> unchanged.
>
> This patch introduces nbd_size_set() to handle size-only updates directly
> without freezing the queue or committing queue limits. Capacity-only
> generic netlink reconfiguration no longer freezes the queue, while startup
> and real block-size changes continue to use the existing frozen limits
> update via nbd_set_size().
>
> INFO: task nbd-client:6285 blocked for more than 143 seconds.
> Call Trace:
> <TASK>
> blk_mq_freeze_queue_wait+0x101/0x180 block/blk-mq.c:191
> queue_limits_commit_update_frozen+0x55/0xd0 block/blk-settings.c:590
> nbd_set_size+0x454/0x680 drivers/block/nbd.c:374
> nbd_genl_reconfigure+0x7e9/0x1e80 drivers/block/nbd.c:2373
> genl_rcv_msg+0x614/0x7a0 net/netlink/genetlink.c:1209
> </TASK>
>
> INFO: task generic-netlink:6030 blocked for more than 143 seconds.
> Call Trace:
> <TASK>
> __mutex_lock+0x7c5/0x1590 kernel/locking/mutex.c:820
> genl_rcv_msg+0x10b/0x7a0 net/netlink/genetlink.c:1208
> </TASK>
>
> Fixes: 2dc691cc4ac2 ("nbd: refactor size updates")
> Assisted-by: Gemini:gemini-3.5-flash Gemini:gemini-3.1-pro-preview syzbot
> Reported-by: syzbot <[email protected]>
> Closes: https://syzkaller.appspot.com/bug?extid=f272bbfbf8498ddadea5
> Link: https://syzkaller.appspot.com/ai_job?id=c8611da4-ddd9-47e3-bbe2-8e178beb3f96
> To: "Jens Axboe" <[email protected]>
> To: "Josef Bacik" <[email protected]>
> To: <[email protected]>
> To: <[email protected]>
> To: "Christoph Hellwig" <[email protected]>
> Cc: <[email protected]>
>
> ---
> v3:
> - Removed the unrelated decrement of nbd_total_devices in nbd_dev_remove().
> - Corrected the referenced commit title of 242a49e5c878 in the description.
> - Clarified that capacity-only generic netlink reconfiguration no longer freezes the queue, while startup and real block-size changes continue to do so.
>
> v2:
> - Replaced the approach of using parallel netlink ops and custom timeouts with skipping queue limits updates for size-only reconfigurations.
> - Introduced nbd_size_set() and nbd_size_update() to update device capacity directly without freezing the queue when the block size does not change.
> - Retained queue freezing only for actual block-size changes.
> - Added decrement of nbd_total_devices in nbd_dev_remove().
> https://lore.kernel.org/all/[email protected]/T/
>
> v1:
> https://lore.kernel.org/all/[email protected]/T/
> ---
> diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
> index fe63f3c55..567b031ec 100644
> --- a/drivers/block/nbd.c
> +++ b/drivers/block/nbd.c
> @@ -331,6 +331,27 @@ static void nbd_mark_nsock_dead(struct nbd_device *nbd, struct nbd_sock *nsock,
> nsock->sent = 0;
> }
>
> +static void nbd_size_update(struct nbd_device *nbd)
> +{
> + struct nbd_config *config = nbd->config;
> +
> + if (max_part)
> + set_bit(GD_NEED_PART_SCAN, &nbd->disk->state);
> + if (!set_capacity_and_notify(nbd->disk, config->bytesize >> 9))
> + kobject_uevent(&nbd_to_dev(nbd)->kobj, KOBJ_CHANGE);
> +}
> +
> +static int nbd_size_set(struct nbd_device *nbd, loff_t bytesize)
> +{
> + if (bytesize < 0)
> + return -EINVAL;
> +
> + nbd->config->bytesize = bytesize;
> + if (nbd->pid)
> + nbd_size_update(nbd);
> + return 0;
> +}
> +
> static int nbd_set_size(struct nbd_device *nbd, loff_t bytesize, loff_t blksize)
> {
> struct queue_limits lim;
> @@ -375,10 +396,7 @@ static int nbd_set_size(struct nbd_device *nbd, loff_t bytesize, loff_t blksize)
> if (error)
> return error;
>
> - if (max_part)
> - set_bit(GD_NEED_PART_SCAN, &nbd->disk->state);
> - if (!set_capacity_and_notify(nbd->disk, bytesize >> 9))
> - kobject_uevent(&nbd_to_dev(nbd)->kobj, KOBJ_CHANGE);
> + nbd_size_update(nbd);
> return 0;
> }
>
> @@ -2062,11 +2080,19 @@ static int nbd_genl_size_set(struct genl_info *info, struct nbd_device *nbd)
> if (info->attrs[NBD_ATTR_SIZE_BYTES])
> bytes = nla_get_u64(info->attrs[NBD_ATTR_SIZE_BYTES]);
>
> - if (info->attrs[NBD_ATTR_BLOCK_SIZE_BYTES])
> + if (info->attrs[NBD_ATTR_BLOCK_SIZE_BYTES]) {
> bsize = nla_get_u64(info->attrs[NBD_ATTR_BLOCK_SIZE_BYTES]);
> + if (!bsize)
> + bsize = 1u << NBD_DEF_BLKSIZE_BITS;
> + if (blk_validate_block_size(bsize))
> + return -EINVAL;
> + }
>
> - if (bytes != config->bytesize || bsize != nbd_blksize(config))
> - return nbd_set_size(nbd, bytes, bsize);
> + if (bytes != config->bytesize || bsize != nbd_blksize(config)) {
> + if (bsize != nbd_blksize(config))
> + return nbd_set_size(nbd, bytes, bsize);
> + return nbd_size_set(nbd, bytes);
> + }
> return 0;
> }
>
>
>
> base-commit: 8cd9520d35a6c38db6567e97dd93b1f11f185dc6