[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210223115048.435-11-xieyongji@bytedance.com>
Date: Tue, 23 Feb 2021 19:50:47 +0800
From: Xie Yongji <xieyongji@...edance.com>
To: mst@...hat.com, jasowang@...hat.com, stefanha@...hat.com,
sgarzare@...hat.com, parav@...dia.com, bob.liu@...cle.com,
hch@...radead.org, rdunlap@...radead.org, willy@...radead.org,
viro@...iv.linux.org.uk, axboe@...nel.dk, bcrl@...ck.org,
corbet@....net
Cc: virtualization@...ts.linux-foundation.org, netdev@...r.kernel.org,
kvm@...r.kernel.org, linux-aio@...ck.org,
linux-fsdevel@...r.kernel.org
Subject: [RFC v4 10/11] vduse: Introduce a workqueue for irq injection
This patch introduces a workqueue to support injecting
virtqueue's interrupt asynchronously. This is mainly
for performance considerations which makes sure the push()
and pop() for used vring can be asynchronous.
Signed-off-by: Xie Yongji <xieyongji@...edance.com>
---
drivers/vdpa/vdpa_user/vduse_dev.c | 29 +++++++++++++++++++++++------
1 file changed, 23 insertions(+), 6 deletions(-)
diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vduse_dev.c
index 8042d3fa57f1..f5adeb9ee027 100644
--- a/drivers/vdpa/vdpa_user/vduse_dev.c
+++ b/drivers/vdpa/vdpa_user/vduse_dev.c
@@ -42,6 +42,7 @@ struct vduse_virtqueue {
spinlock_t irq_lock;
struct eventfd_ctx *kickfd;
struct vdpa_callback cb;
+ struct work_struct inject;
};
struct vduse_dev;
@@ -99,6 +100,7 @@ static DEFINE_IDA(vduse_ida);
static dev_t vduse_major;
static struct class *vduse_class;
+static struct workqueue_struct *vduse_irq_wq;
static inline struct vduse_dev *vdpa_to_vduse(struct vdpa_device *vdpa)
{
@@ -852,6 +854,17 @@ static int vduse_kickfd_setup(struct vduse_dev *dev,
return 0;
}
+static void vduse_vq_irq_inject(struct work_struct *work)
+{
+ struct vduse_virtqueue *vq = container_of(work,
+ struct vduse_virtqueue, inject);
+
+ spin_lock_irq(&vq->irq_lock);
+ if (vq->ready && vq->cb.callback)
+ vq->cb.callback(vq->cb.private);
+ spin_unlock_irq(&vq->irq_lock);
+}
+
static long vduse_dev_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
@@ -917,12 +930,7 @@ static long vduse_dev_ioctl(struct file *file, unsigned int cmd,
break;
vq = &dev->vqs[arg];
- spin_lock_irq(&vq->irq_lock);
- if (vq->ready && vq->cb.callback) {
- vq->cb.callback(vq->cb.private);
- ret = 0;
- }
- spin_unlock_irq(&vq->irq_lock);
+ queue_work(vduse_irq_wq, &vq->inject);
break;
}
case VDUSE_INJECT_CONFIG_IRQ:
@@ -1109,6 +1117,7 @@ static int vduse_create_dev(struct vduse_dev_config *config)
for (i = 0; i < dev->vq_num; i++) {
dev->vqs[i].index = i;
+ INIT_WORK(&dev->vqs[i].inject, vduse_vq_irq_inject);
spin_lock_init(&dev->vqs[i].kick_lock);
spin_lock_init(&dev->vqs[i].irq_lock);
}
@@ -1333,6 +1342,11 @@ static int vduse_init(void)
if (ret)
goto err_chardev;
+ vduse_irq_wq = alloc_workqueue("vduse-irq",
+ WQ_HIGHPRI | WQ_SYSFS | WQ_UNBOUND, 0);
+ if (!vduse_irq_wq)
+ goto err_wq;
+
ret = vduse_domain_init();
if (ret)
goto err_domain;
@@ -1344,6 +1358,8 @@ static int vduse_init(void)
return 0;
err_mgmtdev:
vduse_domain_exit();
+err_wq:
+ destroy_workqueue(vduse_irq_wq);
err_domain:
unregister_chrdev_region(vduse_major, VDUSE_DEV_MAX);
err_chardev:
@@ -1359,6 +1375,7 @@ static void vduse_exit(void)
misc_deregister(&vduse_misc);
class_destroy(vduse_class);
unregister_chrdev_region(vduse_major, VDUSE_DEV_MAX);
+ destroy_workqueue(vduse_irq_wq);
vduse_domain_exit();
vduse_mgmtdev_exit();
}
--
2.11.0
Powered by blists - more mailing lists