[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 |