Skip to content

Commit 36f9967

Browse files
Stefano StabelliniDominique Martinet
authored andcommitted
9p/xen: increase XEN_9PFS_RING_ORDER
Increase XEN_9PFS_RING_ORDER to 9 for performance reason. Order 9 is the max allowed by the protocol. We can't assume that all backends will support order 9. The xenstore property max-ring-page-order specifies the max order supported by the backend. We'll use max-ring-page-order for the size of the ring. This means that the size of the ring is not static (XEN_FLEX_RING_SIZE(9)) anymore. Change XEN_9PFS_RING_SIZE to take an argument and base the calculation on the order chosen at setup time. Finally, modify p9_xen_trans.maxsize to be divided by 4 compared to the original value. We need to divide it by 2 because we have two rings coming off the same order allocation: the in and out rings. This was a mistake in the original code. Also divide it further by 2 because we don't want a single request/reply to fill up the entire ring. There can be multiple requests/replies outstanding at any given time and if we use the full ring with one, we risk forcing the backend to wait for the client to read back more replies before continuing, which is not performant. Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Stefano Stabellini <[email protected]> Signed-off-by: Dominique Martinet <[email protected]>
1 parent 3d77e6a commit 36f9967

File tree

1 file changed

+34
-27
lines changed

1 file changed

+34
-27
lines changed

net/9p/trans_xen.c

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@
4343
#include <net/9p/transport.h>
4444

4545
#define XEN_9PFS_NUM_RINGS 2
46-
#define XEN_9PFS_RING_ORDER 6
47-
#define XEN_9PFS_RING_SIZE XEN_FLEX_RING_SIZE(XEN_9PFS_RING_ORDER)
46+
#define XEN_9PFS_RING_ORDER 9
47+
#define XEN_9PFS_RING_SIZE(ring) XEN_FLEX_RING_SIZE(ring->intf->ring_order)
4848

4949
struct xen_9pfs_header {
5050
uint32_t size;
@@ -132,8 +132,8 @@ static bool p9_xen_write_todo(struct xen_9pfs_dataring *ring, RING_IDX size)
132132
prod = ring->intf->out_prod;
133133
virt_mb();
134134

135-
return XEN_9PFS_RING_SIZE -
136-
xen_9pfs_queued(prod, cons, XEN_9PFS_RING_SIZE) >= size;
135+
return XEN_9PFS_RING_SIZE(ring) -
136+
xen_9pfs_queued(prod, cons, XEN_9PFS_RING_SIZE(ring)) >= size;
137137
}
138138

139139
static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req)
@@ -167,17 +167,18 @@ static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req)
167167
prod = ring->intf->out_prod;
168168
virt_mb();
169169

170-
if (XEN_9PFS_RING_SIZE - xen_9pfs_queued(prod, cons,
171-
XEN_9PFS_RING_SIZE) < size) {
170+
if (XEN_9PFS_RING_SIZE(ring) -
171+
xen_9pfs_queued(prod, cons, XEN_9PFS_RING_SIZE(ring)) < size) {
172172
spin_unlock_irqrestore(&ring->lock, flags);
173173
goto again;
174174
}
175175

176-
masked_prod = xen_9pfs_mask(prod, XEN_9PFS_RING_SIZE);
177-
masked_cons = xen_9pfs_mask(cons, XEN_9PFS_RING_SIZE);
176+
masked_prod = xen_9pfs_mask(prod, XEN_9PFS_RING_SIZE(ring));
177+
masked_cons = xen_9pfs_mask(cons, XEN_9PFS_RING_SIZE(ring));
178178

179179
xen_9pfs_write_packet(ring->data.out, p9_req->tc.sdata, size,
180-
&masked_prod, masked_cons, XEN_9PFS_RING_SIZE);
180+
&masked_prod, masked_cons,
181+
XEN_9PFS_RING_SIZE(ring));
181182

182183
p9_req->status = REQ_STATUS_SENT;
183184
virt_wmb(); /* write ring before updating pointer */
@@ -207,19 +208,19 @@ static void p9_xen_response(struct work_struct *work)
207208
prod = ring->intf->in_prod;
208209
virt_rmb();
209210

210-
if (xen_9pfs_queued(prod, cons, XEN_9PFS_RING_SIZE) <
211+
if (xen_9pfs_queued(prod, cons, XEN_9PFS_RING_SIZE(ring)) <
211212
sizeof(h)) {
212213
notify_remote_via_irq(ring->irq);
213214
return;
214215
}
215216

216-
masked_prod = xen_9pfs_mask(prod, XEN_9PFS_RING_SIZE);
217-
masked_cons = xen_9pfs_mask(cons, XEN_9PFS_RING_SIZE);
217+
masked_prod = xen_9pfs_mask(prod, XEN_9PFS_RING_SIZE(ring));
218+
masked_cons = xen_9pfs_mask(cons, XEN_9PFS_RING_SIZE(ring));
218219

219220
/* First, read just the header */
220221
xen_9pfs_read_packet(&h, ring->data.in, sizeof(h),
221222
masked_prod, &masked_cons,
222-
XEN_9PFS_RING_SIZE);
223+
XEN_9PFS_RING_SIZE(ring));
223224

224225
req = p9_tag_lookup(priv->client, h.tag);
225226
if (!req || req->status != REQ_STATUS_SENT) {
@@ -233,11 +234,11 @@ static void p9_xen_response(struct work_struct *work)
233234
memcpy(&req->rc, &h, sizeof(h));
234235
req->rc.offset = 0;
235236

236-
masked_cons = xen_9pfs_mask(cons, XEN_9PFS_RING_SIZE);
237+
masked_cons = xen_9pfs_mask(cons, XEN_9PFS_RING_SIZE(ring));
237238
/* Then, read the whole packet (including the header) */
238239
xen_9pfs_read_packet(req->rc.sdata, ring->data.in, h.size,
239240
masked_prod, &masked_cons,
240-
XEN_9PFS_RING_SIZE);
241+
XEN_9PFS_RING_SIZE(ring));
241242

