43
43
#include <net/9p/transport.h>
44
44
45
45
#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 )
48
48
49
49
struct xen_9pfs_header {
50
50
uint32_t size ;
@@ -132,8 +132,8 @@ static bool p9_xen_write_todo(struct xen_9pfs_dataring *ring, RING_IDX size)
132
132
prod = ring -> intf -> out_prod ;
133
133
virt_mb ();
134
134
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 ;
137
137
}
138
138
139
139
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)
167
167
prod = ring -> intf -> out_prod ;
168
168
virt_mb ();
169
169
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 ) {
172
172
spin_unlock_irqrestore (& ring -> lock , flags );
173
173
goto again ;
174
174
}
175
175
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 ) );
178
178
179
179
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 ));
181
182
182
183
p9_req -> status = REQ_STATUS_SENT ;
183
184
virt_wmb (); /* write ring before updating pointer */
@@ -207,19 +208,19 @@ static void p9_xen_response(struct work_struct *work)
207
208
prod = ring -> intf -> in_prod ;
208
209
virt_rmb ();
209
210
210
- if (xen_9pfs_queued (prod , cons , XEN_9PFS_RING_SIZE ) <
211
+ if (xen_9pfs_queued (prod , cons , XEN_9PFS_RING_SIZE ( ring ) ) <
211
212
sizeof (h )) {
212
213
notify_remote_via_irq (ring -> irq );
213
214
return ;
214
215
}
215
216
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 ) );
218
219
219
220
/* First, read just the header */
220
221
xen_9pfs_read_packet (& h , ring -> data .in , sizeof (h ),
221
222
masked_prod , & masked_cons ,
222
- XEN_9PFS_RING_SIZE );
223
+ XEN_9PFS_RING_SIZE ( ring ) );
223
224
224
225
req = p9_tag_lookup (priv -> client , h .tag );
225
226
if (!req || req -> status != REQ_STATUS_SENT ) {
@@ -233,11 +234,11 @@ static void p9_xen_response(struct work_struct *work)
233
234
memcpy (& req -> rc , & h , sizeof (h ));
234
235
req -> rc .offset = 0 ;
235
236
236
- masked_cons = xen_9pfs_mask (cons , XEN_9PFS_RING_SIZE );
237
+ masked_cons = xen_9pfs_mask (cons , XEN_9PFS_RING_SIZE ( ring ) );
237
238
/* Then, read the whole packet (including the header) */
238
239
xen_9pfs_read_packet (req -> rc .sdata , ring -> data .in , h .size ,
239
240
masked_prod , & masked_cons ,
240
- XEN_9PFS_RING_SIZE );
241
+ XEN_9PFS_RING_SIZE ( ring ) );
241
242
242
243
virt_mb ();
243
244
cons += h .size ;
@@ -267,7 +268,7 @@ static irqreturn_t xen_9pfs_front_event_handler(int irq, void *r)
267
268
268
269
static struct p9_trans_module p9_xen_trans = {
269
270
.name = "xen" ,
270
- .maxsize = 1 << (XEN_9PFS_RING_ORDER + XEN_PAGE_SHIFT ),
271
+ .maxsize = 1 << (XEN_9PFS_RING_ORDER + XEN_PAGE_SHIFT - 2 ),
271
272
.def = 1 ,
272
273
.create = p9_xen_create ,
273
274
.close = p9_xen_close ,
@@ -295,14 +296,16 @@ static void xen_9pfs_front_free(struct xen_9pfs_front_priv *priv)
295
296
if (priv -> rings [i ].irq > 0 )
296
297
unbind_from_irqhandler (priv -> rings [i ].irq , priv -> dev );
297
298
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 ++ ) {
299
302
grant_ref_t ref ;
300
303
301
304
ref = priv -> rings [i ].intf -> ref [j ];
302
305
gnttab_end_foreign_access (ref , 0 , 0 );
303
306
}
304
307
free_pages ((unsigned long )priv -> rings [i ].data .in ,
305
- XEN_9PFS_RING_ORDER -
308
+ priv -> rings [ i ]. intf -> ring_order -
306
309
(PAGE_SHIFT - XEN_PAGE_SHIFT ));
307
310
}
308
311
gnttab_end_foreign_access (priv -> rings [i ].ref , 0 , 0 );
@@ -323,7 +326,8 @@ static int xen_9pfs_front_remove(struct xenbus_device *dev)
323
326
}
324
327
325
328
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 )
327
331
{
328
332
int i = 0 ;
329
333
int ret = - ENOMEM ;
@@ -342,21 +346,21 @@ static int xen_9pfs_front_alloc_dataring(struct xenbus_device *dev,
342
346
goto out ;
343
347
ring -> ref = ret ;
344
348
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 ));
346
350
if (!bytes ) {
347
351
ret = - ENOMEM ;
348
352
goto out ;
349
353
}
350
- for (; i < (1 << XEN_9PFS_RING_ORDER ); i ++ ) {
354
+ for (; i < (1 << order ); i ++ ) {
351
355
ret = gnttab_grant_foreign_access (
352
356
dev -> otherend_id , virt_to_gfn (bytes ) + i , 0 );
353
357
if (ret < 0 )
354
358
goto out ;
355
359
ring -> intf -> ref [i ] = ret ;
356
360
}
357
- ring -> intf -> ring_order = XEN_9PFS_RING_ORDER ;
361
+ ring -> intf -> ring_order = order ;
358
362
ring -> data .in = bytes ;
359
- ring -> data .out = bytes + XEN_9PFS_RING_SIZE ;
363
+ ring -> data .out = bytes + XEN_FLEX_RING_SIZE ( order ) ;
360
364
361
365
ret = xenbus_alloc_evtchn (dev , & ring -> evtchn );
362
366
if (ret )
@@ -374,7 +378,7 @@ static int xen_9pfs_front_alloc_dataring(struct xenbus_device *dev,
374
378
for (i -- ; i >= 0 ; i -- )
375
379
gnttab_end_foreign_access (ring -> intf -> ref [i ], 0 , 0 );
376
380
free_pages ((unsigned long )bytes ,
377
- XEN_9PFS_RING_ORDER -
381
+ ring -> intf -> ring_order -
378
382
(PAGE_SHIFT - XEN_PAGE_SHIFT ));
379
383
}
380
384
gnttab_end_foreign_access (ring -> ref , 0 , 0 );
@@ -404,8 +408,10 @@ static int xen_9pfs_front_probe(struct xenbus_device *dev,
404
408
return - EINVAL ;
405
409
max_ring_order = xenbus_read_unsigned (dev -> otherend ,
406
410
"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 ;
409
415
410
416
priv = kzalloc (sizeof (* priv ), GFP_KERNEL );
411
417
if (!priv )
@@ -422,7 +428,8 @@ static int xen_9pfs_front_probe(struct xenbus_device *dev,
422
428
423
429
for (i = 0 ; i < priv -> num_rings ; i ++ ) {
424
430
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 );
426
433
if (ret < 0 )
427
434
goto error ;
428
435
}
0 commit comments