virtualization.lists.linux-foundation.org archive mirror
 help / color / mirror / Atom feed
* [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).