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 <xieyongji@xxxxxxxxxxxxx> --- 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