[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH v2 10/16] plat/xen/drivers/blk: Write queues information to Xenstore
This patch introduces the last step of start operation: Writing to Xenstore information about each configured queue (ring grant reference and event channel) in order to connect to Backend. Signed-off-by: Roxana Nicolescu <nicolescu.roxana1996@xxxxxxxxx> --- plat/xen/drivers/blk/blkfront_xb.h | 2 + plat/xen/drivers/blk/blkfront_xs.c | 196 +++++++++++++++++++++++++++++++++++++ 2 files changed, 198 insertions(+) diff --git a/plat/xen/drivers/blk/blkfront_xb.h b/plat/xen/drivers/blk/blkfront_xb.h index 60070d9c..e1b8b199 100644 --- a/plat/xen/drivers/blk/blkfront_xb.h +++ b/plat/xen/drivers/blk/blkfront_xb.h @@ -65,6 +65,7 @@ void blkfront_xb_fini(struct blkfront_dev *dev); int blkfront_xb_write_nb_queues(struct blkfront_dev *dev); /** + * Write ring entries to Xenstore. * Device changes its state to Connected. * It waits until the backend is connected. * @@ -76,6 +77,7 @@ int blkfront_xb_connect(struct blkfront_dev *dev); * Reinitialize the connection with the backend. * The following states are: * Connected -> Closing -> Closed -> Initializing. + * Delete ring entries * * Return 0 on success, a negative errno value on error. */ diff --git a/plat/xen/drivers/blk/blkfront_xs.c b/plat/xen/drivers/blk/blkfront_xs.c index 5ddb38d0..86aee13b 100644 --- a/plat/xen/drivers/blk/blkfront_xs.c +++ b/plat/xen/drivers/blk/blkfront_xs.c @@ -164,6 +164,189 @@ out: return err; } + +/* Write info for a specific queue in xenstore. + * If there is only one queue, the path does not + * include queue-<queue-id>. + **/ +static int blkfront_xb_write_ring_info(struct blkfront_dev *dev, + uint16_t queue_id, + xenbus_transaction_t xbt) +{ + struct xenbus_device *xendev; + char *node_ring_ref = NULL; + char *node_evtchn = NULL; + int err = 0; + + UK_ASSERT(dev != NULL); + xendev = dev->xendev; + + if (queue_id == 0 && dev->nb_queues == 1) { + err = asprintf(&node_ring_ref, "ring-ref"); + if (err <= 0) { + uk_pr_err("Failed to format ring_ref path: %d\n", err); + goto out; + } + + err = asprintf(&node_evtchn, "event-channel"); + if (err <= 0) { + uk_pr_err("Failed to format event-channel path: %d\n", + err); + goto out; + } + } else { + err = asprintf(&node_ring_ref, "queue-%"PRIu16"/ring-ref", + queue_id); + if (err <= 0) { + uk_pr_err("Failed to format ring_ref path: %d\n", err); + goto out; + } + + err = asprintf(&node_evtchn, "queue-%"PRIu16"/event-channel", + queue_id); + if (err <= 0) { + uk_pr_err("Failed to format event-channel path: %d\n", + err); + goto out; + } + } + + err = xs_printf(xbt, xendev->nodename, + node_evtchn, + "%u", + dev->blkdev._queue[queue_id]->evtchn); + if (err <= 0) { + uk_pr_err("Failed to write event-channel: %d\n", err); + goto out; + } + + err = xs_printf(xbt, xendev->nodename, + node_ring_ref, + "%u", + dev->blkdev._queue[queue_id]->ring_ref); + if (err <= 0) { + uk_pr_err("Failed to write ring_ref: %d\n", err); + goto out; + } + + err = 0; + +out: + free(node_evtchn); + free(node_ring_ref); + return err; +} + +/* Delete ring entry */ +static int blkfront_xb_delete_ring_info(struct blkfront_dev *dev, + uint16_t queue_id) +{ + struct xenbus_device *xendev; + char *node_ring_ref = NULL; + char *node_evtchn = NULL; + int err = 0; + + UK_ASSERT(dev); + xendev = dev->xendev; + + if (queue_id == 0 && dev->nb_queues == 1) { + err = asprintf(&node_ring_ref, "%s/ring-ref", + xendev->nodename); + if (err <= 0) { + uk_pr_err("Failed to format ring_ref_path: %d\n", err); + goto out; + } + + err = asprintf(&node_evtchn, "%s/event-channel", + xendev->nodename); + if (err <= 0) { + uk_pr_err("Failed to format event-channel path: %d\n", + err); + goto out; + } + } else { + err = asprintf(&node_ring_ref, "%s/queue-%"PRIu16"/ring-ref", + xendev->nodename, + queue_id); + if (err <= 0) { + uk_pr_err("Failed to format ring_ref_path: %d\n", err); + goto out; + } + + err = asprintf(&node_evtchn, "%s/queue-%"PRIu16"/event-channel", + xendev->nodename, + queue_id); + if (err <= 0) { + uk_pr_err("Failed to format event-channel path: %d\n", + err); + goto out; + } + } + + err = xs_rm(XBT_NIL, node_ring_ref); + if (err) + uk_pr_err("Failed to remove ring_ref from xs: %d\n", err); + + err = xs_rm(XBT_NIL, node_evtchn); + if (err) + uk_pr_err("Failed to remove event-channel from xs: %d\n", err); +out: + free(node_evtchn); + free(node_ring_ref); + return err; +} + +static int blkfront_xb_write_rings_info(struct blkfront_dev *dev) +{ + xenbus_transaction_t xbt = 0; + int err = 0; + + UK_ASSERT(dev != NULL); + + err = xs_transaction_start(&xbt); + if (err) + goto abort_transaction; + + for (uint16_t queue_id = 0; queue_id < dev->nb_queues; ++queue_id) { + err = blkfront_xb_write_ring_info(dev, queue_id, xbt); + if (err) { + uk_pr_err("Failed to write queue%"PRIu16" to xs: %d\n", + queue_id, + err); + goto abort_transaction; + } + } + + err = xs_transaction_end(xbt, 0); + if (err) + uk_pr_err("Failed to end transaction: %d\n", err); + + return err; + +abort_transaction: + xs_transaction_end(xbt, 1); + return err; +} + +static int blkfront_xb_delete_rings_info(struct blkfront_dev *dev) +{ + int err = 0; + + UK_ASSERT(dev != NULL); + + for (uint16_t queue_id = 0; queue_id < dev->nb_queues; ++queue_id) { + err = blkfront_xb_delete_ring_info(dev, queue_id); + if (err) { + uk_pr_err("Failed to delete ring_info for q-%" + PRIu16 ": %d\n", + queue_id, err); + return err; + } + } + + return err; +} + #define WAIT_BE_STATE_CHANGE_WHILE_COND(state_cond) \ do { \ err = xs_read_integer(XBT_NIL, back_state_path,\ @@ -253,6 +436,13 @@ int blkfront_xb_connect(struct blkfront_dev *blkdev) UK_ASSERT(blkdev != NULL); xendev = blkdev->xendev; + err = blkfront_xb_write_rings_info(blkdev); + if (err) { + uk_pr_err("Failed to write rings info to xenstore: %d\n.", + err); + return err; + } + err = xenbus_switch_state(XBT_NIL, xendev, XenbusStateConnected); if (err) goto err; @@ -289,6 +479,12 @@ int blkfront_xb_disconnect(struct blkfront_dev *blkdev) goto out; } + err = blkfront_xb_delete_rings_info(blkdev); + if (err) { + uk_pr_err("Failed to delete rings info: %d\n", err); + goto out; + } + out: return err; } -- 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 |