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

[Minios-devel] [UNIKRAFT PATCH 16/17] plat/xen/drivers/blk: Grant references support



This patch introduces the functions used for allocating
new grant references in order to share data for requests.

Signed-off-by: Roxana Nicolescu <nicolescu.roxana1996@xxxxxxxxx>
---
 plat/xen/drivers/blk/blkfront.c | 91 +++++++++++++++++++++++++++++++++++++++++
 plat/xen/drivers/blk/blkfront.h | 10 +++++
 2 files changed, 101 insertions(+)

diff --git a/plat/xen/drivers/blk/blkfront.c b/plat/xen/drivers/blk/blkfront.c
index 23ec4ad0..23189156 100644
--- a/plat/xen/drivers/blk/blkfront.c
+++ b/plat/xen/drivers/blk/blkfront.c
@@ -66,6 +66,87 @@
 
 static struct uk_alloc *drv_allocator;
 
+static int blkfront_request_set_grefs(struct blkfront_request *blkfront_req)
+{
+       struct blkfront_gref *ref_elem;
+       uint16_t nb_segments;
+       int grefi = 0, grefj;
+       int err = 0;
+
+       UK_ASSERT(blkfront_req != NULL);
+       nb_segments = blkfront_req->nb_segments;
+
+       /* we allocate new ones */
+       for (; grefi < nb_segments; ++grefi) {
+               ref_elem = uk_malloc(drv_allocator, sizeof(*ref_elem));
+               if (!ref_elem) {
+                       err = -ENOMEM;
+                       goto err;
+               }
+
+               blkfront_req->gref[grefi] = ref_elem;
+       }
+
+out:
+       return err;
+err:
+       /* Free all the elements from 0 index to where the error happens */
+       for (grefj = 0; grefj < grefi; ++grefj) {
+               ref_elem = blkfront_req->gref[grefj];
+               uk_free(drv_allocator, ref_elem);
+       }
+       goto out;
+}
+
+static void blkfront_request_reset_grefs(struct blkfront_request *req)
+{
+       uint16_t gref_id = 0;
+       struct blkfront_gref *gref_elem;
+       uint16_t nb_segments;
+       int rc;
+
+       UK_ASSERT(req);
+       nb_segments = req->nb_segments;
+
+       for (; gref_id < nb_segments; ++gref_id) {
+               gref_elem = req->gref[gref_id];
+               if (gref_elem->ref != GRANT_INVALID_REF) {
+                       rc = gnttab_end_access(gref_elem->ref);
+                       UK_ASSERT(rc);
+               }
+
+               uk_free(drv_allocator, gref_elem);
+       }
+}
+
+static void blkfront_request_map_grefs(struct blkif_request *ring_req,
+               domid_t otherend_id)
+{
+       uint16_t gref_index;
+       struct blkfront_request *blkfront_req;
+       struct uk_blkdev_request *req;
+       uint16_t nb_segments;
+       uintptr_t data;
+       uintptr_t start_sector;
+       struct blkfront_gref *ref_elem;
+
+       UK_ASSERT(ring_req);
+
+       blkfront_req = (struct blkfront_request *)ring_req->id;
+       req = blkfront_req->req;
+       start_sector = round_pgdown((uintptr_t)req->aio_buf);
+       nb_segments = blkfront_req->nb_segments;
+
+       for (gref_index = 0; gref_index < nb_segments; ++gref_index) {
+               data = start_sector + gref_index * PAGE_SIZE;
+               ref_elem = blkfront_req->gref[gref_index];
+               ref_elem->ref = gnttab_grant_access(otherend_id,
+                               virtual_to_mfn(data), ring_req->operation);
+
+               UK_ASSERT(ref_elem->ref != GRANT_INVALID_REF);
+               ring_req->seg[gref_index].gref = ref_elem->ref;
+       }
+}
 
 static void blkfront_ring_wr_init(struct blkif_request *ring_req,
                __sector sector_size)
@@ -148,6 +229,14 @@ static int blkfront_request_write(struct blkfront_request 
*blkfront_req,
        blkfront_ring_wr_init(ring_req, sector_size);
        blkfront_req->nb_segments = ring_req->nr_segments;
 
+       rc = blkfront_request_set_grefs(blkfront_req);
+       if (rc)
+               goto out;
+
+       /* Map grant references to ring_req */
+       blkfront_request_map_grefs(ring_req, dev->xendev->otherend_id);
+
+out:
        return rc;
 }
 
@@ -328,9 +417,11 @@ static int blkfront_queue_dequeue(struct uk_blkdev_queue 
*queue,
        switch (rsp->operation) {
        case BLKIF_OP_READ:
                CHECK_STATUS(req_from_q, status, "read");
+               blkfront_request_reset_grefs(blkfront_req);
                break;
        case BLKIF_OP_WRITE:
                CHECK_STATUS(req_from_q, status, "write");
+               blkfront_request_reset_grefs(blkfront_req);
                break;
        case BLKIF_OP_WRITE_BARRIER:
                if (status != BLKIF_RSP_OKAY)
diff --git a/plat/xen/drivers/blk/blkfront.h b/plat/xen/drivers/blk/blkfront.h
index 94072d89..b100ca2f 100644
--- a/plat/xen/drivers/blk/blkfront.h
+++ b/plat/xen/drivers/blk/blkfront.h
@@ -49,11 +49,21 @@
 
 
 /**
+ * Structure used to describe a grant ref element.
+ */
+struct blkfront_gref {
+       /* Grant ref number. */
+       grant_ref_t ref;
+};
+
+/**
  * Structure used to describe a front device request.
  */
 struct blkfront_request {
        /* Request from the API. */
        struct uk_blkdev_request *req;
+       /* List with maximum number of blkfront_grefs for a request. */
+       struct blkfront_gref *gref[BLKIF_MAX_SEGMENTS_PER_REQUEST];
        /* Number of segments. */
        uint16_t nb_segments;
        /* Queue in which the request will be stored */
-- 
2.11.0


_______________________________________________
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®.