@@ -83,6 +83,18 @@ module_param_named(max_persistent_grants, xen_blkif_max_pgrants, int, 0644);
83
83
MODULE_PARM_DESC (max_persistent_grants ,
84
84
"Maximum number of grants to map persistently" );
85
85
86
+ /*
87
+ * How long a persistent grant is allowed to remain allocated without being in
88
+ * use. The time is in seconds, 0 means indefinitely long.
89
+ */
90
+
91
+ static unsigned int xen_blkif_pgrant_timeout = 60 ;
92
+ module_param_named (persistent_grant_unused_seconds , xen_blkif_pgrant_timeout ,
93
+ uint , 0644 );
94
+ MODULE_PARM_DESC (persistent_grant_unused_seconds ,
95
+ "Time in seconds an unused persistent grant is allowed to "
96
+ "remain allocated. Default is 60, 0 means unlimited." );
97
+
86
98
/*
87
99
* Maximum number of rings/queues blkback supports, allow as many queues as there
88
100
* are CPUs if user has not specified a value.
@@ -123,6 +135,13 @@ module_param(log_stats, int, 0644);
123
135
/* Number of free pages to remove on each call to gnttab_free_pages */
124
136
#define NUM_BATCH_FREE_PAGES 10
125
137
138
+ static inline bool persistent_gnt_timeout (struct persistent_gnt * persistent_gnt )
139
+ {
140
+ return xen_blkif_pgrant_timeout &&
141
+ (jiffies - persistent_gnt -> last_used >=
142
+ HZ * xen_blkif_pgrant_timeout );
143
+ }
144
+
126
145
static inline int get_free_page (struct xen_blkif_ring * ring , struct page * * page )
127
146
{
128
147
unsigned long flags ;
@@ -236,8 +255,7 @@ static int add_persistent_gnt(struct xen_blkif_ring *ring,
236
255
}
237
256
}
238
257
239
- bitmap_zero (persistent_gnt -> flags , PERSISTENT_GNT_FLAGS_SIZE );
240
- set_bit (PERSISTENT_GNT_ACTIVE , persistent_gnt -> flags );
258
+ persistent_gnt -> active = true;
241
259
/* Add new node and rebalance tree. */
242
260
rb_link_node (& (persistent_gnt -> node ), parent , new );
243
261
rb_insert_color (& (persistent_gnt -> node ), & ring -> persistent_gnts );
@@ -261,11 +279,11 @@ static struct persistent_gnt *get_persistent_gnt(struct xen_blkif_ring *ring,
261
279
else if (gref > data -> gnt )
262
280
node = node -> rb_right ;
263
281
else {
264
- if ( test_bit ( PERSISTENT_GNT_ACTIVE , data -> flags ) ) {
282
+ if ( data -> active ) {
265
283
pr_alert_ratelimited ("requesting a grant already in use\n" );
266
284
return NULL ;
267
285
}
268
- set_bit ( PERSISTENT_GNT_ACTIVE , data -> flags ) ;
286
+ data -> active = true ;
269
287
atomic_inc (& ring -> persistent_gnt_in_use );
270
288
return data ;
271
289
}
@@ -276,10 +294,10 @@ static struct persistent_gnt *get_persistent_gnt(struct xen_blkif_ring *ring,
276
294
static void put_persistent_gnt (struct xen_blkif_ring * ring ,
277
295
struct persistent_gnt * persistent_gnt )
278
296
{
279
- if (! test_bit ( PERSISTENT_GNT_ACTIVE , persistent_gnt -> flags ) )
297
+ if (! persistent_gnt -> active )
280
298
pr_alert_ratelimited ("freeing a grant already unused\n" );
281
- set_bit ( PERSISTENT_GNT_WAS_ACTIVE , persistent_gnt -> flags ) ;
282
- clear_bit ( PERSISTENT_GNT_ACTIVE , persistent_gnt -> flags ) ;
299
+ persistent_gnt -> last_used = jiffies ;
300
+ persistent_gnt -> active = false ;
283
301
atomic_dec (& ring -> persistent_gnt_in_use );
284
302
}
285
303
@@ -371,26 +389,26 @@ static void purge_persistent_gnt(struct xen_blkif_ring *ring)
371
389
struct persistent_gnt * persistent_gnt ;
372
390
struct rb_node * n ;
373
391
unsigned int num_clean , total ;
374
- bool scan_used = false, clean_used = false ;
392
+ bool scan_used = false;
375
393
struct rb_root * root ;
376
394
377
- if (ring -> persistent_gnt_c < xen_blkif_max_pgrants ||
378
- (ring -> persistent_gnt_c == xen_blkif_max_pgrants &&
379
- !ring -> blkif -> vbd .overflow_max_grants )) {
380
- goto out ;
381
- }
382
-
383
395
if (work_busy (& ring -> persistent_purge_work )) {
384
396
pr_alert_ratelimited ("Scheduled work from previous purge is still busy, cannot purge list\n" );
385
397
goto out ;
386
398
}
387
399
388
- num_clean = (xen_blkif_max_pgrants / 100 ) * LRU_PERCENT_CLEAN ;
389
- num_clean = ring -> persistent_gnt_c - xen_blkif_max_pgrants + num_clean ;
390
- num_clean = min (ring -> persistent_gnt_c , num_clean );
391
- if ((num_clean == 0 ) ||
392
- (num_clean > (ring -> persistent_gnt_c - atomic_read (& ring -> persistent_gnt_in_use ))))
393
- goto out ;
400
+ if (ring -> persistent_gnt_c < xen_blkif_max_pgrants ||
401
+ (ring -> persistent_gnt_c == xen_blkif_max_pgrants &&
402
+ !ring -> blkif -> vbd .overflow_max_grants )) {
403
+ num_clean = 0 ;
404
+ } else {
405
+ num_clean = (xen_blkif_max_pgrants / 100 ) * LRU_PERCENT_CLEAN ;
406
+ num_clean = ring -> persistent_gnt_c - xen_blkif_max_pgrants +
407
+ num_clean ;
408
+ num_clean = min (ring -> persistent_gnt_c , num_clean );
409
+ pr_debug ("Going to purge at least %u persistent grants\n" ,
410
+ num_clean );
411
+ }
394
412
395
413
/*
396
414
* At this point, we can assure that there will be no calls
@@ -401,9 +419,7 @@ static void purge_persistent_gnt(struct xen_blkif_ring *ring)
401
419
* number of grants.
402
420
*/
403
421
404
- total = num_clean ;
405
-
406
- pr_debug ("Going to purge %u persistent grants\n" , num_clean );
422
+ total = 0 ;
407
423
408
424
BUG_ON (!list_empty (& ring -> persistent_purge_list ));
409
425
root = & ring -> persistent_gnts ;
@@ -412,46 +428,37 @@ static void purge_persistent_gnt(struct xen_blkif_ring *ring)
412
428
BUG_ON (persistent_gnt -> handle ==
413
429
BLKBACK_INVALID_HANDLE );
414
430
415
- if (clean_used ) {
416
- clear_bit (PERSISTENT_GNT_WAS_ACTIVE , persistent_gnt -> flags );
431
+ if (persistent_gnt -> active )
417
432
continue ;
418
- }
419
-
420
- if (test_bit (PERSISTENT_GNT_ACTIVE , persistent_gnt -> flags ))
433
+ if (!scan_used && !persistent_gnt_timeout (persistent_gnt ))
421
434
continue ;
422
- if (!scan_used &&
423
- (test_bit (PERSISTENT_GNT_WAS_ACTIVE , persistent_gnt -> flags )))
435
+ if (scan_used && total >= num_clean )
424
436
continue ;
425
437
426
438
rb_erase (& persistent_gnt -> node , root );
427
439
list_add (& persistent_gnt -> remove_node ,
428
440
& ring -> persistent_purge_list );
429
- if (-- num_clean == 0 )
430
- goto finished ;
441
+ total ++ ;
431
442
}
432
443
/*
433
- * If we get here it means we also need to start cleaning
444
+ * Check whether we also need to start cleaning
434
445
* grants that were used since last purge in order to cope
435
446
* with the requested num
436
447
*/
437
- if (!scan_used && ! clean_used ) {
438
- pr_debug ("Still missing %u purged frames\n" , num_clean );
448
+ if (!scan_used && total < num_clean ) {
449
+ pr_debug ("Still missing %u purged frames\n" , num_clean - total );
439
450
scan_used = true;
440
451
goto purge_list ;
441
452
}
442
- finished :
443
- if (!clean_used ) {
444
- pr_debug ("Finished scanning for grants to clean, removing used flag\n" );
445
- clean_used = true;
446
- goto purge_list ;
447
- }
448
453
449
- ring -> persistent_gnt_c -= (total - num_clean );
450
- ring -> blkif -> vbd .overflow_max_grants = 0 ;
454
+ if (total ) {
455
+ ring -> persistent_gnt_c -= total ;
456
+ ring -> blkif -> vbd .overflow_max_grants = 0 ;
451
457
452
- /* We can defer this work */
453
- schedule_work (& ring -> persistent_purge_work );
454
- pr_debug ("Purged %u/%u\n" , (total - num_clean ), total );
458
+ /* We can defer this work */
459
+ schedule_work (& ring -> persistent_purge_work );
460
+ pr_debug ("Purged %u/%u\n" , num_clean , total );
461
+ }
455
462
456
463
out :
457
464
return ;
0 commit comments