Inter-revision diff: patch 5

Comparing v6 (message) to v4 (message)

--- v6
+++ v4
@@ -1,135 +1,63 @@
-The virtio transport supports by default a 9p 'msize' of up to
-approximately 500 kB. This patch adds support for larger 'msize'
-values by resizing the amount of scatter/gather lists if required.
-
-To be more precise, for the moment this patch increases the 'msize'
-limit for the virtio transport to slightly below 4 MB, virtio
-transport actually supports much more (tested successfully with an
-experimental QEMU version and some dirty 9p Linux client hacks up
-to msize=128MB), but client still uses linear buffers, which in
-turn are limited to KMALLOC_MAX_SIZE (4M).
+This new field 'trans_maxsize' optionally allows transport to
+update it to reflect the actual maximum msize supported by
+allocated transport channel.
 
 Signed-off-by: Christian Schoenebeck <linux_oss@crudebyte.com>
 ---
+ include/net/9p/client.h |  2 ++
+ net/9p/client.c         | 12 ++++++++++--
+ 2 files changed, 12 insertions(+), 2 deletions(-)
 
-I am not sure if it is safe the way SG lists are resized here. I "think"
-Dominique said before there should be no concurrency here, but probably
-deserves a revisit.
-
- net/9p/trans_virtio.c | 79 +++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 79 insertions(+)
-
-diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
-index 5ac533f83322..921caa022570 100644
---- a/net/9p/trans_virtio.c
-+++ b/net/9p/trans_virtio.c
-@@ -36,6 +36,16 @@
- #include <linux/virtio_9p.h>
- #include "trans_common.h"
- 
-+/*
-+ * Maximum amount of virtio descriptors allowed per virtio round-trip
-+ * message.
-+ *
-+ * This effectively limits msize to (slightly below) 4M, virtio transport
-+ * actually supports much more, but client still uses linear buffers, which
-+ * in turn are limited to KMALLOC_MAX_SIZE (4M).
-+ */
-+#define VIRTIO_MAX_DESCRIPTORS 1024
-+
- /**
-  * struct virtqueue_sg - (chained) scatter gather lists for virtqueue data
-  * transmission
-@@ -203,6 +213,31 @@ static struct virtqueue_sg *vq_sg_alloc(unsigned int nsgl)
- 	return vq_sg;
- }
- 
-+/**
-+ * vq_sg_resize - resize passed virtqueue scatter/gather lists to the passed
-+ * amount of lists
-+ * @_vq_sg: scatter/gather lists to be resized
-+ * @nsgl: new amount of scatter/gather lists
-+ */
-+static int vq_sg_resize(struct virtqueue_sg **_vq_sg, unsigned int nsgl)
-+{
-+	struct virtqueue_sg *vq_sg;
-+
-+	BUG_ON(!_vq_sg || !nsgl);
-+	vq_sg = *_vq_sg;
-+	if (vq_sg->nsgl == nsgl)
-+		return 0;
-+
-+	/* lazy resize implementation for now */
-+	vq_sg = vq_sg_alloc(nsgl);
-+	if (!vq_sg)
-+		return -ENOMEM;
-+
-+	kfree(*_vq_sg);
-+	*_vq_sg = vq_sg;
-+	return 0;
-+}
-+
- /**
-  * p9_virtio_close - reclaim resources of a channel
-  * @client: client instance
-@@ -774,6 +809,10 @@ p9_virtio_create(struct p9_client *client, const char *devname, char *args)
- 	struct virtio_chan *chan;
- 	int ret = -ENOENT;
- 	int found = 0;
-+#if !defined(CONFIG_ARCH_NO_SG_CHAIN)
-+	size_t npages;
-+	size_t nsgl;
-+#endif
- 
- 	if (devname == NULL)
- 		return -EINVAL;
-@@ -796,6 +835,46 @@ p9_virtio_create(struct p9_client *client, const char *devname, char *args)
- 		return ret;
+diff --git a/include/net/9p/client.h b/include/net/9p/client.h
+index ec1d1706f43c..f5718057fca4 100644
+--- a/include/net/9p/client.h
++++ b/include/net/9p/client.h
+@@ -87,6 +87,7 @@ struct p9_req_t {
+  * struct p9_client - per client instance state
+  * @lock: protect @fids and @reqs
+  * @msize: maximum data size negotiated by protocol
++ * @trans_maxsize: actual maximum msize supported by transport channel
+  * @proto_version: 9P protocol version to use
+  * @trans_mod: module API instantiated with this client
+  * @status: connection state
+@@ -101,6 +102,7 @@ struct p9_req_t {
+ struct p9_client {
+ 	spinlock_t lock;
+ 	unsigned int msize;
++	unsigned int trans_maxsize;
+ 	unsigned char proto_version;
+ 	struct p9_trans_module *trans_mod;
+ 	enum p9_trans_status status;
+diff --git a/net/9p/client.c b/net/9p/client.c
+index 8bba0d9cf975..20054addd81b 100644
+--- a/net/9p/client.c
++++ b/net/9p/client.c
+@@ -1031,6 +1031,14 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
+ 		goto free_client;
  	}
  
 +	/*
-+	 * if user supplied an 'msize' option that's larger than what this
-+	 * transport supports by default, then try to allocate more sg lists
++	 * transport will get a chance to increase trans_maxsize (if
++	 * necessary) and it may update trans_maxsize in create() function
++	 * below accordingly to reflect the actual maximum size supported by
++	 * the allocated transport channel
 +	 */
-+	if (client->msize > client->trans_maxsize) {
-+#ifdef CONFIG_ARCH_NO_SG_CHAIN
-+		pr_info("limiting 'msize' to %d because architecture does not "
-+			"support chained scatter gather lists\n",
-+			client->trans_maxsize);
-+#else
-+		npages = DIV_ROUND_UP(client->msize, PAGE_SIZE);
-+		if (npages > VIRTIO_MAX_DESCRIPTORS)
-+			npages = VIRTIO_MAX_DESCRIPTORS;
-+		if (npages > chan->p9_max_pages) {
-+			npages = chan->p9_max_pages;
-+			pr_info("limiting 'msize' as it would exceed the max. "
-+				"of %lu pages allowed on this system\n",
-+				chan->p9_max_pages);
-+		}
-+		nsgl = DIV_ROUND_UP(npages, SG_USER_PAGES_PER_LIST);
-+		if (nsgl > chan->vq_sg->nsgl) {
-+			/*
-+			 * if resize fails, no big deal, then just continue with
-+			 * whatever we got
-+			 */
-+			if (!vq_sg_resize(&chan->vq_sg, nsgl)) {
-+				/*
-+				 * decrement 2 pages as both 9p request and 9p reply have
-+				 * to fit into the virtio round-trip message
-+				 */
-+				client->trans_maxsize =
-+					PAGE_SIZE *
-+					clamp_t(int,
-+						(nsgl * SG_USER_PAGES_PER_LIST) - 2,
-+						0, VIRTIO_MAX_DESCRIPTORS - 2);
-+			}
-+		}
-+#endif /* CONFIG_ARCH_NO_SG_CHAIN */
-+	}
++	clnt->trans_maxsize = clnt->trans_mod->maxsize;
 +
- 	client->trans = (void *)chan;
- 	client->status = Connected;
- 	chan->client = client;
+ 	p9_debug(P9_DEBUG_MUX, "clnt %p trans %p msize %d protocol %d\n",
+ 		 clnt, clnt->trans_mod, clnt->msize, clnt->proto_version);
+ 
+@@ -1038,8 +1046,8 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
+ 	if (err)
+ 		goto put_trans;
+ 
+-	if (clnt->msize > clnt->trans_mod->maxsize) {
+-		clnt->msize = clnt->trans_mod->maxsize;
++	if (clnt->msize > clnt->trans_maxsize) {
++		clnt->msize = clnt->trans_maxsize;
+ 		pr_info("Limiting 'msize' to %d as this is the maximum "
+ 			"supported by transport %s\n",
+ 			clnt->msize, clnt->trans_mod->name
 -- 
 2.30.2
 
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help