Re: [RFC v4 10/11] vduse: Introduce a workqueue for irq injection

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 2021/2/23 7:50 下午, Xie Yongji wrote:
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.


Do you have pref numbers for this patch?

Thanks



Signed-off-by: Xie Yongji <xieyongji@xxxxxxxxxxxxx>
---
  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();
  }




[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux