Re: [PATCH 3/5] VFIO: Support threaded interrupt handling on VFIO

2015-12-16 Thread Alex Williamson
On Thu, 2015-12-03 at 10:22 -0800, Yunhong Jiang wrote:
> For VFIO device with MSI interrupt type, it's possible to handle the
> interrupt on hard interrupt context without invoking the interrupt
> thread. Handling the interrupt on hard interrupt context reduce the
> interrupt latency.
> 
> Signed-off-by: Yunhong Jiang 
> ---
>  drivers/vfio/pci/vfio_pci_intrs.c | 39 
> ++-
>  1 file changed, 34 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/vfio/pci/vfio_pci_intrs.c 
> b/drivers/vfio/pci/vfio_pci_intrs.c
> index 3b3ba15558b7..108d335c5656 100644
> --- a/drivers/vfio/pci/vfio_pci_intrs.c
> +++ b/drivers/vfio/pci/vfio_pci_intrs.c
> @@ -236,12 +236,35 @@ static void vfio_intx_disable(struct vfio_pci_device 
> *vdev)
>   kfree(vdev->ctx);
>  }
>  
> +static irqreturn_t vfio_msihandler(int irq, void *arg)
> +{
> + struct vfio_pci_irq_ctx *ctx = arg;
> + struct irq_bypass_producer *producer = >producer;
> + struct irq_bypass_consumer *consumer;
> + int ret = IRQ_HANDLED, idx;
> +
> + idx = srcu_read_lock(>srcu);
> +
> + list_for_each_entry_rcu(consumer, >consumers, sibling) {
> + /*
> +  * Invoke the thread handler if any consumer would block, but
> +  * finish all consumes.
> +  */
> + if (consumer->handle_irq(consumer->irq_context) == -EWOULDBLOCK)
> + ret = IRQ_WAKE_THREAD;
> + continue;
> + }
> +
> + srcu_read_unlock(>srcu, idx);


There should be an irq bypass manager interface to abstract this.
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/5] VFIO: Support threaded interrupt handling on VFIO

2015-12-03 Thread Yunhong Jiang
For VFIO device with MSI interrupt type, it's possible to handle the
interrupt on hard interrupt context without invoking the interrupt
thread. Handling the interrupt on hard interrupt context reduce the
interrupt latency.

Signed-off-by: Yunhong Jiang 
---
 drivers/vfio/pci/vfio_pci_intrs.c | 39 ++-
 1 file changed, 34 insertions(+), 5 deletions(-)

diff --git a/drivers/vfio/pci/vfio_pci_intrs.c 
b/drivers/vfio/pci/vfio_pci_intrs.c
index 3b3ba15558b7..108d335c5656 100644
--- a/drivers/vfio/pci/vfio_pci_intrs.c
+++ b/drivers/vfio/pci/vfio_pci_intrs.c
@@ -236,12 +236,35 @@ static void vfio_intx_disable(struct vfio_pci_device 
*vdev)
kfree(vdev->ctx);
 }
 
+static irqreturn_t vfio_msihandler(int irq, void *arg)
+{
+   struct vfio_pci_irq_ctx *ctx = arg;
+   struct irq_bypass_producer *producer = >producer;
+   struct irq_bypass_consumer *consumer;
+   int ret = IRQ_HANDLED, idx;
+
+   idx = srcu_read_lock(>srcu);
+
+   list_for_each_entry_rcu(consumer, >consumers, sibling) {
+   /*
+* Invoke the thread handler if any consumer would block, but
+* finish all consumes.
+*/
+   if (consumer->handle_irq(consumer->irq_context) == -EWOULDBLOCK)
+   ret = IRQ_WAKE_THREAD;
+   continue;
+   }
+
+   srcu_read_unlock(>srcu, idx);
+   return ret;
+}
+
 /*
  * MSI/MSI-X
  */
-static irqreturn_t vfio_msihandler(int irq, void *arg)
+static irqreturn_t vfio_msihandler_threaded(int irq, void *arg)
 {
-   struct eventfd_ctx *trigger = arg;
+   struct eventfd_ctx *trigger = ((struct vfio_pci_irq_ctx *)arg)->trigger;
 
eventfd_signal(trigger, 1);
return IRQ_HANDLED;
@@ -318,7 +341,7 @@ static int vfio_msi_set_vector_signal(struct 
vfio_pci_device *vdev,
return -EINVAL;
 
if (vdev->ctx[vector].trigger) {
-   free_irq(irq, vdev->ctx[vector].trigger);
+   free_irq(irq, >ctx[vector]);
irq_bypass_unregister_producer(>ctx[vector].producer);
kfree(vdev->ctx[vector].name);
eventfd_ctx_put(vdev->ctx[vector].trigger);
@@ -353,8 +376,14 @@ static int vfio_msi_set_vector_signal(struct 
vfio_pci_device *vdev,
pci_write_msi_msg(irq, );
}
 
-   ret = request_irq(irq, vfio_msihandler, 0,
- vdev->ctx[vector].name, trigger);
+   /*
+* Currently the primary handler for the thread_irq will be invoked on
+* a thread, the IRQF_ONESHOT is a hack for it.
+*/
+   ret = request_threaded_irq(irq, vfio_msihandler,
+  vfio_msihandler_threaded,
+  IRQF_ONESHOT, vdev->ctx[vector].name,
+  >ctx[vector]);
if (ret) {
kfree(vdev->ctx[vector].name);
eventfd_ctx_put(trigger);
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html