summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuergen Gross <jgross@suse.com>2023-01-30 12:30:36 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-03-11 16:44:11 +0100
commit7cc9dbae8a5f73bd555130384ea256018d28f283 (patch)
tree3bc089c320ba0d682be504c223986e6e165c93f3
parent9d1c625c99c56f6de66705138a7f03dd73dffa86 (diff)
downloadlinux-stable-7cc9dbae8a5f73bd555130384ea256018d28f283.tar.gz
linux-stable-7cc9dbae8a5f73bd555130384ea256018d28f283.tar.bz2
linux-stable-7cc9dbae8a5f73bd555130384ea256018d28f283.zip
9p/xen: fix connection sequence
[ 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>
-rw-r--r--net/9p/trans_xen.c38
1 files changed, 23 insertions, 15 deletions
diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c
index 131757aa0e6e..67e9a7085e13 100644
--- a/net/9p/trans_xen.c
+++ b/net/9p/trans_xen.c
@@ -389,12 +389,11 @@ out:
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;
@@ -420,11 +419,6 @@ static int xen_9pfs_front_probe(struct xenbus_device *dev,
if (max_ring_order < XEN_9PFS_RING_ORDER)
return -EINVAL;
- 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);
@@ -482,23 +476,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");
@@ -517,6 +523,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: