From: Alexander Ivanov <alexander.ivanov@virtuozzo.com>
To: no-reply@sashiko.virtuozzo.com, andrey.zhadchenko@virtuozzo.com
Cc: andrey.drobyshev@virtuozzo.com, svt-core@virtuozzo.com
Subject: Re: [PATCH hci-8.1 1/2] vhost-blk: create kernel threads with the mainstream worker ioctls
Date: Tue, 27 Oct 2026 13:11:20 +0100 [thread overview]
Message-ID: <829bf354-5783-4b06-a43b-cabcfef97bf5@virtuozzo.com> (raw)
In-Reply-To: <010701a17d2bfd69-07c611d4-bf3a-47f3-9970-bc829fc0ef42-000000@eu-central-1.amazonses.com>
>> +static int vhost_blk_set_workers(VHostBlk *s, int nworkers)
>> +{
>> + uint32_t ids[VHOST_BLK_MAX_QUEUES];
>> + struct vhost_worker_state worker;
>> + struct vhost_vring_worker vq_worker;
>> + int ret, i;
>> +
>> + for (i = 1; i < nworkers; i++) {
>> + memset(&worker, 0, sizeof(worker));
>> + if (ioctl(s->vhostfd, VHOST_NEW_WORKER, &worker)) {
>> + ret = -errno;
>> + if (ret == -ENOTTY && i == 1) {
>> + warn_report_once("vhost-blk: kernel does not support worker "
>> + "ioctls, using a single kernel thread");
>> + return 0;
>> + }
>> + error_report("vhost-blk: unable to create kernel thread: %s",
>> + strerror(-ret));
>> + return ret;
>> + }
>> + ids[i] = worker.worker_id;
> [Severity: High]
> Can this overflow ids[]?
>
> ids[] has VHOST_BLK_MAX_QUEUES (32) entries, but nworkers is bounded only
> by nvqs. In vhost_blk_start():
>
> nworkers = MIN(s->conf.num_threads, s->dev.nvqs);
>
> vhost_blk_device_realize() and vhost_blk_pci_realize() clamp num-queues to
> VHOST_BLK_MAX_QUEUES only when it equals VHOST_BLK_AUTO_NUM_QUEUES:
>
> if (conf->num_queues == VHOST_BLK_AUTO_NUM_QUEUES) {
> conf->num_queues = MIN(virtio_pci_optimal_num_queues(0),
> VHOST_BLK_MAX_QUEUES);
> }
>
> An explicit value such as num-queues=64 is accepted and becomes
> s->dev.nvqs. With num-threads=64, nworkers is 64.
>
> The loop above then writes ids[i] past the end of the stack array for
> i >= 32.
Fixed.
>
>> + }
>> +
>> + for (i = 0; i < s->dev.nvqs; i++) {
>> + if (i % nworkers == 0) {
>> + continue;
>> + }
>> + memset(&vq_worker, 0, sizeof(vq_worker));
>> + vq_worker.index = i;
>> + vq_worker.worker_id = ids[i % nworkers];
> The same configuration also reads ids[i % nworkers] out of bounds when
> i % nworkers >= 32.
>
> Should realize reject num-queues above VHOST_BLK_MAX_QUEUES, or should
> ids[] be sized from nworkers or nvqs?
Fixed.
>
> [ ... ]
>
>> static int vhost_blk_start(VirtIODevice *vdev)
>> {
> [ ... ]
>
>> + nworkers = MIN(s->conf.num_threads, s->dev.nvqs);
>> + if (nworkers > 1) {
> [Severity: Low]
> Is it intended that num-threads=0 and values above nvqs are silently
> clamped here?
>
> vhost_blk_device_realize() validates num-queues but has no equivalent
> check for num-threads, and the property is an unconstrained uint16:
>
> DEFINE_PROP_UINT16("num-threads", VHostBlk, conf.num_threads, 1),
>
> With num-threads=0, nworkers becomes 0, the nworkers > 1 test is false,
> and no worker ioctls are issued. Before this patch the old condition was
> nworkers != 1, so a value of 0 reached VHOST_SET_NWORKERS.
>
> Would a realize-time check that rejects 0, or warns when num-threads
> exceeds num-queues, make the behaviour explicit? The commit message only
> says that num-threads=1 is unchanged.
No behaviour change: the old VHOST_SET_NWORKERS handler already
clamped n to nvqs and created no extra workers for n=0, and the patch
does the same on the QEMU side.
>> + /*
>> + * VHOST_NEW_WORKER works only in vhost_task mode, and
>> + * VHOST_RESET_OWNER brings the kthread default back.
>> + */
>> + uint8_t fork_owner = VHOST_FORK_OWNER_TASK;
>> +
>> + if (ioctl(s->vhostfd, VHOST_SET_FORK_FROM_OWNER, &fork_owner)) {
>> + ret = -errno;
>> + if (ret != -ENOTTY) {
>> + error_report("vhost-blk: unable to set vhost task mode: %s",
>> + strerror(-ret));
>> + return ret;
>> + }
>> + warn_report_once("vhost-blk: kernel does not support vhost "
>> + "tasks, using a single kernel thread");
>> + nworkers = 1;
> [Severity: Medium]
> Does this -ENOTTY fallback drop a working multi-thread configuration?
>
> linux-headers/linux/vhost.h documents VHOST_SET_FORK_FROM_OWNER as "Only
> available when CONFIG_VHOST_ENABLE_FORK_OWNER_CONTROL=y". It also
> documents VHOST_FORK_OWNER_TASK as the "(default value)".
>
> A kernel built without that option returns -ENOTTY here. According to the
> header, such a kernel runs in task mode, which VHOST_NEW_WORKER and
> VHOST_ATTACH_VRING_WORKER need. In that case nworkers = 1 discards a
> usable setup.
>
> The commit message says "the kernel defaults to kthreads", which
> contradicts the header. I could not check the kernel source for the target
> kernel, so which one is correct is unverified.
>
> vhost_blk_set_workers() already handles -ENOTTY from VHOST_NEW_WORKER when
> i == 1, with its own warning and single-thread fallback. Is the earlier
> -ENOTTY fallback needed, given that?
Our kernel, unlike the mainline header, defaults to kthreads, so without
CONFIG_VHOST_ENABLE_FORK_OWNER_CONTROL VHOST_NEW_WORKER
fails with -EFAULT, which the vhost_blk_set_workers() fallback does not
catch,
so the early -ENOTTY fallback is needed (commit message reworded to say
"unlike mainline").
next prev parent reply other threads:[~2026-10-27 12:11 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-27 11:38 [PATCH hci-8.1 0/2] vhost-blk: switch from VHOST_SET_NWORKERS to " Alexander Ivanov
2026-10-27 11:38 ` [PATCH hci-8.1 1/2] vhost-blk: create kernel threads with " Alexander Ivanov
2026-10-27 11:43 ` no-reply
2026-10-27 12:11 ` Alexander Ivanov [this message]
2026-10-27 11:38 ` [PATCH hci-8.1 2/2] linux-headers: drop VHOST_SET_NWORKERS Alexander Ivanov
2026-10-27 11:42 ` no-reply
2026-10-27 12:29 ` Alexander Ivanov
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=829bf354-5783-4b06-a43b-cabcfef97bf5@virtuozzo.com \
--to=alexander.ivanov@virtuozzo.com \
--cc=andrey.drobyshev@virtuozzo.com \
--cc=andrey.zhadchenko@virtuozzo.com \
--cc=no-reply@sashiko.virtuozzo.com \
--cc=svt-core@virtuozzo.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.