[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Minios-devel] [UNIKRAFT PATCH v3 10/17] plat/xen/drivers/blk: Start blkfront device
Reviewed-by: Costin Lupu <costin.lupu@xxxxxxxxx> On 10/30/19 5:54 PM, Roxana Nicolescu wrote: > This patch introduces start/stop operations to blkfront device. > This implies connection to backend by communication through Xenstore. > > Signed-off-by: Roxana Nicolescu <nicolescu.roxana1996@xxxxxxxxx> > --- > plat/xen/drivers/blk/blkfront.c | 47 +++++++++++ > plat/xen/drivers/blk/blkfront_xb.h | 18 ++++ > plat/xen/drivers/blk/blkfront_xs.c | 129 +++++++++++++++++++++++++++++ > 3 files changed, 194 insertions(+) > > diff --git a/plat/xen/drivers/blk/blkfront.c b/plat/xen/drivers/blk/blkfront.c > index 63b1e778..00343525 100644 > --- a/plat/xen/drivers/blk/blkfront.c > +++ b/plat/xen/drivers/blk/blkfront.c > @@ -270,6 +270,51 @@ out_err: > uk_free(drv_allocator, dev->queues); > goto out; > } > + > +static int blkfront_start(struct uk_blkdev *blkdev) > +{ > + struct blkfront_dev *dev; > + int err = 0; > + > + UK_ASSERT(blkdev != NULL); > + dev = to_blkfront(blkdev); > + err = blkfront_xb_connect(dev); > + if (err) { > + uk_pr_err("Failed to connect to backend: %d.\n", err); > + return err; > + } > + > + uk_pr_info(DRIVER_NAME": %"PRIu16" started\n", dev->uid); > + > + return err; > +} > + > +/* If one queue has unconsumed responses it returns -EBUSY */ > +static int blkfront_stop(struct uk_blkdev *blkdev) > +{ > + struct blkfront_dev *dev; > + uint16_t q_id; > + int err; > + > + UK_ASSERT(blkdev != NULL); > + dev = to_blkfront(blkdev); > + for (q_id = 0; q_id < dev->nb_queues; ++q_id) { > + if (RING_HAS_UNCONSUMED_RESPONSES(&dev->queues[q_id].ring)) { > + uk_pr_err("Queue:%"PRIu16" has unconsumed responses\n", > + q_id); > + return -EBUSY; > + } > + } > + > + err = blkfront_xb_disconnect(dev); > + if (err) { > + uk_pr_err( > + "Failed to disconnect: %d.\n", err); > + return err; > + } > + > + uk_pr_info(DRIVER_NAME": %"PRIu16" stopped\n", dev->uid); > + > return err; > } > > @@ -302,6 +347,8 @@ static const struct uk_blkdev_ops blkfront_ops = { > .queue_get_info = blkfront_queue_get_info, > .queue_setup = blkfront_queue_setup, > .queue_release = blkfront_queue_release, > + .dev_start = blkfront_start, > + .dev_stop = blkfront_stop, > .dev_unconfigure = blkfront_unconfigure, > .queue_intr_enable = blkfront_queue_intr_enable, > .queue_intr_disable = blkfront_queue_intr_disable, > diff --git a/plat/xen/drivers/blk/blkfront_xb.h > b/plat/xen/drivers/blk/blkfront_xb.h > index 668206a0..90638e94 100644 > --- a/plat/xen/drivers/blk/blkfront_xb.h > +++ b/plat/xen/drivers/blk/blkfront_xb.h > @@ -62,4 +62,22 @@ void blkfront_xb_fini(struct blkfront_dev *dev); > * Return 0 on success, a negative errno value on error. > */ > int blkfront_xb_write_nb_queues(struct blkfront_dev *dev); > + > +/** > + * Device changes its state to Connected. > + * It waits until the backend is connected. > + * > + * Return 0 on success, a negative errno value on error. > + */ > +int blkfront_xb_connect(struct blkfront_dev *dev); > + > +/** > + * Reinitialize the connection with the backend. > + * The following states are: > + * Connected -> Closing -> Closed -> Initializing. > + * > + * Return 0 on success, a negative errno value on error. > + */ > +int blkfront_xb_disconnect(struct blkfront_dev *dev); > + > #endif /* __BLKFRONT_XB_H__ */ > diff --git a/plat/xen/drivers/blk/blkfront_xs.c > b/plat/xen/drivers/blk/blkfront_xs.c > index 9f44246e..67320712 100644 > --- a/plat/xen/drivers/blk/blkfront_xs.c > +++ b/plat/xen/drivers/blk/blkfront_xs.c > @@ -164,3 +164,132 @@ int blkfront_xb_write_nb_queues(struct blkfront_dev > *dev) > out: > return err; > } > + > +#define WAIT_BE_STATE_CHANGE_WHILE_COND(state_cond) \ > + do { \ > + err = xs_read_integer(XBT_NIL, back_state_path,\ > + (int *) &back_state); \ > + if (err) \ > + goto out; \ > + while (!err && (state_cond)) \ > + err = xenbus_wait_for_state_change(back_state_path, \ > + &back_state, \ > + xendev->otherend_watch); \ > + if (err) \ > + goto out; \ > + } while (0) > + > + > +static int blkfront_xb_wait_be_connect(struct blkfront_dev *blkdev) > +{ > + struct xenbus_device *xendev; > + char *back_state_path = NULL; > + XenbusState back_state; > + int err = 0; > + > + UK_ASSERT(blkdev != NULL); > + xendev = blkdev->xendev; > + err = asprintf(&back_state_path, "%s/state", xendev->otherend); > + if (err <= 0) { > + uk_pr_err("Failed to format back_state_path: %d\n", err); > + goto out; > + } > + > + WAIT_BE_STATE_CHANGE_WHILE_COND(back_state < XenbusStateConnected); > + if (back_state != XenbusStateConnected) { > + uk_pr_err("Backend not available, state=%s\n", > + xenbus_state_to_str(back_state)); > + err = -1; > + goto out; > + } > + > +out: > + free(back_state_path); > + return err; > +} > + > +static int blkfront_xb_wait_be_disconnect(struct blkfront_dev *blkdev) > +{ > + struct xenbus_device *xendev; > + char *back_state_path = NULL; > + XenbusState back_state; > + int err = 0; > + > + UK_ASSERT(blkdev != NULL); > + xendev = blkdev->xendev; > + > + err = asprintf(&back_state_path, "%s/state", xendev->otherend); > + if (err <= 0) { > + uk_pr_err("Failed to format back_state_path: %d\n", err); > + goto out; > + } > + > + WAIT_BE_STATE_CHANGE_WHILE_COND(back_state < XenbusStateClosing); > + err = xenbus_switch_state(XBT_NIL, xendev, XenbusStateClosed); > + if (err) { > + uk_pr_err("Failed to switch state to Closed: %d\n", err); > + goto out; > + } > + > + WAIT_BE_STATE_CHANGE_WHILE_COND(back_state < XenbusStateClosed); > + err = xenbus_switch_state(XBT_NIL, xendev, XenbusStateInitialising); > + if (err) { > + uk_pr_err("Failed to switch state to Initialising: %d\n", err); > + goto out; > + } > + > + WAIT_BE_STATE_CHANGE_WHILE_COND(back_state < XenbusStateInitWait || > + back_state >= XenbusStateClosed); > + > +out: > + free(back_state_path); > + return err; > +} > + > +int blkfront_xb_connect(struct blkfront_dev *blkdev) > +{ > + int err; > + struct xenbus_device *xendev; > + > + UK_ASSERT(blkdev != NULL); > + xendev = blkdev->xendev; > + > + err = xenbus_switch_state(XBT_NIL, xendev, XenbusStateConnected); > + if (err) > + goto err; > + > + err = blkfront_xb_wait_be_connect(blkdev); > + if (err) > + goto err; > + > +err: > + return err; > +} > + > +int blkfront_xb_disconnect(struct blkfront_dev *blkdev) > +{ > + struct xenbus_device *xendev; > + int err; > + > + UK_ASSERT(blkdev != NULL); > + > + xendev = blkdev->xendev; > + > + uk_pr_info("Disconnect blkfront: backend at %s\n", > + xendev->otherend); > + > + err = xenbus_switch_state(XBT_NIL, xendev, XenbusStateClosing); > + if (err) { > + uk_pr_err("Failed to switch state to Closing: %d\n", err); > + goto out; > + } > + > + err = blkfront_xb_wait_be_disconnect(blkdev); > + if (err) { > + uk_pr_err("Failed to disconnect: %d\n", err); > + goto out; > + } > + > +out: > + return err; > +} > _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |