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

Re: [Minios-devel] [UNIKRAFT PATCH v2 06/12] plat/drivers: Configure virtio block queue


  • To: Roxana Nicolescu <nicolescu.roxana1996@xxxxxxxxx>, "minios-devel@xxxxxxxxxxxxx" <minios-devel@xxxxxxxxxxxxx>
  • From: "Justin He (Arm Technology China)" <Justin.He@xxxxxxx>
  • Date: Tue, 26 Nov 2019 06:32:28 +0000
  • Accept-language: en-US, zh-CN
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=KQpGR0nHYavHb+I86KTr75m2LEff8APzIQsUiLfREM0=; b=JUggrFFKMxpNTm9WZFwQtWduhjwLUfrSMoXy9uhhbcEveQFm6B8p3J4cFNQCJICQ6oT5aqYF5gq6LwtLWq26o8kH4COzKOsbcYOs7E9KMzikrJBTsSDxa4dGyWopSvE02aXlc3c9lOzElVhrrqx7ItsaBpJXTx4kmcYW4FvauZMwCMutCnj+V/JPNH6Ou2B2efk2aDhnNFkLEwN35nkh1C5UOA0IFu8Ebep7l0uLCPW0cnBvWcSaWXEQTg7HK5kAxeVBnUjVHQZjslqcrU27NbVRsGEwdWq/ta2Arxi5IDobeYvRF4IkTGX9QWt20B5OWT6i6FliCW74IMMH9C7grA==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=aPy70K1Y/sI1G5dnQ+/0/9uh2LOGEigeYlYLSIEwazGLBGPOXjBIDcHth8EsIy91pFm5vV1fyfucqTyJHqLclZdHfGAtXS/l4eZ7qX8Tzpf6HHWAHd9QmEUPiSfV5uKwj8y6WHuwTY8C3vZbbx4tRN6MC3s/NyamW72volenR3Mcc3TiM8ZoIQb+bEz8SSGrocIPO7SWL3biTppaTUFrExpsPwNmgBD9+vR+1+WczIAr8cDI64ogh8GRH9fwPS7fEJX8kzoFy+eNTpBYqjWLkroXtvGCOO/1vtxJCQkLN5uWDKS8zrY4/e3A5NI/c15j2DbmXbwL7Bowf9hZeVwk5A==
  • Authentication-results: spf=pass (sender IP is 63.35.35.123) smtp.mailfrom=arm.com; lists.xen.org; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com;lists.xen.org; dmarc=bestguesspass action=none header.from=arm.com;
  • Authentication-results-original: spf=none (sender IP is ) smtp.mailfrom=Justin.He@xxxxxxx;
  • Cc: "sharan.santhanam@xxxxxxxxx" <sharan.santhanam@xxxxxxxxx>
  • Delivery-date: Tue, 26 Nov 2019 06:32:42 +0000
  • List-id: Mini-os development list <minios-devel.lists.xenproject.org>
  • Original-authentication-results: spf=none (sender IP is ) smtp.mailfrom=Justin.He@xxxxxxx;
  • Thread-index: AQHVjw9puL5I5NQxtEOb/Xr1inzbMqedJ/gw
  • Thread-topic: [Minios-devel] [UNIKRAFT PATCH v2 06/12] plat/drivers: Configure virtio block queue

Hi Roxana

