summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-driver-xen-blkback10
-rw-r--r--drivers/block/xen-blkback/blkback.c88
-rw-r--r--drivers/block/xen-blkback/common.h8
3 files changed, 60 insertions, 46 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-xen-blkback b/Documentation/ABI/testing/sysfs-driver-xen-blkback
index 8bb43b66eb55..4e7babb3ba1f 100644
--- a/Documentation/ABI/testing/sysfs-driver-xen-blkback
+++ b/Documentation/ABI/testing/sysfs-driver-xen-blkback
@@ -15,3 +15,13 @@ Description:
15 blkback. If the frontend tries to use more than 15 blkback. If the frontend tries to use more than
16 max_persistent_grants, the LRU kicks in and starts 16 max_persistent_grants, the LRU kicks in and starts
17 removing 5% of max_persistent_grants every 100ms. 17 removing 5% of max_persistent_grants every 100ms.
18
19What: /sys/module/xen_blkback/parameters/persistent_grant_unused_seconds
20Date: August 2018
21KernelVersion: 4.19
22Contact: Roger Pau Monné <roger.pau@citrix.com>
23Description:
24 How long a persistent grant is allowed to remain
25 allocated without being in use. The time is in
26 seconds, 0 means indefinitely long.
27 The default is 60 seconds.
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c
index b55b245e8052..9eae7b243f68 100644
--- a/drivers/block/xen-blkback/blkback.c
+++ b/drivers/block/xen-blkback/blkback.c
@@ -84,6 +84,18 @@ MODULE_PARM_DESC(max_persistent_grants,
84 "Maximum number of grants to map persistently"); 84 "Maximum number of grants to map persistently");
85 85
86/* 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
91static unsigned int xen_blkif_pgrant_timeout = 60;
92module_param_named(persistent_grant_unused_seconds, xen_blkif_pgrant_timeout,
93 uint, 0644);
94MODULE_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
98/*
87 * Maximum number of rings/queues blkback supports, allow as many queues as there 99 * Maximum number of rings/queues blkback supports, allow as many queues as there
88 * are CPUs if user has not specified a value. 100 * are CPUs if user has not specified a value.
89 */ 101 */
@@ -123,6 +135,13 @@ module_param(log_stats, int, 0644);
123/* Number of free pages to remove on each call to gnttab_free_pages */ 135/* Number of free pages to remove on each call to gnttab_free_pages */
124#define NUM_BATCH_FREE_PAGES 10 136#define NUM_BATCH_FREE_PAGES 10
125 137
138static 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
126static inline int get_free_page(struct xen_blkif_ring *ring, struct page **page) 145static inline int get_free_page(struct xen_blkif_ring *ring, struct page **page)
127{ 146{
128 unsigned long flags; 147 unsigned long flags;
@@ -278,7 +297,7 @@ static void put_persistent_gnt(struct xen_blkif_ring *ring,
278{ 297{
279 if(!test_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags)) 298 if(!test_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags))
280 pr_alert_ratelimited("freeing a grant already unused\n"); 299 pr_alert_ratelimited("freeing a grant already unused\n");
281 set_bit(PERSISTENT_GNT_WAS_ACTIVE, persistent_gnt->flags); 300 persistent_gnt->last_used = jiffies;
282 clear_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags); 301 clear_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags);
283 atomic_dec(&ring->persistent_gnt_in_use); 302 atomic_dec(&ring->persistent_gnt_in_use);
284} 303}
@@ -371,26 +390,26 @@ static void purge_persistent_gnt(struct xen_blkif_ring *ring)
371 struct persistent_gnt *persistent_gnt; 390 struct persistent_gnt *persistent_gnt;
372 struct rb_node *n; 391 struct rb_node *n;
373 unsigned int num_clean, total; 392 unsigned int num_clean, total;
374 bool scan_used = false, clean_used = false; 393 bool scan_used = false;
375 struct rb_root *root; 394 struct rb_root *root;
376 395
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 if (work_busy(&ring->persistent_purge_work)) { 396 if (work_busy(&ring->persistent_purge_work)) {
384 pr_alert_ratelimited("Scheduled work from previous purge is still busy, cannot purge list\n"); 397 pr_alert_ratelimited("Scheduled work from previous purge is still busy, cannot purge list\n");
385 goto out; 398 goto out;
386 } 399 }
387 400
388 num_clean = (xen_blkif_max_pgrants / 100) * LRU_PERCENT_CLEAN; 401 if (ring->persistent_gnt_c < xen_blkif_max_pgrants ||
389 num_clean = ring->persistent_gnt_c - xen_blkif_max_pgrants + num_clean; 402 (ring->persistent_gnt_c == xen_blkif_max_pgrants &&
390 num_clean = min(ring->persistent_gnt_c, num_clean); 403 !ring->blkif->vbd.overflow_max_grants)) {
391 if ((num_clean == 0) || 404 num_clean = 0;
392 (num_clean > (ring->persistent_gnt_c - atomic_read(&ring->persistent_gnt_in_use)))) 405 } else {
393 goto out; 406 num_clean = (xen_blkif_max_pgrants / 100) * LRU_PERCENT_CLEAN;
407 num_clean = ring->persistent_gnt_c - xen_blkif_max_pgrants +
408 num_clean;
409 num_clean = min(ring->persistent_gnt_c, num_clean);
410 pr_debug("Going to purge at least %u persistent grants\n",
411 num_clean);
412 }
394 413
395 /* 414 /*
396 * At this point, we can assure that there will be no calls 415 * At this point, we can assure that there will be no calls
@@ -401,9 +420,7 @@ static void purge_persistent_gnt(struct xen_blkif_ring *ring)
401 * number of grants. 420 * number of grants.
402 */ 421 */
403 422
404 total = num_clean; 423 total = 0;
405
406 pr_debug("Going to purge %u persistent grants\n", num_clean);
407 424
408 BUG_ON(!list_empty(&ring->persistent_purge_list)); 425 BUG_ON(!list_empty(&ring->persistent_purge_list));
409 root = &ring->persistent_gnts; 426 root = &ring->persistent_gnts;
@@ -412,46 +429,37 @@ purge_list:
412 BUG_ON(persistent_gnt->handle == 429 BUG_ON(persistent_gnt->handle ==
413 BLKBACK_INVALID_HANDLE); 430 BLKBACK_INVALID_HANDLE);
414 431
415 if (clean_used) {
416 clear_bit(PERSISTENT_GNT_WAS_ACTIVE, persistent_gnt->flags);
417 continue;
418 }
419
420 if (test_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags)) 432 if (test_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags))
421 continue; 433 continue;
422 if (!scan_used && 434 if (!scan_used && !persistent_gnt_timeout(persistent_gnt))
423 (test_bit(PERSISTENT_GNT_WAS_ACTIVE, persistent_gnt->flags))) 435 continue;
436 if (scan_used && total >= num_clean)
424 continue; 437 continue;
425 438
426 rb_erase(&persistent_gnt->node, root); 439 rb_erase(&persistent_gnt->node, root);
427 list_add(&persistent_gnt->remove_node, 440 list_add(&persistent_gnt->remove_node,
428 &ring->persistent_purge_list); 441 &ring->persistent_purge_list);
429 if (--num_clean == 0) 442 total++;
430 goto finished;
431 } 443 }
432 /* 444 /*
433 * If we get here it means we also need to start cleaning 445 * Check whether we also need to start cleaning
434 * grants that were used since last purge in order to cope 446 * grants that were used since last purge in order to cope
435 * with the requested num 447 * with the requested num
436 */ 448 */
437 if (!scan_used && !clean_used) { 449 if (!scan_used && total < num_clean) {
438 pr_debug("Still missing %u purged frames\n", num_clean); 450 pr_debug("Still missing %u purged frames\n", num_clean - total);
439 scan_used = true; 451 scan_used = true;
440 goto purge_list; 452 goto purge_list;
441 } 453 }
442finished:
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 454
449 ring->persistent_gnt_c -= (total - num_clean); 455 if (total) {
450 ring->blkif->vbd.overflow_max_grants = 0; 456 ring->persistent_gnt_c -= total;
457 ring->blkif->vbd.overflow_max_grants = 0;
451 458
452 /* We can defer this work */ 459 /* We can defer this work */
453 schedule_work(&ring->persistent_purge_work); 460 schedule_work(&ring->persistent_purge_work);
454 pr_debug("Purged %u/%u\n", (total - num_clean), total); 461 pr_debug("Purged %u/%u\n", num_clean, total);
462 }
455 463
456out: 464out:
457 return; 465 return;
diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h
index ecb35fe8ca8d..7bff72db3b7e 100644
--- a/drivers/block/xen-blkback/common.h
+++ b/drivers/block/xen-blkback/common.h
@@ -234,14 +234,9 @@ struct xen_vbd {
234struct backend_info; 234struct backend_info;
235 235
236/* Number of available flags */ 236/* Number of available flags */
237#define PERSISTENT_GNT_FLAGS_SIZE 2 237#define PERSISTENT_GNT_FLAGS_SIZE 1
238/* This persistent grant is currently in use */ 238/* This persistent grant is currently in use */
239#define PERSISTENT_GNT_ACTIVE 0 239#define PERSISTENT_GNT_ACTIVE 0
240/*
241 * This persistent grant has been used, this flag is set when we remove the
242 * PERSISTENT_GNT_ACTIVE, to know that this grant has been used recently.
243 */
244#define PERSISTENT_GNT_WAS_ACTIVE 1
245 240
246/* Number of requests that we can fit in a ring */ 241/* Number of requests that we can fit in a ring */
247#define XEN_BLKIF_REQS_PER_PAGE 32 242#define XEN_BLKIF_REQS_PER_PAGE 32
@@ -250,6 +245,7 @@ struct persistent_gnt {
250 struct page *page; 245 struct page *page;
251 grant_ref_t gnt; 246 grant_ref_t gnt;
252 grant_handle_t handle; 247 grant_handle_t handle;
248 unsigned long last_used;
253 DECLARE_BITMAP(flags, PERSISTENT_GNT_FLAGS_SIZE); 249 DECLARE_BITMAP(flags, PERSISTENT_GNT_FLAGS_SIZE);
254 struct rb_node node; 250 struct rb_node node;
255 struct list_head remove_node; 251 struct list_head remove_node;