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

[Minios-devel] [UNIKRAFT PATCH 10/10] plat/xen/drivers/cons: Introduce Consfront Interrupt Handling



The current changes form interrupt handling for consfront.
Interrupt design is similar to virtio-net:
        Keeps track if the user has enabled intr.
        Enables only when rx is empty.
        Read can not be called when intr are enabled.

Signed-off-by: Birlea Costin <costin.birlea@xxxxxxxxx>
---
 plat/xen/drivers/cons/consfront.c | 61 +++++++++++++++++++++++++++++++++++++++
 plat/xen/drivers/cons/consfront.h |  2 ++
 2 files changed, 63 insertions(+)

diff --git a/plat/xen/drivers/cons/consfront.c 
b/plat/xen/drivers/cons/consfront.c
index 6dd8a6f8..df233ea5 100644
--- a/plat/xen/drivers/cons/consfront.c
+++ b/plat/xen/drivers/cons/consfront.c
@@ -54,6 +54,12 @@
 #define XEN_CONSFRONT_SIZE_IN 1024
 #define XEN_CONSFRONT_SIZE_OUT 2048
 
+/* TODO Same interrupt macros we use in virtio-cons */
+#define CONSFRONT_INTR_EN             (1 << 0)
+#define CONSFRONT_INTR_EN_MASK        (1)
+#define CONSFRONT_INTR_USR_EN         (1 << 1)
+#define CONSFRONT_INTR_USR_EN_MASK    (2)
+
 /* Get consfront_dev* which contains consdev */
 #define to_consfront(dev) \
                __containerof(dev, struct consfront_dev, consdev)
@@ -70,6 +76,7 @@ static void consfront_rx_handler(evtchn_port_t port __unused,
        cfdev = to_consfront(dev);
        UK_ASSERT(cfdev);
 
+       cfdev->intr_enabled &= ~(CONSFRONT_INTR_EN);
        mask_evtchn(cfdev->evtchn);
 
        uk_consdev_drv_rx_event(dev);
@@ -167,6 +174,7 @@ static int consfront_rx_configure(struct uk_consdev *dev,
 
        /* Start with interrupts disabled, API user should enable them */
        mask_evtchn(cfdev->evtchn);
+       cfdev->intr_enabled = 0;
 
        return rc;
 }
@@ -252,6 +260,54 @@ static int consfront_stop(struct uk_consdev *dev)
        return 0;
 }
 
+static int consfront_rx_intr_enable(struct uk_consdev *dev)
+{
+       struct xencons_interface *intf;
+       struct consfront_dev *cfdev;
+
+       UK_ASSERT(dev);
+
+       cfdev = to_consfront(dev);
+       UK_ASSERT(cfdev);
+
+       /* If the interrupt is enabled */
+       if (cfdev->intr_enabled & CONSFRONT_INTR_EN)
+               return 0;
+
+       intf = cfdev->ring;
+       UK_ASSERT(intf);
+
+       /**
+        * Enable the user configuration bit. This would cause the interrupt to
+        * be enabled automatically if the interrupt could not be enabled now
+        * due to data in the queue.
+        */
+       cfdev->intr_enabled = CONSFRONT_INTR_USR_EN;
+
+       /* Enable only if rx is empty */
+       if (intf->in_cons == intf->in_prod) {
+               cfdev->intr_enabled |= CONSFRONT_INTR_EN;
+               unmask_evtchn(cfdev->evtchn);
+       }
+
+       return 0;
+}
+
+static int consfront_rx_intr_disable(struct uk_consdev *dev)
+{
+       struct consfront_dev *cfdev;
+
+       UK_ASSERT(dev);
+
+       cfdev = to_consfront(dev);
+       UK_ASSERT(cfdev);
+
+       cfdev->intr_enabled &= ~(CONSFRONT_INTR_USR_EN | CONSFRONT_INTR_EN);
+       mask_evtchn(cfdev->evtchn);
+
+       return 0;
+}
+
 static unsigned int pvconsole_output(struct consfront_dev *dev,
                                char *buf, unsigned int len)
 {
@@ -358,6 +414,9 @@ static unsigned int consfront_read(struct uk_consdev *dev,
        cfdev = to_consfront(dev);
        UK_ASSERT(cfdev);
 
+       /* Queue interrupts have to be off when calling read */
+       UK_ASSERT(!(cfdev->intr_enabled & CONSFRONT_INTR_EN));
+
        intf = cfdev->ring;
        UK_ASSERT(intf);
 
@@ -407,6 +466,8 @@ static const struct uk_consdev_ops consfront_ops = {
        .release = consfront_release,
        .start = consfront_start,
        .stop = consfront_stop,
+       .rx_intr_enable = consfront_rx_intr_enable,
+       .rx_intr_disable = consfront_rx_intr_disable,
        .write = consfront_write,
        .read = consfront_read,
        .close = consfront_close,
diff --git a/plat/xen/drivers/cons/consfront.h 
b/plat/xen/drivers/cons/consfront.h
index 61cb2df4..9360e95f 100644
--- a/plat/xen/drivers/cons/consfront.h
+++ b/plat/xen/drivers/cons/consfront.h
@@ -53,6 +53,8 @@ struct consfront_dev {
        grant_ref_t ring_ref;
        /* Event channel for the front ring. */
        evtchn_port_t evtchn;
+       /* Flag for user interrupt enable */
+       uint8_t intr_enabled;
        /* The consdev identifier */
        __u16 uid;
 };
-- 
2.11.0


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.