* [PATCH] vhost: add a new ioctl VHOST_GET_VRING_WORKER_INFO and use in net.c
@ 2025-10-27 10:26 Nick Hudson
2025-10-27 22:17 ` kernel test robot
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Nick Hudson @ 2025-10-27 10:26 UTC (permalink / raw)
To: Michael S. Tsirkin, Jason Wang, Eugenio Pérez
Cc: Nick Hudson, Max Tottenham, kvm, virtualization, netdev,
linux-kernel
The vhost_net (and vhost_sock) drivers create worker tasks to handle
the virtual queues. Provide a new ioctl VHOST_GET_VRING_WORKER_INFO that
can be used to determine the PID of these tasks so that, for example,
they can be pinned to specific CPU(s).
Signed-off-by: Nick Hudson <nhudson@akamai.com>
Reviewed-by: Max Tottenham <mtottenh@akamai.com>
---
drivers/vhost/net.c | 5 +++++
drivers/vhost/vhost.c | 16 ++++++++++++++++
include/uapi/linux/vhost.h | 3 +++
include/uapi/linux/vhost_types.h | 13 +++++++++++++
kernel/vhost_task.c | 12 ++++++++++++
5 files changed, 49 insertions(+)
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 35ded4330431..e86bd5d7d202 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -1804,6 +1804,11 @@ static long vhost_net_ioctl(struct file *f, unsigned int ioctl,
return vhost_net_reset_owner(n);
case VHOST_SET_OWNER:
return vhost_net_set_owner(n);
+ case VHOST_GET_VRING_WORKER_INFO:
+ mutex_lock(&n->dev.mutex);
+ r = vhost_worker_ioctl(&n->dev, ioctl, argp);
+ mutex_unlock(&n->dev.mutex);
+ return r;
default:
mutex_lock(&n->dev.mutex);
r = vhost_dev_ioctl(&n->dev, ioctl, argp);
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 8570fdf2e14a..8b52fd5723c3 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -2399,6 +2399,22 @@ long vhost_dev_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *argp)
if (ctx)
eventfd_ctx_put(ctx);
break;
+ case VHOST_GET_VRING_WORKER_INFO:
+ worker = rcu_dereference_check(vq->worker,
+ lockdep_is_held(&dev->mutex));
+ if (!worker) {
+ ret = -EINVAL;
+ break;
+ }
+
+ memset(&ring_worker_info, 0, sizeof(ring_worker_info));
+ ring_worker_info.index = idx;
+ ring_worker_info.worker_id = worker->id;
+ ring_worker_info.worker_pid = task_pid_vnr(vhost_get_task(worker->vtsk));
+
+ if (copy_to_user(argp, &ring_worker_info, sizeof(ring_worker_info)))
+ ret = -EFAULT;
+ break;
default:
r = -ENOIOCTLCMD;
break;
diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h
index c57674a6aa0d..c32aa8c71952 100644
--- a/include/uapi/linux/vhost.h
+++ b/include/uapi/linux/vhost.h
@@ -101,6 +101,9 @@
/* Return the vring worker's ID */
#define VHOST_GET_VRING_WORKER _IOWR(VHOST_VIRTIO, 0x16, \
struct vhost_vring_worker)
+/* Return the vring worker's ID and PID */
+#define VHOST_GET_VRING_WORKER_INFO _IOWR(VHOST_VIRTIO, 0x17, \
+ struct vhost_vring_worker_info)
/* The following ioctls use eventfd file descriptors to signal and poll
* for events. */
diff --git a/include/uapi/linux/vhost_types.h b/include/uapi/linux/vhost_types.h
index 1c39cc5f5a31..28e00f8ade85 100644
--- a/include/uapi/linux/vhost_types.h
+++ b/include/uapi/linux/vhost_types.h
@@ -63,6 +63,19 @@ struct vhost_vring_worker {
unsigned int worker_id;
};
+/* Per-virtqueue worker mapping entry */
+struct vhost_vring_worker_info {
+ /* vring index */
+ unsigned int index;
+ /*
+ * The id of the vhost_worker returned from VHOST_NEW_WORKER or
+ * allocated as part of vhost_dev_set_owner.
+ */
+ unsigned int worker_id;
+
+ __kernel_pid_t worker_pid; /* PID/TID of worker thread, -1 if none */
+};
+
/* no alignment requirement */
struct vhost_iotlb_msg {
__u64 iova;
diff --git a/kernel/vhost_task.c b/kernel/vhost_task.c
index 27107dcc1cbf..aa87a7f0c98a 100644
--- a/kernel/vhost_task.c
+++ b/kernel/vhost_task.c
@@ -67,6 +67,18 @@ static int vhost_task_fn(void *data)
do_exit(0);
}
+/**
+ * vhost_get_task - get a pointer to the vhost_task's task_struct
+ * @vtsk: vhost_task to return the task for
+ *
+ * return the vhost_task's task.
+ */
+struct task_struct *vhost_get_task(struct vhost_task *vtsk)
+{
+ return vtsk->task;
+}
+EXPORT_SYMBOL_GPL(vhost_get_task);
+
/**
* vhost_task_wake - wakeup the vhost_task
* @vtsk: vhost_task to wake
--
2.34.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] vhost: add a new ioctl VHOST_GET_VRING_WORKER_INFO and use in net.c
2025-10-27 10:26 [PATCH] vhost: add a new ioctl VHOST_GET_VRING_WORKER_INFO and use in net.c Nick Hudson
@ 2025-10-27 22:17 ` kernel test robot
2025-10-27 22:27 ` kernel test robot
2025-10-28 0:42 ` Jason Wang
2 siblings, 0 replies; 5+ messages in thread
From: kernel test robot @ 2025-10-27 22:17 UTC (permalink / raw)
To: Nick Hudson, Michael S. Tsirkin, Jason Wang, Eugenio Pérez
Cc: llvm, oe-kbuild-all, Nick Hudson, Max Tottenham, kvm,
virtualization, netdev, linux-kernel
Hi Nick,
kernel test robot noticed the following build errors:
[auto build test ERROR on mst-vhost/linux-next]
[also build test ERROR on linus/master v6.18-rc3 next-20251027]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Nick-Hudson/vhost-add-a-new-ioctl-VHOST_GET_VRING_WORKER_INFO-and-use-in-net-c/20251027-182919
base: https://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git linux-next
patch link: https://lore.kernel.org/r/20251027102644.622305-1-nhudson%40akamai.com
patch subject: [PATCH] vhost: add a new ioctl VHOST_GET_VRING_WORKER_INFO and use in net.c
config: arm-randconfig-001-20251028 (https://download.01.org/0day-ci/archive/20251028/202510280515.pRBqbq4I-lkp@intel.com/config)
compiler: clang version 22.0.0git (https://github.com/llvm/llvm-project e1ae12640102fd2b05bc567243580f90acb1135f)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251028/202510280515.pRBqbq4I-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202510280515.pRBqbq4I-lkp@intel.com/
All errors (new ones prefixed by >>):
drivers/vhost/vhost.c:2403:3: error: use of undeclared identifier 'worker'
2403 | worker = rcu_dereference_check(vq->worker,
| ^~~~~~
drivers/vhost/vhost.c:2403:34: error: use of undeclared identifier 'vq'
2403 | worker = rcu_dereference_check(vq->worker,
| ^~
drivers/vhost/vhost.c:2403:34: error: use of undeclared identifier 'vq'
2403 | worker = rcu_dereference_check(vq->worker,
| ^~
drivers/vhost/vhost.c:2404:30: error: use of undeclared identifier 'dev'
2404 | lockdep_is_held(&dev->mutex));
| ^~~
drivers/vhost/vhost.c:2403:34: error: use of undeclared identifier 'vq'
2403 | worker = rcu_dereference_check(vq->worker,
| ^~
drivers/vhost/vhost.c:2405:8: error: use of undeclared identifier 'worker'
2405 | if (!worker) {
| ^~~~~~
drivers/vhost/vhost.c:2406:4: error: use of undeclared identifier 'ret'
2406 | ret = -EINVAL;
| ^~~
drivers/vhost/vhost.c:2410:11: error: use of undeclared identifier 'ring_worker_info'; did you mean 'print_worker_info'?
2410 | memset(&ring_worker_info, 0, sizeof(ring_worker_info));
| ^~~~~~~~~~~~~~~~
| print_worker_info
include/linux/workqueue.h:637:13: note: 'print_worker_info' declared here
637 | extern void print_worker_info(const char *log_lvl, struct task_struct *task);
| ^
drivers/vhost/vhost.c:2410:39: error: use of undeclared identifier 'ring_worker_info'; did you mean 'print_worker_info'?
2410 | memset(&ring_worker_info, 0, sizeof(ring_worker_info));
| ^~~~~~~~~~~~~~~~
| print_worker_info
include/linux/workqueue.h:637:13: note: 'print_worker_info' declared here
637 | extern void print_worker_info(const char *log_lvl, struct task_struct *task);
| ^
drivers/vhost/vhost.c:2411:3: error: use of undeclared identifier 'ring_worker_info'; did you mean 'print_worker_info'?
2411 | ring_worker_info.index = idx;
| ^~~~~~~~~~~~~~~~
| print_worker_info
include/linux/workqueue.h:637:13: note: 'print_worker_info' declared here
637 | extern void print_worker_info(const char *log_lvl, struct task_struct *task);
| ^
drivers/vhost/vhost.c:2411:19: error: member reference base type 'void (const char *, struct task_struct *)' is not a structure or union
2411 | ring_worker_info.index = idx;
| ~~~~~~~~~~~~~~~~^~~~~~
drivers/vhost/vhost.c:2411:28: error: use of undeclared identifier 'idx'
2411 | ring_worker_info.index = idx;
| ^~~
drivers/vhost/vhost.c:2412:3: error: use of undeclared identifier 'ring_worker_info'; did you mean 'print_worker_info'?
2412 | ring_worker_info.worker_id = worker->id;
| ^~~~~~~~~~~~~~~~
| print_worker_info
include/linux/workqueue.h:637:13: note: 'print_worker_info' declared here
637 | extern void print_worker_info(const char *log_lvl, struct task_struct *task);
| ^
drivers/vhost/vhost.c:2412:19: error: member reference base type 'void (const char *, struct task_struct *)' is not a structure or union
2412 | ring_worker_info.worker_id = worker->id;
| ~~~~~~~~~~~~~~~~^~~~~~~~~~
drivers/vhost/vhost.c:2412:32: error: use of undeclared identifier 'worker'
2412 | ring_worker_info.worker_id = worker->id;
| ^~~~~~
drivers/vhost/vhost.c:2413:3: error: use of undeclared identifier 'ring_worker_info'; did you mean 'print_worker_info'?
2413 | ring_worker_info.worker_pid = task_pid_vnr(vhost_get_task(worker->vtsk));
| ^~~~~~~~~~~~~~~~
| print_worker_info
include/linux/workqueue.h:637:13: note: 'print_worker_info' declared here
637 | extern void print_worker_info(const char *log_lvl, struct task_struct *task);
| ^
drivers/vhost/vhost.c:2413:19: error: member reference base type 'void (const char *, struct task_struct *)' is not a structure or union
2413 | ring_worker_info.worker_pid = task_pid_vnr(vhost_get_task(worker->vtsk));
| ~~~~~~~~~~~~~~~~^~~~~~~~~~~
>> drivers/vhost/vhost.c:2413:46: error: call to undeclared function 'vhost_get_task'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
2413 | ring_worker_info.worker_pid = task_pid_vnr(vhost_get_task(worker->vtsk));
| ^
drivers/vhost/vhost.c:2413:46: note: did you mean 'vhost_get_desc'?
drivers/vhost/vhost.c:1581:19: note: 'vhost_get_desc' declared here
1581 | static inline int vhost_get_desc(struct vhost_virtqueue *vq,
| ^
drivers/vhost/vhost.c:2413:61: error: use of undeclared identifier 'worker'
2413 | ring_worker_info.worker_pid = task_pid_vnr(vhost_get_task(worker->vtsk));
| ^~~~~~
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
vim +/vhost_get_task +2413 drivers/vhost/vhost.c
2352
2353 /* You must be the owner to do anything else */
2354 r = vhost_dev_check_owner(d);
2355 if (r)
2356 goto done;
2357
2358 switch (ioctl) {
2359 case VHOST_SET_MEM_TABLE:
2360 r = vhost_set_memory(d, argp);
2361 break;
2362 case VHOST_SET_LOG_BASE:
2363 if (copy_from_user(&p, argp, sizeof p)) {
2364 r = -EFAULT;
2365 break;
2366 }
2367 if ((u64)(unsigned long)p != p) {
2368 r = -EFAULT;
2369 break;
2370 }
2371 for (i = 0; i < d->nvqs; ++i) {
2372 struct vhost_virtqueue *vq;
2373 void __user *base = (void __user *)(unsigned long)p;
2374 vq = d->vqs[i];
2375 mutex_lock(&vq->mutex);
2376 /* If ring is inactive, will check when it's enabled. */
2377 if (vq->private_data && !vq_log_access_ok(vq, base))
2378 r = -EFAULT;
2379 else
2380 vq->log_base = base;
2381 mutex_unlock(&vq->mutex);
2382 }
2383 break;
2384 case VHOST_SET_LOG_FD:
2385 r = get_user(fd, (int __user *)argp);
2386 if (r < 0)
2387 break;
2388 ctx = fd == VHOST_FILE_UNBIND ? NULL : eventfd_ctx_fdget(fd);
2389 if (IS_ERR(ctx)) {
2390 r = PTR_ERR(ctx);
2391 break;
2392 }
2393 swap(ctx, d->log_ctx);
2394 for (i = 0; i < d->nvqs; ++i) {
2395 mutex_lock(&d->vqs[i]->mutex);
2396 d->vqs[i]->log_ctx = d->log_ctx;
2397 mutex_unlock(&d->vqs[i]->mutex);
2398 }
2399 if (ctx)
2400 eventfd_ctx_put(ctx);
2401 break;
2402 case VHOST_GET_VRING_WORKER_INFO:
2403 worker = rcu_dereference_check(vq->worker,
2404 lockdep_is_held(&dev->mutex));
2405 if (!worker) {
2406 ret = -EINVAL;
2407 break;
2408 }
2409
2410 memset(&ring_worker_info, 0, sizeof(ring_worker_info));
2411 ring_worker_info.index = idx;
2412 ring_worker_info.worker_id = worker->id;
> 2413 ring_worker_info.worker_pid = task_pid_vnr(vhost_get_task(worker->vtsk));
2414
2415 if (copy_to_user(argp, &ring_worker_info, sizeof(ring_worker_info)))
2416 ret = -EFAULT;
2417 break;
2418 default:
2419 r = -ENOIOCTLCMD;
2420 break;
2421 }
2422 done:
2423 return r;
2424 }
2425 EXPORT_SYMBOL_GPL(vhost_dev_ioctl);
2426
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] vhost: add a new ioctl VHOST_GET_VRING_WORKER_INFO and use in net.c
2025-10-27 10:26 [PATCH] vhost: add a new ioctl VHOST_GET_VRING_WORKER_INFO and use in net.c Nick Hudson
2025-10-27 22:17 ` kernel test robot
@ 2025-10-27 22:27 ` kernel test robot
2025-10-28 0:42 ` Jason Wang
2 siblings, 0 replies; 5+ messages in thread
From: kernel test robot @ 2025-10-27 22:27 UTC (permalink / raw)
To: Nick Hudson, Michael S. Tsirkin, Jason Wang, Eugenio Pérez
Cc: oe-kbuild-all, Nick Hudson, Max Tottenham, kvm, virtualization,
netdev, linux-kernel
Hi Nick,
kernel test robot noticed the following build errors:
[auto build test ERROR on mst-vhost/linux-next]
[also build test ERROR on linus/master v6.18-rc3 next-20251027]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Nick-Hudson/vhost-add-a-new-ioctl-VHOST_GET_VRING_WORKER_INFO-and-use-in-net-c/20251027-182919
base: https://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git linux-next
patch link: https://lore.kernel.org/r/20251027102644.622305-1-nhudson%40akamai.com
patch subject: [PATCH] vhost: add a new ioctl VHOST_GET_VRING_WORKER_INFO and use in net.c
config: csky-randconfig-002-20251028 (https://download.01.org/0day-ci/archive/20251028/202510280631.i6odx2RJ-lkp@intel.com/config)
compiler: csky-linux-gcc (GCC) 15.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251028/202510280631.i6odx2RJ-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202510280631.i6odx2RJ-lkp@intel.com/
All errors (new ones prefixed by >>):
drivers/vhost/vhost.c: In function 'vhost_dev_ioctl':
>> drivers/vhost/vhost.c:2403:17: error: 'worker' undeclared (first use in this function)
2403 | worker = rcu_dereference_check(vq->worker,
| ^~~~~~
drivers/vhost/vhost.c:2403:17: note: each undeclared identifier is reported only once for each function it appears in
In file included from include/linux/rbtree.h:24,
from include/linux/mm_types.h:11,
from include/linux/mmzone.h:22,
from include/linux/gfp.h:7,
from include/linux/mm.h:7,
from include/linux/scatterlist.h:8,
from include/linux/virtio.h:7,
from include/linux/virtio_config.h:7,
from include/uapi/linux/vhost_types.h:16,
from include/uapi/linux/vhost.h:14,
from drivers/vhost/vhost.c:14:
>> drivers/vhost/vhost.c:2403:48: error: 'vq' undeclared (first use in this function); did you mean 'rq'?
2403 | worker = rcu_dereference_check(vq->worker,
| ^~
include/linux/rcupdate.h:532:17: note: in definition of macro '__rcu_dereference_check'
532 | typeof(*p) *local = (typeof(*p) *__force)READ_ONCE(p); \
| ^
drivers/vhost/vhost.c:2403:26: note: in expansion of macro 'rcu_dereference_check'
2403 | worker = rcu_dereference_check(vq->worker,
| ^~~~~~~~~~~~~~~~~~~~~
>> drivers/vhost/vhost.c:2404:65: error: 'dev' undeclared (first use in this function); did you mean 'cdev'?
2404 | lockdep_is_held(&dev->mutex));
| ^~~
include/linux/rcupdate.h:483:52: note: in definition of macro 'RCU_LOCKDEP_WARN'
483 | #define RCU_LOCKDEP_WARN(c, s) do { } while (0 && (c))
| ^
include/linux/rcupdate.h:680:9: note: in expansion of macro '__rcu_dereference_check'
680 | __rcu_dereference_check((p), __UNIQUE_ID(rcu), \
| ^~~~~~~~~~~~~~~~~~~~~~~
drivers/vhost/vhost.c:2403:26: note: in expansion of macro 'rcu_dereference_check'
2403 | worker = rcu_dereference_check(vq->worker,
| ^~~~~~~~~~~~~~~~~~~~~
drivers/vhost/vhost.c:2404:48: note: in expansion of macro 'lockdep_is_held'
2404 | lockdep_is_held(&dev->mutex));
| ^~~~~~~~~~~~~~~
>> drivers/vhost/vhost.c:2406:25: error: 'ret' undeclared (first use in this function); did you mean 'net'?
2406 | ret = -EINVAL;
| ^~~
| net
>> drivers/vhost/vhost.c:2410:25: error: 'ring_worker_info' undeclared (first use in this function); did you mean 'print_worker_info'?
2410 | memset(&ring_worker_info, 0, sizeof(ring_worker_info));
| ^~~~~~~~~~~~~~~~
| print_worker_info
>> drivers/vhost/vhost.c:2411:42: error: 'idx' undeclared (first use in this function); did you mean 'ida'?
2411 | ring_worker_info.index = idx;
| ^~~
| ida
>> drivers/vhost/vhost.c:2413:60: error: implicit declaration of function 'vhost_get_task'; did you mean 'vhost_get_desc'? [-Wimplicit-function-declaration]
2413 | ring_worker_info.worker_pid = task_pid_vnr(vhost_get_task(worker->vtsk));
| ^~~~~~~~~~~~~~
| vhost_get_desc
vim +/worker +2403 drivers/vhost/vhost.c
2352
2353 /* You must be the owner to do anything else */
2354 r = vhost_dev_check_owner(d);
2355 if (r)
2356 goto done;
2357
2358 switch (ioctl) {
2359 case VHOST_SET_MEM_TABLE:
2360 r = vhost_set_memory(d, argp);
2361 break;
2362 case VHOST_SET_LOG_BASE:
2363 if (copy_from_user(&p, argp, sizeof p)) {
2364 r = -EFAULT;
2365 break;
2366 }
2367 if ((u64)(unsigned long)p != p) {
2368 r = -EFAULT;
2369 break;
2370 }
2371 for (i = 0; i < d->nvqs; ++i) {
2372 struct vhost_virtqueue *vq;
2373 void __user *base = (void __user *)(unsigned long)p;
2374 vq = d->vqs[i];
2375 mutex_lock(&vq->mutex);
2376 /* If ring is inactive, will check when it's enabled. */
2377 if (vq->private_data && !vq_log_access_ok(vq, base))
2378 r = -EFAULT;
2379 else
2380 vq->log_base = base;
2381 mutex_unlock(&vq->mutex);
2382 }
2383 break;
2384 case VHOST_SET_LOG_FD:
2385 r = get_user(fd, (int __user *)argp);
2386 if (r < 0)
2387 break;
2388 ctx = fd == VHOST_FILE_UNBIND ? NULL : eventfd_ctx_fdget(fd);
2389 if (IS_ERR(ctx)) {
2390 r = PTR_ERR(ctx);
2391 break;
2392 }
2393 swap(ctx, d->log_ctx);
2394 for (i = 0; i < d->nvqs; ++i) {
2395 mutex_lock(&d->vqs[i]->mutex);
2396 d->vqs[i]->log_ctx = d->log_ctx;
2397 mutex_unlock(&d->vqs[i]->mutex);
2398 }
2399 if (ctx)
2400 eventfd_ctx_put(ctx);
2401 break;
2402 case VHOST_GET_VRING_WORKER_INFO:
> 2403 worker = rcu_dereference_check(vq->worker,
> 2404 lockdep_is_held(&dev->mutex));
2405 if (!worker) {
> 2406 ret = -EINVAL;
2407 break;
2408 }
2409
> 2410 memset(&ring_worker_info, 0, sizeof(ring_worker_info));
> 2411 ring_worker_info.index = idx;
2412 ring_worker_info.worker_id = worker->id;
> 2413 ring_worker_info.worker_pid = task_pid_vnr(vhost_get_task(worker->vtsk));
2414
2415 if (copy_to_user(argp, &ring_worker_info, sizeof(ring_worker_info)))
2416 ret = -EFAULT;
2417 break;
2418 default:
2419 r = -ENOIOCTLCMD;
2420 break;
2421 }
2422 done:
2423 return r;
2424 }
2425 EXPORT_SYMBOL_GPL(vhost_dev_ioctl);
2426
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] vhost: add a new ioctl VHOST_GET_VRING_WORKER_INFO and use in net.c
2025-10-27 10:26 [PATCH] vhost: add a new ioctl VHOST_GET_VRING_WORKER_INFO and use in net.c Nick Hudson
2025-10-27 22:17 ` kernel test robot
2025-10-27 22:27 ` kernel test robot
@ 2025-10-28 0:42 ` Jason Wang
2025-10-28 7:13 ` Hudson, Nick
2 siblings, 1 reply; 5+ messages in thread
From: Jason Wang @ 2025-10-28 0:42 UTC (permalink / raw)
To: Nick Hudson
Cc: Michael S. Tsirkin, Eugenio Pérez, Max Tottenham, kvm,
virtualization, netdev, linux-kernel
On Mon, Oct 27, 2025 at 6:27 PM Nick Hudson <nhudson@akamai.com> wrote:
>
> The vhost_net (and vhost_sock) drivers create worker tasks to handle
> the virtual queues. Provide a new ioctl VHOST_GET_VRING_WORKER_INFO that
> can be used to determine the PID of these tasks so that, for example,
> they can be pinned to specific CPU(s).
>
> Signed-off-by: Nick Hudson <nhudson@akamai.com>
> Reviewed-by: Max Tottenham <mtottenh@akamai.com>
> ---
> drivers/vhost/net.c | 5 +++++
> drivers/vhost/vhost.c | 16 ++++++++++++++++
> include/uapi/linux/vhost.h | 3 +++
> include/uapi/linux/vhost_types.h | 13 +++++++++++++
> kernel/vhost_task.c | 12 ++++++++++++
> 5 files changed, 49 insertions(+)
>
> diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
> index 35ded4330431..e86bd5d7d202 100644
> --- a/drivers/vhost/net.c
> +++ b/drivers/vhost/net.c
> @@ -1804,6 +1804,11 @@ static long vhost_net_ioctl(struct file *f, unsigned int ioctl,
> return vhost_net_reset_owner(n);
> case VHOST_SET_OWNER:
> return vhost_net_set_owner(n);
> + case VHOST_GET_VRING_WORKER_INFO:
> + mutex_lock(&n->dev.mutex);
> + r = vhost_worker_ioctl(&n->dev, ioctl, argp);
> + mutex_unlock(&n->dev.mutex);
> + return r;
> default:
> mutex_lock(&n->dev.mutex);
> r = vhost_dev_ioctl(&n->dev, ioctl, argp);
> diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
> index 8570fdf2e14a..8b52fd5723c3 100644
> --- a/drivers/vhost/vhost.c
> +++ b/drivers/vhost/vhost.c
> @@ -2399,6 +2399,22 @@ long vhost_dev_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *argp)
> if (ctx)
> eventfd_ctx_put(ctx);
> break;
> + case VHOST_GET_VRING_WORKER_INFO:
> + worker = rcu_dereference_check(vq->worker,
> + lockdep_is_held(&dev->mutex));
> + if (!worker) {
> + ret = -EINVAL;
> + break;
> + }
> +
> + memset(&ring_worker_info, 0, sizeof(ring_worker_info));
> + ring_worker_info.index = idx;
> + ring_worker_info.worker_id = worker->id;
> + ring_worker_info.worker_pid = task_pid_vnr(vhost_get_task(worker->vtsk));
> +
> + if (copy_to_user(argp, &ring_worker_info, sizeof(ring_worker_info)))
> + ret = -EFAULT;
> + break;
> default:
> r = -ENOIOCTLCMD;
> break;
> diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h
> index c57674a6aa0d..c32aa8c71952 100644
> --- a/include/uapi/linux/vhost.h
> +++ b/include/uapi/linux/vhost.h
> @@ -101,6 +101,9 @@
> /* Return the vring worker's ID */
> #define VHOST_GET_VRING_WORKER _IOWR(VHOST_VIRTIO, 0x16, \
> struct vhost_vring_worker)
> +/* Return the vring worker's ID and PID */
> +#define VHOST_GET_VRING_WORKER_INFO _IOWR(VHOST_VIRTIO, 0x17, \
> + struct vhost_vring_worker_info)
>
> /* The following ioctls use eventfd file descriptors to signal and poll
> * for events. */
> diff --git a/include/uapi/linux/vhost_types.h b/include/uapi/linux/vhost_types.h
> index 1c39cc5f5a31..28e00f8ade85 100644
> --- a/include/uapi/linux/vhost_types.h
> +++ b/include/uapi/linux/vhost_types.h
> @@ -63,6 +63,19 @@ struct vhost_vring_worker {
> unsigned int worker_id;
> };
>
> +/* Per-virtqueue worker mapping entry */
> +struct vhost_vring_worker_info {
> + /* vring index */
> + unsigned int index;
> + /*
> + * The id of the vhost_worker returned from VHOST_NEW_WORKER or
> + * allocated as part of vhost_dev_set_owner.
> + */
> + unsigned int worker_id;
I'm not sure the above two are a must and exposing internal workd_id
seems not like a good idea.
> +
> + __kernel_pid_t worker_pid; /* PID/TID of worker thread, -1 if none */
Instead of exposing the worker PID, I wonder if it's simple to just
having a better naming of the worker instead of a simple:
snprintf(name, sizeof(name), "vhost-%d", current->pid);
> +};
> +
> /* no alignment requirement */
> struct vhost_iotlb_msg {
> __u64 iova;
> diff --git a/kernel/vhost_task.c b/kernel/vhost_task.c
> index 27107dcc1cbf..aa87a7f0c98a 100644
> --- a/kernel/vhost_task.c
> +++ b/kernel/vhost_task.c
> @@ -67,6 +67,18 @@ static int vhost_task_fn(void *data)
> do_exit(0);
> }
>
> +/**
> + * vhost_get_task - get a pointer to the vhost_task's task_struct
> + * @vtsk: vhost_task to return the task for
> + *
> + * return the vhost_task's task.
> + */
> +struct task_struct *vhost_get_task(struct vhost_task *vtsk)
> +{
> + return vtsk->task;
> +}
> +EXPORT_SYMBOL_GPL(vhost_get_task);
> +
> /**
> * vhost_task_wake - wakeup the vhost_task
> * @vtsk: vhost_task to wake
> --
> 2.34.1
>
Thanks
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] vhost: add a new ioctl VHOST_GET_VRING_WORKER_INFO and use in net.c
2025-10-28 0:42 ` Jason Wang
@ 2025-10-28 7:13 ` Hudson, Nick
0 siblings, 0 replies; 5+ messages in thread
From: Hudson, Nick @ 2025-10-28 7:13 UTC (permalink / raw)
To: Jason Wang
Cc: Michael S. Tsirkin, Eugenio Pérez, Tottenham, Max,
kvm@vger.kernel.org, virtualization@lists.linux.dev,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
[-- Attachment #1: Type: text/plain, Size: 5178 bytes --]
> On 28 Oct 2025, at 00:42, Jason Wang <jasowang@redhat.com> wrote:
>
> !-------------------------------------------------------------------|
> This Message Is From an External Sender
> This message came from outside your organization.
> |-------------------------------------------------------------------!
>
> On Mon, Oct 27, 2025 at 6:27 PM Nick Hudson <nhudson@akamai.com> wrote:
>>
>> The vhost_net (and vhost_sock) drivers create worker tasks to handle
>> the virtual queues. Provide a new ioctl VHOST_GET_VRING_WORKER_INFO that
>> can be used to determine the PID of these tasks so that, for example,
>> they can be pinned to specific CPU(s).
>>
>> Signed-off-by: Nick Hudson <nhudson@akamai.com>
>> Reviewed-by: Max Tottenham <mtottenh@akamai.com>
>> ---
>> drivers/vhost/net.c | 5 +++++
>> drivers/vhost/vhost.c | 16 ++++++++++++++++
>> include/uapi/linux/vhost.h | 3 +++
>> include/uapi/linux/vhost_types.h | 13 +++++++++++++
>> kernel/vhost_task.c | 12 ++++++++++++
>> 5 files changed, 49 insertions(+)
>>
>> diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
>> index 35ded4330431..e86bd5d7d202 100644
>> --- a/drivers/vhost/net.c
>> +++ b/drivers/vhost/net.c
>> @@ -1804,6 +1804,11 @@ static long vhost_net_ioctl(struct file *f, unsigned int ioctl,
>> return vhost_net_reset_owner(n);
>> case VHOST_SET_OWNER:
>> return vhost_net_set_owner(n);
>> + case VHOST_GET_VRING_WORKER_INFO:
>> + mutex_lock(&n->dev.mutex);
>> + r = vhost_worker_ioctl(&n->dev, ioctl, argp);
>> + mutex_unlock(&n->dev.mutex);
>> + return r;
>> default:
>> mutex_lock(&n->dev.mutex);
>> r = vhost_dev_ioctl(&n->dev, ioctl, argp);
>> diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
>> index 8570fdf2e14a..8b52fd5723c3 100644
>> --- a/drivers/vhost/vhost.c
>> +++ b/drivers/vhost/vhost.c
>> @@ -2399,6 +2399,22 @@ long vhost_dev_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *argp)
>> if (ctx)
>> eventfd_ctx_put(ctx);
>> break;
>> + case VHOST_GET_VRING_WORKER_INFO:
>> + worker = rcu_dereference_check(vq->worker,
>> + lockdep_is_held(&dev->mutex));
>> + if (!worker) {
>> + ret = -EINVAL;
>> + break;
>> + }
>> +
>> + memset(&ring_worker_info, 0, sizeof(ring_worker_info));
>> + ring_worker_info.index = idx;
>> + ring_worker_info.worker_id = worker->id;
>> + ring_worker_info.worker_pid = task_pid_vnr(vhost_get_task(worker->vtsk));
>> +
>> + if (copy_to_user(argp, &ring_worker_info, sizeof(ring_worker_info)))
>> + ret = -EFAULT;
>> + break;
>> default:
>> r = -ENOIOCTLCMD;
>> break;
>> diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h
>> index c57674a6aa0d..c32aa8c71952 100644
>> --- a/include/uapi/linux/vhost.h
>> +++ b/include/uapi/linux/vhost.h
>> @@ -101,6 +101,9 @@
>> /* Return the vring worker's ID */
>> #define VHOST_GET_VRING_WORKER _IOWR(VHOST_VIRTIO, 0x16, \
>> struct vhost_vring_worker)
>> +/* Return the vring worker's ID and PID */
>> +#define VHOST_GET_VRING_WORKER_INFO _IOWR(VHOST_VIRTIO, 0x17, \
>> + struct vhost_vring_worker_info)
>>
>> /* The following ioctls use eventfd file descriptors to signal and poll
>> * for events. */
>> diff --git a/include/uapi/linux/vhost_types.h b/include/uapi/linux/vhost_types.h
>> index 1c39cc5f5a31..28e00f8ade85 100644
>> --- a/include/uapi/linux/vhost_types.h
>> +++ b/include/uapi/linux/vhost_types.h
>> @@ -63,6 +63,19 @@ struct vhost_vring_worker {
>> unsigned int worker_id;
>> };
>>
>> +/* Per-virtqueue worker mapping entry */
>> +struct vhost_vring_worker_info {
>> + /* vring index */
>> + unsigned int index;
>> + /*
>> + * The id of the vhost_worker returned from VHOST_NEW_WORKER or
>> + * allocated as part of vhost_dev_set_owner.
>> + */
>> + unsigned int worker_id;
>
> I'm not sure the above two are a must and exposing internal workd_id
> seems not like a good idea.
It’s already exposed by VHOST_NEW_WORKER, but happy to drop it if you prefer.
>
>> +
>> + __kernel_pid_t worker_pid; /* PID/TID of worker thread, -1 if none */
>
> Instead of exposing the worker PID, I wonder if it's simple to just
> having a better naming of the worker instead of a simple:
>
> snprintf(name, sizeof(name), "vhost-%d", current->pid);
This is currently the case
drivers/vhost/vhost.c: snprintf(name, sizeof(name), "vhost-%d", current->pid);
I was hoping to add the IOCTL, use in qemu, and expose it via QMP/HMP. I have changes to qemu that do this.
Thanks,
Nick
[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 3067 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-10-28 7:14 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-27 10:26 [PATCH] vhost: add a new ioctl VHOST_GET_VRING_WORKER_INFO and use in net.c Nick Hudson
2025-10-27 22:17 ` kernel test robot
2025-10-27 22:27 ` kernel test robot
2025-10-28 0:42 ` Jason Wang
2025-10-28 7:13 ` Hudson, Nick
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).