[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Minios-devel] [UNIKRAFT PATCH v3 15/17] plat/xen/drivers/blk: Handle responses from backend
Reviewed-by: Costin Lupu <costin.lupu@xxxxxxxxx> On 10/30/19 5:55 PM, Roxana Nicolescu wrote: > This patch introduces the function responsible of processing responses > from the queue. > Responses are popped out from queue until there is nothing to process. > > Signed-off-by: Roxana Nicolescu <nicolescu.roxana1996@xxxxxxxxx> > --- > plat/xen/drivers/blk/blkfront.c | 120 ++++++++++++++++++++++++++++++++ > 1 file changed, 120 insertions(+) > > diff --git a/plat/xen/drivers/blk/blkfront.c b/plat/xen/drivers/blk/blkfront.c > index 5866c8e7..1b4d2938 100644 > --- a/plat/xen/drivers/blk/blkfront.c > +++ b/plat/xen/drivers/blk/blkfront.c > @@ -273,6 +273,125 @@ static int blkfront_xen_ring_intr_enable(struct > uk_blkdev_queue *queue) > > return (more > 0); > } > + > +#define CHECK_STATUS(req, status, operation) \ > + do { \ > + if (status != BLKIF_RSP_OKAY) \ > + uk_pr_err("Failed to "operation" %lu sector: %d\n", \ > + req->start_sector, \ > + status); \ > + else \ > + uk_pr_debug("Succeed to "operation " %lu sector: %d\n",\ > + req->start_sector, \ > + status); \ > + } while (0) > + > +static int blkfront_queue_dequeue(struct uk_blkdev_queue *queue, > + struct uk_blkreq **req) > +{ > + RING_IDX prod, cons; > + struct blkif_response *rsp; > + struct uk_blkreq *req_from_q = NULL; > + struct blkfront_request *blkfront_req; > + struct blkif_front_ring *ring; > + uint8_t status; > + int rc = 0; > + > + UK_ASSERT(queue); > + UK_ASSERT(req); > + > + ring = &queue->ring; > + prod = ring->sring->rsp_prod; > + rmb(); /* Ensure we see queued responses up to 'rp'. */ > + cons = ring->rsp_cons; > + > + /* No new descriptor since last dequeue operation */ > + if (cons == prod) > + goto out; > + > + rsp = RING_GET_RESPONSE(ring, cons); > + blkfront_req = (struct blkfront_request *) rsp->id; > + UK_ASSERT(blkfront_req); > + req_from_q = blkfront_req->req; > + UK_ASSERT(req_from_q); > + status = rsp->status; > + switch (rsp->operation) { > + case BLKIF_OP_READ: > + CHECK_STATUS(req_from_q, status, "read"); > + break; > + case BLKIF_OP_WRITE: > + CHECK_STATUS(req_from_q, status, "write"); > + break; > + case BLKIF_OP_WRITE_BARRIER: > + if (status != BLKIF_RSP_OKAY) > + uk_pr_err("Write barrier error %d\n", status); > + break; > + case BLKIF_OP_FLUSH_DISKCACHE: > + if (status != BLKIF_RSP_OKAY) > + uk_pr_err("Flush_diskcache error %d\n", status); > + break; > + default: > + uk_pr_err("Unrecognized block operation %d (rsp %d)\n", > + rsp->operation, status); > + break; > + } > + > + req_from_q->result = -status; > + uk_free(drv_allocator, blkfront_req); > + ring->rsp_cons++; > + > +out: > + *req = req_from_q; > + return rc; > +} > + > +static int blkfront_complete_reqs(struct uk_blkdev *blkdev, > + struct uk_blkdev_queue *queue) > +{ > + struct uk_blkreq *req; > + int rc; > + int more; > + > + UK_ASSERT(blkdev); > + UK_ASSERT(queue); > + > + /* Queue interrupts have to be off when calling receive */ > + UK_ASSERT(!(queue->intr_enabled & BLKFRONT_INTR_EN)); > +moretodo: > + for (;;) { > + rc = blkfront_queue_dequeue(queue, &req); > + if (rc < 0) { > + uk_pr_err("Failed to dequeue the request: %d\n", rc); > + goto err_exit; > + } > + > + if (!req) > + break; > + > + uk_blkreq_finished(req); > + if (req->cb) > + req->cb(req, req->cb_cookie); > + } > + > + /* Enable interrupt only when user had previously enabled it */ > + if (queue->intr_enabled & BLKFRONT_INTR_USR_EN_MASK) { > + /* Need to enable the interrupt on the last packet */ > + rc = blkfront_xen_ring_intr_enable(queue); > + if (rc == 1) > + goto moretodo; > + } else { > + RING_FINAL_CHECK_FOR_RESPONSES(&queue->ring, more); > + if (more) > + goto moretodo; > + } > + > + return 0; > + > +err_exit: > + return rc; > + > +} > + > static int blkfront_ring_init(struct uk_blkdev_queue *queue) > { > struct blkif_sring *sring = NULL; > @@ -565,6 +684,7 @@ static int blkfront_add_dev(struct xenbus_device *dev) > > d->xendev = dev; > d->blkdev.submit_one = blkfront_submit_request; > + d->blkdev.finish_reqs = blkfront_complete_reqs; > d->blkdev.dev_ops = &blkfront_ops; > > /* Xenbus initialization */ > _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |