|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |