|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH 09/17] plat/xen/drivers/blk: Enable/disable interrupts for queues
This patch introduces support for the user to enable/disable interrupts
on queues.
Signed-off-by: Roxana Nicolescu <nicolescu.roxana1996@xxxxxxxxx>
---
plat/xen/drivers/blk/blkfront.c | 83 +++++++++++++++++++++++++++++++++++++++++
plat/xen/drivers/blk/blkfront.h | 2 +
2 files changed, 85 insertions(+)
diff --git a/plat/xen/drivers/blk/blkfront.c b/plat/xen/drivers/blk/blkfront.c
index 9ccd2113..c65267f0 100644
--- a/plat/xen/drivers/blk/blkfront.c
+++ b/plat/xen/drivers/blk/blkfront.c
@@ -41,12 +41,19 @@
#include <uk/essentials.h>
#include <uk/arch/limits.h>
#include <uk/blkdev_driver.h>
+#include <xen-x86/mm.h>
+#include <xen-x86/mm_pv.h>
#include <xenbus/xenbus.h>
#include "blkfront.h"
#include "blkfront_xb.h"
#define DRIVER_NAME "xen-blkfront"
+/* TODO Same interrupt macros we use in virtio-blk */
+#define BLKFRONT_INTR_EN (1 << 0)
+#define BLKFRONT_INTR_EN_MASK (1)
+#define BLKFRONT_INTR_USR_EN (1 << 1)
+#define BLKFRONT_INTR_USR_EN_MASK (2)
/* Get blkfront_dev* which contains blkdev */
#define to_blkfront(blkdev) \
@@ -55,6 +62,22 @@
static struct uk_alloc *drv_allocator;
+/* Returns 1 if more responses available */
+static int blkfront_xen_ring_intr_enable(struct uk_blkdev_queue *queue)
+{
+ int more;
+
+ /* Check if there are no more responses enabled */
+ RING_FINAL_CHECK_FOR_RESPONSES(&queue->ring, more);
+ if (!more) {
+ /* No more responses, we can enable interrupts */
+ queue->intr_enabled |= BLKFRONT_INTR_EN;
+ unmask_evtchn(queue->evtchn);
+ }
+
+ return (more > 0);
+}
+
static int blkfront_ring_init(struct uk_blkdev_queue *queue)
{
struct blkif_sring *sring = NULL;
@@ -98,6 +121,11 @@ static void blkfront_handler(evtchn_port_t port __unused,
UK_ASSERT(arg);
queue = (struct uk_blkdev_queue *)arg;
+
+ /* Disable the interrupt for the ring */
+ queue->intr_enabled &= ~(BLKFRONT_INTR_EN);
+ mask_evtchn(queue->evtchn);
+
uk_blkdev_drv_queue_event(&queue->dev->blkdev, queue->queue_id);
}
@@ -122,6 +150,7 @@ static struct uk_blkdev_queue *blkfront_queue_setup(struct
uk_blkdev *blkdev,
queue->a = queue_conf->a;
queue->queue_id = queue_id;
queue->dev = dev;
+ queue->intr_enabled = 0;
err = blkfront_ring_init(queue);
if (err) {
uk_pr_err("Failed to init ring: %d.\n", err);
@@ -164,6 +193,58 @@ static int blkfront_queue_release(struct uk_blkdev *blkdev,
unbind_evtchn(queue->evtchn);
blkfront_ring_fini(queue);
+
+static int blkfront_queue_intr_enable(struct uk_blkdev *blkdev,
+ uint16_t queue_id)
+{
+ struct blkfront_dev *dev;
+ struct uk_blkdev_queue *queue;
+ int rc = 0;
+
+ UK_ASSERT(blkdev);
+ dev = to_blkfront(blkdev);
+ if (queue_id >= dev->nb_queues) {
+ uk_pr_err("Invalid queue identifier: %"__PRIu16"\n", queue_id);
+ return -EINVAL;
+ }
+
+ queue = &dev->queues[queue_id];
+ /* If the interrupt is enabled */
+ if (queue->intr_enabled & BLKFRONT_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.
+ */
+ queue->intr_enabled = BLKFRONT_INTR_USR_EN;
+ rc = blkfront_xen_ring_intr_enable(queue);
+ if (!rc)
+ queue->intr_enabled |= BLKFRONT_INTR_EN;
+
+ return rc;
+}
+
+static int blkfront_queue_intr_disable(struct uk_blkdev *blkdev,
+ uint16_t queue_id)
+{
+ struct blkfront_dev *dev;
+ struct uk_blkdev_queue *queue;
+
+ UK_ASSERT(blkdev);
+
+ dev = to_blkfront(blkdev);
+ if (queue_id >= dev->nb_queues) {
+ uk_pr_err("Invalid queue identifier: %"__PRIu16"\n", queue_id);
+ return -EINVAL;
+ }
+
+ queue = &dev->queues[queue_id];
+
+ queue->intr_enabled &= ~(BLKFRONT_INTR_USR_EN | BLKFRONT_INTR_EN);
+ mask_evtchn(queue->evtchn);
+
return 0;
}
@@ -255,6 +336,8 @@ static const struct uk_blkdev_ops blkfront_ops = {
.queue_setup = blkfront_queue_setup,
.queue_release = blkfront_queue_release,
.dev_close = blkfront_close,
+ .queue_intr_enable = blkfront_queue_intr_enable,
+ .queue_intr_disable = blkfront_queue_intr_disable,
};
/**
diff --git a/plat/xen/drivers/blk/blkfront.h b/plat/xen/drivers/blk/blkfront.h
index 656f7845..bf6d231e 100644
--- a/plat/xen/drivers/blk/blkfront.h
+++ b/plat/xen/drivers/blk/blkfront.h
@@ -62,6 +62,8 @@ struct uk_blkdev_queue {
struct uk_alloc *a;
/* The libukblkdev queue identifier */
uint16_t queue_id;
+ /* The flag to interrupt on the queue */
+ int intr_enabled;
/* Reference to the Blkfront Device */
struct blkfront_dev *dev;
};
--
2.11.0
_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |