Add a parameter for the ioctl VDUSE_INJECT_VQ_IRQ to support
injecting virtqueue's interrupt to the specified cpu.

Signed-off-by: Xie Yongji <xieyon...@bytedance.com>
---
 drivers/vdpa/vdpa_user/vduse_dev.c | 22 +++++++++++++++++-----
 include/uapi/linux/vduse.h         |  7 ++++++-
 2 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c 
b/drivers/vdpa/vdpa_user/vduse_dev.c
index f5adeb9ee027..df3d467fff40 100644
--- a/drivers/vdpa/vdpa_user/vduse_dev.c
+++ b/drivers/vdpa/vdpa_user/vduse_dev.c
@@ -923,14 +923,27 @@ static long vduse_dev_ioctl(struct file *file, unsigned 
int cmd,
                break;
        }
        case VDUSE_INJECT_VQ_IRQ: {
+               struct vduse_vq_irq irq;
                struct vduse_virtqueue *vq;
 
+               ret = -EFAULT;
+               if (copy_from_user(&irq, argp, sizeof(irq)))
+                       break;
+
                ret = -EINVAL;
-               if (arg >= dev->vq_num)
+               if (irq.index >= dev->vq_num)
+                       break;
+
+               if (irq.cpu != -1 && (irq.cpu >= nr_cpu_ids ||
+                   !cpu_online(irq.cpu)))
                        break;
 
-               vq = &dev->vqs[arg];
-               queue_work(vduse_irq_wq, &vq->inject);
+               ret = 0;
+               vq = &dev->vqs[irq.index];
+               if (irq.cpu == -1)
+                       queue_work(vduse_irq_wq, &vq->inject);
+               else
+                       queue_work_on(irq.cpu, vduse_irq_wq, &vq->inject);
                break;
        }
        case VDUSE_INJECT_CONFIG_IRQ:
@@ -1342,8 +1355,7 @@ static int vduse_init(void)
        if (ret)
                goto err_chardev;
 
-       vduse_irq_wq = alloc_workqueue("vduse-irq",
-                               WQ_HIGHPRI | WQ_SYSFS | WQ_UNBOUND, 0);
+       vduse_irq_wq = alloc_workqueue("vduse-irq", WQ_HIGHPRI, 0);
        if (!vduse_irq_wq)
                goto err_wq;
 
diff --git a/include/uapi/linux/vduse.h b/include/uapi/linux/vduse.h
index 9070cd512cb4..9c70fd842ce5 100644
--- a/include/uapi/linux/vduse.h
+++ b/include/uapi/linux/vduse.h
@@ -116,6 +116,11 @@ struct vduse_vq_eventfd {
        int fd; /* eventfd, -1 means de-assigning the eventfd */
 };
 
+struct vduse_vq_irq {
+       __u32 index; /* virtqueue index */
+       int cpu; /* bind irq to the specified cpu, -1 means running on the 
current cpu */
+};
+
 #define VDUSE_BASE     0x81
 
 /* Create a vduse device which is represented by a char device 
(/dev/vduse/<name>) */
@@ -131,7 +136,7 @@ struct vduse_vq_eventfd {
 #define VDUSE_VQ_SETUP_KICKFD  _IOW(VDUSE_BASE, 0x04, struct vduse_vq_eventfd)
 
 /* Inject an interrupt for specific virtqueue */
-#define VDUSE_INJECT_VQ_IRQ    _IO(VDUSE_BASE, 0x05)
+#define VDUSE_INJECT_VQ_IRQ    _IOW(VDUSE_BASE, 0x05, struct vduse_vq_irq)
 
 /* Inject a config interrupt */
 #define VDUSE_INJECT_CONFIG_IRQ        _IO(VDUSE_BASE, 0x06)
-- 
2.11.0

Reply via email to