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

[UNIKRAFT PATCH v5 07/10] plat/xen/drivers/net: Enable/disable interrupts for rx queues



The user can enable/disable interrupts for devices according with the operation
mode he or she chooses for the device. This patch follows closely the logic
implemented in the virtio net driver.

Signed-off-by: Costin Lupu <costin.lupu@xxxxxxxxx>
Signed-off-by: Razvan Cojocaru <razvan.cojocaru93@xxxxxxxxx>
Reviewed-by: Sharan Santhanam <sharan.santhanam@xxxxxxxxx>
---
 plat/xen/drivers/net/netfront.c | 67 +++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/plat/xen/drivers/net/netfront.c b/plat/xen/drivers/net/netfront.c
index bb52d4a3..7d1cb16e 100644
--- a/plat/xen/drivers/net/netfront.c
+++ b/plat/xen/drivers/net/netfront.c
@@ -46,6 +46,12 @@
 
 #define DRIVER_NAME  "xen-netfront"
 
+/* TODO Same interrupt macros we use in virtio-net */
+#define NETFRONT_INTR_EN             (1 << 0)
+#define NETFRONT_INTR_EN_MASK        (1)
+#define NETFRONT_INTR_USR_EN         (1 << 1)
+#define NETFRONT_INTR_USR_EN_MASK    (2)
+
 #define to_netfront_dev(dev) \
        __containerof(dev, struct netfront_dev, netdev)
 
@@ -148,6 +154,22 @@ out:
        return status;
 }
 
+/* Returns 1 if more packets available */
+static int netfront_rxq_intr_enable(struct uk_netdev_rx_queue *rxq)
+{
+       int more;
+
+       /* Check if there are no more packets enabled */
+       RING_FINAL_CHECK_FOR_RESPONSES(&rxq->ring, more);
+       if (!more) {
+               /* No more packets, we can enable interrupts */
+               rxq->intr_enabled |= NETFRONT_INTR_EN;
+               unmask_evtchn(rxq->evtchn);
+       }
+
+       return (more > 0);
+}
+
 static struct uk_netdev_tx_queue *netfront_txq_setup(struct uk_netdev *n,
                uint16_t queue_id,
                uint16_t nb_desc __unused,
@@ -219,6 +241,10 @@ static void netfront_handler(evtchn_port_t port __unused,
 {
        struct uk_netdev_rx_queue *rxq = arg;
 
+       /* Disable the interrupt for the ring */
+       rxq->intr_enabled &= ~(NETFRONT_INTR_EN);
+       mask_evtchn(rxq->evtchn);
+
        /* Indicate to the network stack about an event */
        uk_netdev_drv_rx_event(&rxq->netfront_dev->netdev, rxq->lqueue_id);
 }
@@ -335,6 +361,45 @@ err_free_txrx:
        return rc;
 }
 
+static int netfront_rx_intr_enable(struct uk_netdev *n,
+               struct uk_netdev_rx_queue *rxq)
+{
+       int rc;
+
+       UK_ASSERT(n != NULL);
+       UK_ASSERT(rxq != NULL);
+       UK_ASSERT(&rxq->netfront_dev->netdev == n);
+
+       /* If the interrupt is enabled */
+       if (rxq->intr_enabled & NETFRONT_INTR_EN)
+               return 0;
+
+       /**
+        * 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.
+        */
+       rxq->intr_enabled = NETFRONT_INTR_USR_EN;
+       rc = netfront_rxq_intr_enable(rxq);
+       if (!rc)
+               rxq->intr_enabled |= NETFRONT_INTR_EN;
+
+       return rc;
+}
+
+static int netfront_rx_intr_disable(struct uk_netdev *n,
+               struct uk_netdev_rx_queue *rxq)
+{
+       UK_ASSERT(n != NULL);
+       UK_ASSERT(rxq != NULL);
+       UK_ASSERT(&rxq->netfront_dev->netdev == n);
+
+       rxq->intr_enabled &= ~(NETFRONT_INTR_USR_EN | NETFRONT_INTR_EN);
+       mask_evtchn(rxq->evtchn);
+
+       return 0;
+}
+
 static int netfront_txq_info_get(struct uk_netdev *n,
                uint16_t queue_id,
                struct uk_netdev_queue_info *qinfo)
@@ -482,6 +547,8 @@ static const struct uk_netdev_ops netfront_ops = {
        .configure = netfront_configure,
        .txq_configure = netfront_txq_setup,
        .rxq_configure = netfront_rxq_setup,
+       .rxq_intr_enable = netfront_rx_intr_enable,
+       .rxq_intr_disable = netfront_rx_intr_disable,
        .txq_info_get = netfront_txq_info_get,
        .rxq_info_get = netfront_rxq_info_get,
        .info_get = netfront_info_get,
-- 
2.20.1




 


Rackspace

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