> -----Original Message-----
> From: Minios-devel <minios-devel-bounces@xxxxxxxxxxxxxxxxxxxx> On Behalf
> Of Roxana Nicolescu
> Sent: Wednesday, October 30, 2019 6:46 PM
> To: minios-devel@xxxxxxxxxxxxx
> Cc: sharan.santhanam@xxxxxxxxx
> Subject: [Minios-devel] [UNIKRAFT PATCH v2 06/12] plat/drivers: Configure
> virtio block queue
>
> This patch introduces the initialization of the virtqueue used for
> communication to Backend.
>
> Signed-off-by: Roxana Nicolescu <nicolescu.roxana1996@xxxxxxxxx>
> ---
>  plat/drivers/include/virtio/virtio_blk.h |   6 +
>  plat/drivers/virtio/virtio_blk.c         | 203 +++++++++++++++++++++++
>  2 files changed, 209 insertions(+)
>
> diff --git a/plat/drivers/include/virtio/virtio_blk.h
> b/plat/drivers/include/virtio/virtio_blk.h
> index 0efb5ba9..4877e404 100644
> --- a/plat/drivers/include/virtio/virtio_blk.h
> +++ b/plat/drivers/include/virtio/virtio_blk.h
> @@ -39,6 +39,8 @@
>  #include <virtio/virtio_types.h>
>
>  /* Feature bits */
> +#define VIRTIO_BLK_F_SIZE_MAX        1       /* Indicates maximum
> segment size */
> +#define VIRTIO_BLK_F_SEG_MAX 2       /* Indicates maximum # of
> segments */
>  #define VIRTIO_BLK_F_RO              5       /* Disk is read-only */
>  #define VIRTIO_BLK_F_BLK_SIZE        6       /* Block size of disk is
> available*/
>  #define VIRTIO_BLK_F_MQ              12      /* support more than one vq
> */
> @@ -46,6 +48,10 @@
>  struct virtio_blk_config {
>       /* The capacity (in 512-byte sectors). */
>       __u64 capacity;
> +     /* The maximum segment size (if VIRTIO_BLK_F_SIZE_MAX) */
> +     __u32 size_max;
> +     /* The maximum number of segments (if VIRTIO_BLK_F_SEG_MAX) */
> +     __u32 seg_max;
>
>       /* block size of device (if VIRTIO_BLK_F_BLK_SIZE) */
>       __u32 blk_size;
> diff --git a/plat/drivers/virtio/virtio_blk.c 
> b/plat/drivers/virtio/virtio_blk.c
> index 4346104f..8da4edc3 100644
> --- a/plat/drivers/virtio/virtio_blk.c
> +++ b/plat/drivers/virtio/virtio_blk.c
> @@ -29,6 +29,7 @@
>  #include <virtio/virtio_ids.h>
>  #include <uk/blkdev.h>
>  #include <virtio/virtio_blk.h>
> +#include <uk/sglist.h>
>  #include <uk/blkdev_driver.h>
>
>  #define DRIVER_NAME          "virtio-blk"
> @@ -41,10 +42,13 @@
>   *   Access Mode
>   *   Sector_size;
>   *   Multi-queue,
> + *   Maximum size of a segment for requests,
> + *   Maximum number of segments per request,
>   **/
>  #define VIRTIO_BLK_DRV_FEATURES(features) \
>       (VIRTIO_FEATURES_UPDATE(features, VIRTIO_BLK_F_RO | \
>       VIRTIO_BLK_F_BLK_SIZE | VIRTIO_BLK_F_MQ | \
> +     VIRTIO_BLK_F_SEG_MAX | VIRTIO_BLK_F_SIZE_MAX | \
>
It would be better that you can make one single patch compilable.
This makes a compilation error here

--
Cheers,
Justin (Jia He)


>  static struct uk_alloc *a;
>  static const char *drv_name = DRIVER_NAME;
> @@ -64,6 +68,10 @@ struct virtio_blk_device {
>       __u16    nb_queues;
>       /* List of queues */
>       struct   uk_blkdev_queue *qs;
> +     /* Maximum number of segments for a request */
> +     __u32 max_segments;
> +     /* Maximum size of a segment */
> +     __u32 max_size_segment;
>  };
>
>  struct uk_blkdev_queue {
> @@ -76,11 +84,164 @@ struct uk_blkdev_queue {
>       struct uk_alloc *a;
>       /* The nr. of descriptor limit */
>       uint16_t max_nb_desc;
> +     /* The nr. of descriptor user configured */
> +     uint16_t nb_desc;
>       /* Reference to virtio_blk_device  */
>       struct virtio_blk_device *vbd;
> +     /* The scatter list and its associated fragments */
> +     struct uk_sglist sg;
> +     struct uk_sglist_seg *sgsegs;
>  };
>
>
> +static int virtio_blkdev_recv_done(struct virtqueue *vq, void *priv)
> +{
> +     struct uk_blkdev_queue *queue = NULL;
> +
> +     UK_ASSERT(vq && priv);
> +
> +     queue = (struct uk_blkdev_queue *) priv;
> +
> +     uk_blkdev_drv_queue_event(&queue->vbd->blkdev, queue-
> >lqueue_id);
> +
> +     return 1;
> +}
> +
> +/**
> + * This function setup the vring infrastructure.
> + */
> +static int virtio_blkdev_vqueue_setup(struct uk_blkdev_queue *queue,
> +             uint16_t nr_desc)
> +{
> +     uint16_t max_desc;
> +     struct virtqueue *vq;
> +
> +     UK_ASSERT(queue);
> +     max_desc = queue->max_nb_desc;
> +     if (unlikely(max_desc < nr_desc)) {
> +             uk_pr_err("Max desc: %"__PRIu16" Requested
> desc:%"__PRIu16"\n",
> +                       max_desc, nr_desc);
> +             return -ENOBUFS;
> +     }
> +
> +     nr_desc = (nr_desc) ? nr_desc : max_desc;
> +     uk_pr_debug("Configuring the %d descriptors\n", nr_desc);
> +
> +     /* Check if the descriptor is a power of 2 */
> +     if (unlikely(nr_desc & (nr_desc - 1))) {
> +             uk_pr_err("Expected descriptor count as a power 2\n");
> +             return -EINVAL;
> +     }
> +
> +     vq = virtio_vqueue_setup(queue->vbd->vdev, queue->lqueue_id,
> nr_desc,
> +                     virtio_blkdev_recv_done, a);
> +     if (unlikely(PTRISERR(vq))) {
> +             uk_pr_err("Failed to set up virtqueue %"__PRIu16"\n",
> +                       queue->lqueue_id);
> +             return PTR2ERR(vq);
> +     }
> +
> +     queue->vq = vq;
> +     vq->priv = queue;
> +
> +     return 0;
> +}
> +
> +static struct uk_blkdev_queue *virtio_blkdev_queue_setup(struct
> uk_blkdev *dev,
> +             uint16_t queue_id,
> +             uint16_t nb_desc,
> +             const struct uk_blkdev_queue_conf *queue_conf)
> +{
> +     struct virtio_blk_device *vbdev;
> +     int rc = 0;
> +     struct uk_blkdev_queue *queue;
> +
> +     UK_ASSERT(dev != NULL);
> +     UK_ASSERT(queue_conf != NULL);
> +
> +     vbdev = to_virtioblkdev(dev);
> +     if (unlikely(queue_id >= vbdev->nb_queues)) {
> +             uk_pr_err("Invalid queue_id %"__PRIu16"\n", queue_id);
> +             rc = -EINVAL;
> +             goto err_exit;
> +     }
> +
> +     queue = &vbdev->qs[queue_id];
> +     queue->a = queue_conf->a;
> +
> +     /* Init sglist */
> +     queue->sgsegs = uk_malloc(queue->a,
> +                     vbdev->max_segments * sizeof(*queue->sgsegs));
> +     if (unlikely(!queue->sgsegs)) {
> +             rc = -ENOMEM;
> +             goto err_exit;
> +     }
> +
> +     uk_sglist_init(&queue->sg, vbdev->max_segments,
> +                     queue->sgsegs);
> +     queue->vbd = vbdev;
> +     queue->nb_desc = nb_desc;
> +     queue->lqueue_id = queue_id;
> +
> +     /* Setup the virtqueue with the descriptor */
> +     rc = virtio_blkdev_vqueue_setup(queue, nb_desc);
> +     if (rc < 0) {
> +             uk_pr_err("Failed to set up virtqueue %"__PRIu16": %d\n",
> +                       queue_id, rc);
> +             goto setup_err;
> +     }
> +
> +exit:
> +     return queue;
> +setup_err:
> +     uk_free(queue->a, queue->sgsegs);
> +err_exit:
> +     queue = ERR2PTR(rc);
> +     goto exit;
> +}
> +
> +static int virtio_blkdev_queue_release(struct uk_blkdev *dev,
> +             struct uk_blkdev_queue *queue)
> +{
> +     struct virtio_blk_device *vbdev;
> +     int rc = 0;
> +
> +     UK_ASSERT(dev != NULL);
> +     vbdev = to_virtioblkdev(dev);
> +
> +     uk_free(queue->a, queue->sgsegs);
> +     virtio_vqueue_release(vbdev->vdev, queue->vq, queue->a);
> +
> +     return rc;
> +}
> +
> +static int virtio_blkdev_queue_info_get(struct uk_blkdev *dev,
> +             uint16_t queue_id,
> +             struct uk_blkdev_queue_info *qinfo)
> +{
> +     struct virtio_blk_device *vbdev = NULL;
> +     struct uk_blkdev_queue *queue = NULL;
> +     int rc = 0;
> +
> +     UK_ASSERT(dev);
> +     UK_ASSERT(qinfo);
> +
> +     vbdev = to_virtioblkdev(dev);
> +     if (unlikely(queue_id >= vbdev->nb_queues)) {
> +             uk_pr_err("Invalid queue_id %"__PRIu16"\n", queue_id);
> +             rc = -EINVAL;
> +             goto exit;
> +     }
> +
> +     queue = &vbdev->qs[queue_id];
> +     qinfo->nb_min = queue->max_nb_desc;
> +     qinfo->nb_max = queue->max_nb_desc;
> +     qinfo->nb_is_power_of_two = 1;
> +
> +exit:
> +     return rc;
> +}
> +
>  static int virtio_blkdev_queues_alloc(struct virtio_blk_device *vbdev,
>                                   const struct uk_blkdev_conf *conf)
>  {
> @@ -177,6 +338,8 @@ static int virtio_blkdev_feature_negotiate(struct
> virtio_blk_device *vbdev)
>       __sector sectors;
>       __sector ssize;
>       __u16 num_queues;
> +     __u32 max_segments;
> +     __u32 max_size_segment;
>       int rc = 0;
>
>       UK_ASSERT(vbdev);
> @@ -228,13 +391,50 @@ static int virtio_blkdev_feature_negotiate(struct
> virtio_blk_device *vbdev)
>               }
>       } else
>               num_queues = 1;
> +
> +     if (virtio_has_features(host_features, VIRTIO_BLK_F_SEG_MAX)) {
> +             bytes_to_read = virtio_config_get(vbdev->vdev,
> +                     __offsetof(struct virtio_blk_config, seg_max),
> +                     &max_segments,
> +                     sizeof(max_segments),
> +                     1);
> +             if (bytes_to_read != sizeof(max_segments))  {
> +                     uk_pr_err("Failed to get maximum nb of
> segments\n");
> +                     rc = -EAGAIN;
> +                     goto exit;
> +             }
> +     } else
> +             max_segments = 1;
> +
> +     /* We need extra sg elements for head (header) and tail (status). */
> +     max_segments += 2;
> +
> +     if (virtio_has_features(host_features, VIRTIO_BLK_F_SIZE_MAX)) {
> +             bytes_to_read = virtio_config_get(vbdev->vdev,
> +                     __offsetof(struct virtio_blk_config, size_max),
> +                     &max_size_segment,
> +                     sizeof(max_size_segment),
> +                     1);
> +             if (bytes_to_read != sizeof(max_size_segment))  {
> +                     uk_pr_err("Failed to get size max from device %d\n",
> +                                     rc);
> +                     rc = -EAGAIN;
> +                     goto exit;
> +             }
> +     } else
> +             max_size_segment = __PAGE_SIZE;
> +
>       cap->ssize = ssize;
>       cap->sectors = sectors;
>       cap->ioalign = sizeof(void *);
>       cap->mode = (virtio_has_features(
>                       host_features, VIRTIO_BLK_F_RO)) ? O_RDONLY :
> O_RDWR;
> +     cap->max_sectors_per_req =
> +                     max_size_segment / ssize * (max_segments - 2);
>
>       vbdev->max_vqueue_pairs = num_queues;
> +     vbdev->max_segments = max_segments;
> +     vbdev->max_size_segment = max_size_segment;
>
>       /**
>        * Mask out features supported by both driver and device.
> @@ -257,6 +457,9 @@ static inline void virtio_blkdev_feature_set(struct
> virtio_blk_device *vbdev)
>  static const struct uk_blkdev_ops virtio_blkdev_ops = {
>               .get_info = virtio_blkdev_get_info,
>               .dev_configure = virtio_blkdev_configure,
> +             .queue_get_info = virtio_blkdev_queue_info_get,
> +             .queue_setup = virtio_blkdev_queue_setup,
> +             .queue_release = virtio_blkdev_queue_release,
>               .dev_unconfigure = virtio_blkdev_unconfigure,
>  };
>
> --
> 2.17.1
>
>
> _______________________________________________
> Minios-devel mailing list
> Minios-devel@xxxxxxxxxxxxxxxxxxxx
> https://lists.xenproject.org/mailman/listinfo/minios-devel
IMPORTANT NOTICE: The contents of this email and any attachments are 
confidential and may also be privileged. If you are not the intended recipient, 
please notify the sender immediately and do not disclose the contents to any 
other person, use it for any purpose, or store or copy the information in any 
medium. Thank you.
_______________________________________________
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®.