| From 42b23da209c04798698d552824e7ed081a0d85e4 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 30 Jan 2023 12:30:36 +0100 |
| Subject: 9p/xen: fix connection sequence |
| |
| From: Juergen Gross <jgross@suse.com> |
| |
| [ Upstream commit c15fe55d14b3b4ded5af2a3260877460a6ffb8ad ] |
| |
| Today the connection sequence of the Xen 9pfs frontend doesn't match |
| the documented sequence. It can work reliably only for a PV 9pfs device |
| having been added at boot time already, as the frontend is not waiting |
| for the backend to have set its state to "XenbusStateInitWait" before |
| reading the backend properties from Xenstore. |
| |
| Fix that by following the documented sequence [1] (the documentation |
| has a bug, so the reference is for the patch fixing that). |
| |
| [1]: https://lore.kernel.org/xen-devel/20230130090937.31623-1-jgross@suse.com/T/#u |
| |
| Link: https://lkml.kernel.org/r/20230130113036.7087-3-jgross@suse.com |
| Fixes: 868eb122739a ("xen/9pfs: introduce Xen 9pfs transport driver") |
| Signed-off-by: Juergen Gross <jgross@suse.com> |
| Reviewed-by: Simon Horman <simon.horman@corigine.com> |
| Signed-off-by: Dominique Martinet <asmadeus@codewreck.org> |
| Signed-off-by: Eric Van Hensbergen <ericvh@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| net/9p/trans_xen.c | 38 +++++++++++++++++++++++--------------- |
| 1 file changed, 23 insertions(+), 15 deletions(-) |
| |
| diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c |
| index d8ed75e8dbb1d..220e8f4ac0cfe 100644 |
| --- a/net/9p/trans_xen.c |
| +++ b/net/9p/trans_xen.c |
| @@ -393,12 +393,11 @@ static int xen_9pfs_front_alloc_dataring(struct xenbus_device *dev, |
| return ret; |
| } |
| |
| -static int xen_9pfs_front_probe(struct xenbus_device *dev, |
| - const struct xenbus_device_id *id) |
| +static int xen_9pfs_front_init(struct xenbus_device *dev) |
| { |
| int ret, i; |
| struct xenbus_transaction xbt; |
| - struct xen_9pfs_front_priv *priv = NULL; |
| + struct xen_9pfs_front_priv *priv = dev_get_drvdata(&dev->dev); |
| char *versions, *v; |
| unsigned int max_rings, max_ring_order, len = 0; |
| |
| @@ -426,11 +425,6 @@ static int xen_9pfs_front_probe(struct xenbus_device *dev, |
| if (p9_xen_trans.maxsize > XEN_FLEX_RING_SIZE(max_ring_order)) |
| p9_xen_trans.maxsize = XEN_FLEX_RING_SIZE(max_ring_order) / 2; |
| |
| - priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
| - if (!priv) |
| - return -ENOMEM; |
| - |
| - priv->dev = dev; |
| priv->num_rings = XEN_9PFS_NUM_RINGS; |
| priv->rings = kcalloc(priv->num_rings, sizeof(*priv->rings), |
| GFP_KERNEL); |
| @@ -489,23 +483,35 @@ static int xen_9pfs_front_probe(struct xenbus_device *dev, |
| goto error; |
| } |
| |
| - write_lock(&xen_9pfs_lock); |
| - list_add_tail(&priv->list, &xen_9pfs_devs); |
| - write_unlock(&xen_9pfs_lock); |
| - dev_set_drvdata(&dev->dev, priv); |
| - xenbus_switch_state(dev, XenbusStateInitialised); |
| - |
| return 0; |
| |
| error_xenbus: |
| xenbus_transaction_end(xbt, 1); |
| xenbus_dev_fatal(dev, ret, "writing xenstore"); |
| error: |
| - dev_set_drvdata(&dev->dev, NULL); |
| xen_9pfs_front_free(priv); |
| return ret; |
| } |
| |
| +static int xen_9pfs_front_probe(struct xenbus_device *dev, |
| + const struct xenbus_device_id *id) |
| +{ |
| + struct xen_9pfs_front_priv *priv = NULL; |
| + |
| + priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
| + if (!priv) |
| + return -ENOMEM; |
| + |
| + priv->dev = dev; |
| + dev_set_drvdata(&dev->dev, priv); |
| + |
| + write_lock(&xen_9pfs_lock); |
| + list_add_tail(&priv->list, &xen_9pfs_devs); |
| + write_unlock(&xen_9pfs_lock); |
| + |
| + return 0; |
| +} |
| + |
| static int xen_9pfs_front_resume(struct xenbus_device *dev) |
| { |
| dev_warn(&dev->dev, "suspend/resume unsupported\n"); |
| @@ -524,6 +530,8 @@ static void xen_9pfs_front_changed(struct xenbus_device *dev, |
| break; |
| |
| case XenbusStateInitWait: |
| + if (!xen_9pfs_front_init(dev)) |
| + xenbus_switch_state(dev, XenbusStateInitialised); |
| break; |
| |
| case XenbusStateConnected: |
| -- |
| 2.39.2 |
| |