[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

 


Rackspace

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