242243
virt_mb();
243244
cons += h.size;
@@ -267,7 +268,7 @@ static irqreturn_t xen_9pfs_front_event_handler(int irq, void *r)
267268

268269
static struct p9_trans_module p9_xen_trans = {
269270
.name = "xen",
270-
.maxsize = 1 << (XEN_9PFS_RING_ORDER + XEN_PAGE_SHIFT),
271+
.maxsize = 1 << (XEN_9PFS_RING_ORDER + XEN_PAGE_SHIFT - 2),
271272
.def = 1,
272273
.create = p9_xen_create,
273274
.close = p9_xen_close,
@@ -295,14 +296,16 @@ static void xen_9pfs_front_free(struct xen_9pfs_front_priv *priv)
295296
if (priv->rings[i].irq > 0)
296297
unbind_from_irqhandler(priv->rings[i].irq, priv->dev);
297298
if (priv->rings[i].data.in) {
298-
for (j = 0; j < (1 << XEN_9PFS_RING_ORDER); j++) {
299+
for (j = 0;
300+
j < (1 << priv->rings[i].intf->ring_order);
301+
j++) {
299302
grant_ref_t ref;
300303

301304
ref = priv->rings[i].intf->ref[j];
302305
gnttab_end_foreign_access(ref, 0, 0);
303306
}
304307
free_pages((unsigned long)priv->rings[i].data.in,
305-
XEN_9PFS_RING_ORDER -
308+
priv->rings[i].intf->ring_order -
306309
(PAGE_SHIFT - XEN_PAGE_SHIFT));
307310
}
308311
gnttab_end_foreign_access(priv->rings[i].ref, 0, 0);
@@ -323,7 +326,8 @@ static int xen_9pfs_front_remove(struct xenbus_device *dev)
323326
}
324327

325328
static int xen_9pfs_front_alloc_dataring(struct xenbus_device *dev,
326-
struct xen_9pfs_dataring *ring)
329+
struct xen_9pfs_dataring *ring,
330+
unsigned int order)
327331
{
328332
int i = 0;
329333
int ret = -ENOMEM;
@@ -342,21 +346,21 @@ static int xen_9pfs_front_alloc_dataring(struct xenbus_device *dev,
342346
goto out;
343347
ring->ref = ret;
344348
bytes = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
345-
XEN_9PFS_RING_ORDER - (PAGE_SHIFT - XEN_PAGE_SHIFT));
349+
order - (PAGE_SHIFT - XEN_PAGE_SHIFT));
346350
if (!bytes) {
347351
ret = -ENOMEM;
348352
goto out;
349353
}
350-
for (; i < (1 << XEN_9PFS_RING_ORDER); i++) {
354+
for (; i < (1 << order); i++) {
351355
ret = gnttab_grant_foreign_access(
352356
dev->otherend_id, virt_to_gfn(bytes) + i, 0);
353357
if (ret < 0)
354358
goto out;
355359
ring->intf->ref[i] = ret;
356360
}
357-
ring->intf->ring_order = XEN_9PFS_RING_ORDER;
361+
ring->intf->ring_order = order;
358362
ring->data.in = bytes;
359-
ring->data.out = bytes + XEN_9PFS_RING_SIZE;
363+
ring->data.out = bytes + XEN_FLEX_RING_SIZE(order);
360364

361365
ret = xenbus_alloc_evtchn(dev, &ring->evtchn);
362366
if (ret)
@@ -374,7 +378,7 @@ static int xen_9pfs_front_alloc_dataring(struct xenbus_device *dev,
374378
for (i--; i >= 0; i--)
375379
gnttab_end_foreign_access(ring->intf->ref[i], 0, 0);
376380
free_pages((unsigned long)bytes,
377-
XEN_9PFS_RING_ORDER -
381+
ring->intf->ring_order -
378382
(PAGE_SHIFT - XEN_PAGE_SHIFT));
379383
}
380384
gnttab_end_foreign_access(ring->ref, 0, 0);
@@ -404,8 +408,10 @@ static int xen_9pfs_front_probe(struct xenbus_device *dev,
404408
return -EINVAL;
405409
max_ring_order = xenbus_read_unsigned(dev->otherend,
406410
"max-ring-page-order", 0);
407-
if (max_ring_order < XEN_9PFS_RING_ORDER)
408-
return -EINVAL;
411+
if (max_ring_order > XEN_9PFS_RING_ORDER)
412+
max_ring_order = XEN_9PFS_RING_ORDER;
413+
if (p9_xen_trans.maxsize > XEN_FLEX_RING_SIZE(max_ring_order))
414+
p9_xen_trans.maxsize = XEN_FLEX_RING_SIZE(max_ring_order) / 2;
409415

410416
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
411417
if (!priv)
@@ -422,7 +428,8 @@ static int xen_9pfs_front_probe(struct xenbus_device *dev,
422428

423429
for (i = 0; i < priv->num_rings; i++) {
424430
priv->rings[i].priv = priv;
425-
ret = xen_9pfs_front_alloc_dataring(dev, &priv->rings[i]);
431+
ret = xen_9pfs_front_alloc_dataring(dev, &priv->rings[i],
432+
max_ring_order);
426433
if (ret < 0)
427434
goto error;
428435
}

0 commit comments

Comments
 (0)