[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 |