[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Minios-devel] [UNIKRAFT PATCH v3 08/17] plat/xen/drivers/blk: Configure blkfront queue
Reviewed-by: Costin Lupu <costin.lupu@xxxxxxxxx> On 10/30/19 5:54 PM, Roxana Nicolescu wrote: > Blkfront queues use Xen shared rings. > This patch introduces the allocation and initialization of the shared > ring, and also adds the event-handler for queue notification. > > Signed-off-by: Roxana Nicolescu <nicolescu.roxana1996@xxxxxxxxx> > --- > plat/xen/drivers/blk/blkfront.c | 125 ++++++++++++++++++++++++++++++++ > plat/xen/drivers/blk/blkfront.h | 9 +++ > 2 files changed, 134 insertions(+) > > diff --git a/plat/xen/drivers/blk/blkfront.c b/plat/xen/drivers/blk/blkfront.c > index 58d33ddd..62b14f4c 100644 > --- a/plat/xen/drivers/blk/blkfront.c > +++ b/plat/xen/drivers/blk/blkfront.c > @@ -54,6 +54,128 @@ > > static struct uk_alloc *drv_allocator; > > +static int blkfront_ring_init(struct uk_blkdev_queue *queue) > +{ > + struct blkif_sring *sring = NULL; > + struct blkfront_dev *dev; > + > + UK_ASSERT(queue); > + dev = queue->dev; > + sring = uk_malloc_page(queue->a); > + if (!sring) > + return -ENOMEM; > + > + memset(sring, 0, PAGE_SIZE); > + SHARED_RING_INIT(sring); > + FRONT_RING_INIT(&queue->ring, sring, PAGE_SIZE); > + > + queue->ring_ref = gnttab_grant_access(dev->xendev->otherend_id, > + virt_to_mfn(sring), 0); > + UK_ASSERT(queue->ring_ref != GRANT_INVALID_REF); > + > + return 0; > +} > + > +static void blkfront_ring_fini(struct uk_blkdev_queue *queue) > +{ > + int rc; > + > + if (queue->ring_ref != GRANT_INVALID_REF) { > + rc = gnttab_end_access(queue->ring_ref); > + UK_ASSERT(rc); > + } > + > + if (queue->ring.sring != NULL) > + uk_free_page(queue->a, queue->ring.sring); > +} > + > +/* Handler for event channel notifications */ > +static void blkfront_handler(evtchn_port_t port __unused, > + struct __regs *regs __unused, void *arg) > +{ > + struct uk_blkdev_queue *queue; > + > + UK_ASSERT(arg); > + queue = (struct uk_blkdev_queue *)arg; > + > + uk_blkdev_drv_queue_event(&queue->dev->blkdev, queue->queue_id); > +} > + > +static struct uk_blkdev_queue *blkfront_queue_setup(struct uk_blkdev *blkdev, > + uint16_t queue_id, > + uint16_t nb_desc __unused, > + const struct uk_blkdev_queue_conf *queue_conf) > +{ > + struct blkfront_dev *dev; > + struct uk_blkdev_queue *queue; > + int err = 0; > + > + UK_ASSERT(blkdev != NULL); > + > + dev = to_blkfront(blkdev); > + if (queue_id >= dev->nb_queues) { > + uk_pr_err("Invalid queue identifier: %"__PRIu16"\n", queue_id); > + return ERR2PTR(-EINVAL); > + } > + > + queue = &dev->queues[queue_id]; > + queue->a = queue_conf->a; > + queue->queue_id = queue_id; > + queue->dev = dev; > + err = blkfront_ring_init(queue); > + if (err) { > + uk_pr_err("Failed to init ring: %d.\n", err); > + return ERR2PTR(err); > + } > + > + err = evtchn_alloc_unbound(dev->xendev->otherend_id, > + blkfront_handler, queue, > + &queue->evtchn); > + if (err) { > + uk_pr_err("Failed to create event-channel: %d.\n", err); > + err *= -1; > + goto err_out; > + } > + > + return queue; > + > +err_out: > + blkfront_ring_fini(queue); > + return ERR2PTR(err); > +} > + > +static int blkfront_queue_release(struct uk_blkdev *blkdev, > + struct uk_blkdev_queue *queue) > +{ > + UK_ASSERT(blkdev != NULL); > + UK_ASSERT(queue != NULL); > + > + mask_evtchn(queue->evtchn); > + unbind_evtchn(queue->evtchn); > + blkfront_ring_fini(queue); > + > + return 0; > +} > + > +static int blkfront_queue_get_info(struct uk_blkdev *blkdev, > + uint16_t queue_id, > + struct uk_blkdev_queue_info *qinfo) > +{ > + struct blkfront_dev *dev; > + > + UK_ASSERT(blkdev); > + UK_ASSERT(qinfo); > + > + dev = to_blkfront(blkdev); > + if (queue_id >= dev->nb_queues) { > + uk_pr_err("Invalid queue identifier: %"__PRIu16"\n", queue_id); > + return -EINVAL; > + } > + > + qinfo->nb_is_power_of_two = 1; > + > + return 0; > +} > > static int blkfront_configure(struct uk_blkdev *blkdev, > const struct uk_blkdev_conf *conf) > @@ -113,6 +235,9 @@ static void blkfront_get_info(struct uk_blkdev *blkdev, > static const struct uk_blkdev_ops blkfront_ops = { > .get_info = blkfront_get_info, > .dev_configure = blkfront_configure, > + .queue_get_info = blkfront_queue_get_info, > + .queue_setup = blkfront_queue_setup, > + .queue_release = blkfront_queue_release, > .dev_unconfigure = blkfront_unconfigure, > }; > > diff --git a/plat/xen/drivers/blk/blkfront.h b/plat/xen/drivers/blk/blkfront.h > index 6b7d5cad..a8b0ca85 100644 > --- a/plat/xen/drivers/blk/blkfront.h > +++ b/plat/xen/drivers/blk/blkfront.h > @@ -42,11 +42,20 @@ > * implementation. > */ > #include <uk/blkdev.h> > +#include <xen/io/blkif.h> > +#include <common/gnttab.h> > +#include <common/events.h> > > /* > * Structure used to describe a queue used for both requests and responses > */ > struct uk_blkdev_queue { > + /* Front_ring structure */ > + struct blkif_front_ring ring; > + /* Grant ref pointing at the front ring. */ > + grant_ref_t ring_ref; > + /* Event channel for the front ring. */ > + evtchn_port_t evtchn; > /* Allocator for this queue. */ > struct uk_alloc *a; > /* The libukblkdev queue identifier */ > _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |