All Virtuozzo development lists (kernel + QEMU)
 help / color / mirror / Atom feed
From: Alexander Ivanov <alexander.ivanov@virtuozzo.com>
To: andrey.zhadchenko@virtuozzo.com
Cc: andrey.drobyshev@virtuozzo.com, svt-core@virtuozzo.com
Subject: [PATCH hci-8.1 v4 4/5] vhost-blk: create kernel threads with the mainstream worker ioctls
Date: Thu, 29 Oct 2026 10:23:00 +0100	[thread overview]
Message-ID: <20261029092301.3286535-5-alexander.ivanov@virtuozzo.com> (raw)
In-Reply-To: <20261029092301.3286535-1-alexander.ivanov@virtuozzo.com>

num-threads was passed to our own VHOST_SET_NWORKERS kernel ioctl. The
kernel drops it with the revert of "drivers/vhost: add ioctl to
increase the number of workers" in favour of the mainstream worker
ioctls, which vhost-blk now supports. Create num-threads - 1 workers
with VHOST_NEW_WORKER and attach them to the virtqueues round-robin
with VHOST_ATTACH_VRING_WORKER, the layout VHOST_SET_NWORKERS produced.

Our kernel, unlike mainline, defaults to kthread mode, where
VHOST_NEW_WORKER fails with -EFAULT rather than -ENOTTY. So switch the
device to vhost_task mode with VHOST_SET_FORK_FROM_OWNER before
VHOST_SET_OWNER. With num-threads=1 nothing changes: no worker ioctls,
kthread mode.

Released vz10 kernels have VHOST_SET_FORK_FROM_OWNER, but their
vhost-blk does not handle the worker ioctls and fails VHOST_NEW_WORKER
with -ENOTTY. Other errors are possible as well, so do not key on the
errno: if VHOST_SET_FORK_FROM_OWNER fails, keep all virtqueues on the
default thread; if VHOST_NEW_WORKER fails partway, spread the
remaining virtqueues over the threads created so far; if attaching a
virtqueue fails, it stays on the default thread. Either way warn rather
than fail to start vhost-blk. Unless VHOST_SET_FORK_FROM_OWNER failed,
the default thread stays a vhost_task, as the mode cannot be changed
after VHOST_SET_OWNER.

https://virtuozzo.atlassian.net/browse/VSTOR-107537

Signed-off-by: Alexander Ivanov <alexander.ivanov@virtuozzo.com>
---
 hw/block/vhost-blk.c | 64 +++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 60 insertions(+), 4 deletions(-)

diff --git a/hw/block/vhost-blk.c b/hw/block/vhost-blk.c
index b3eb181ceae..9416c3ac07e 100644
--- a/hw/block/vhost-blk.c
+++ b/hw/block/vhost-blk.c
@@ -33,6 +33,53 @@
 #include "migration/cpr.h"
 #include "system/runstate.h"
 
+/*
+ * Spread the virtqueues round-robin over nworkers kernel threads. Thread 0 is
+ * the default worker VHOST_SET_OWNER created; vq 0 and every nworkers-th vq
+ * after it stay on it.
+ */
+static void vhost_blk_set_workers(struct vhost_dev *hdev, int nworkers)
+{
+    uint32_t ids[VHOST_BLK_MAX_QUEUES];
+    int i, ret, err = 0, nfailed = 0;
+
+    assert(nworkers <= ARRAY_SIZE(ids));
+
+    for (i = 1; i < hdev->nvqs; i++) {
+        int w = i % nworkers;
+        struct vhost_vring_worker vq_worker = { .index = i };
+
+        if (w == 0) {
+            continue;
+        }
+
+        if (i < nworkers) {
+            struct vhost_worker_state worker = { };
+
+            ret = hdev->vhost_ops->vhost_new_worker(hdev, &worker);
+            if (ret < 0) {
+                warn_report("vhost-blk: unable to create kernel thread: %s",
+                            strerror(-ret));
+                nworkers = i;
+                continue;
+            }
+            ids[w] = worker.worker_id;
+        }
+
+        vq_worker.worker_id = ids[w];
+        ret = hdev->vhost_ops->vhost_attach_vring_worker(hdev, &vq_worker);
+        if (ret < 0) {
+            err = ret;
+            nfailed++;
+        }
+    }
+
+    if (nfailed) {
+        warn_report("vhost-blk: unable to attach kernel threads to %d "
+                    "queues: %s", nfailed, strerror(-err));
+    }
+}
+
 static int vhost_blk_start(VirtIODevice *vdev)
 {
     VHostBlk *s = VHOST_BLK(vdev);
@@ -52,15 +99,24 @@ static int vhost_blk_start(VirtIODevice *vdev)
         return 0;
     }
 
+    nworkers = MIN(s->conf.num_threads, hdev->nvqs);
+    if (nworkers > 1) {
+        ret = hdev->vhost_ops->vhost_set_fork_from_owner(hdev,
+                                                         VHOST_FORK_OWNER_TASK);
+        if (ret < 0) {
+            warn_report("vhost-blk: unable to use multiple kernel threads: "
+                        "%s", strerror(-ret));
+            nworkers = 1;
+        }
+    }
+
     if (ioctl(s->vhostfd, VHOST_SET_OWNER, NULL)) {
         error_report("vhost-blk: unable to set owner");
         return -ENOSYS;
     }
 
-    nworkers = s->conf.num_threads;
-    if (nworkers != 1 && ioctl(s->vhostfd, VHOST_SET_NWORKERS, &nworkers)) {
-        error_report("vhost-blk: unable to set number of kernel threads");
-        return -EINVAL;
+    if (nworkers > 1) {
+        vhost_blk_set_workers(hdev, nworkers);
     }
 
     if (s->conf.serial) {
-- 
2.53.0


  parent reply	other threads:[~2026-10-29  9:23 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-29  9:22 [PATCH hci-8.1 v4 0/5] vhost-blk: switch from VHOST_SET_NWORKERS to " Alexander Ivanov
2026-10-29  9:22 ` [PATCH hci-8.1 v4 1/5] vhost-backend: add vhost_set_fork_from_owner op Alexander Ivanov
2026-10-29  9:24   ` no-reply
2026-10-29  9:22 ` [PATCH hci-8.1 v4 2/5] vhost-blk: reject num-queues above VHOST_BLK_MAX_QUEUES Alexander Ivanov
2026-10-29  9:24   ` no-reply
2026-10-29  9:22 ` [PATCH hci-8.1 v4 3/5] vhost-blk: use a local vhost_dev pointer in start and stop Alexander Ivanov
2026-10-29  9:24   ` no-reply
2026-10-29 10:04     ` Alexander Ivanov
2026-10-29  9:28   ` Andrey Drobyshev
2026-10-29  9:23 ` Alexander Ivanov [this message]
2026-10-29  9:27   ` [PATCH hci-8.1 v4 4/5] vhost-blk: create kernel threads with the mainstream worker ioctls no-reply
2026-10-29  9:57     ` Alexander Ivanov
2026-10-29  9:35   ` Andrey Drobyshev
2026-10-29 10:12   ` Andrey Zhadchenko
2026-10-29  9:23 ` [PATCH hci-8.1 v4 5/5] linux-headers: drop VHOST_SET_NWORKERS Alexander Ivanov
2026-10-29  9:25   ` no-reply

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=20261029092301.3286535-5-alexander.ivanov@virtuozzo.com \
    --to=alexander.ivanov@virtuozzo.com \
    --cc=andrey.drobyshev@virtuozzo.com \
    --cc=andrey.zhadchenko@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.