aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/xen-blkback
diff options
context:
space:
mode:
authorRoger Pau Monne <roger.pau@citrix.com>2013-06-21 06:56:53 -0400
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2013-06-21 15:58:44 -0400
commit2d9105433ff471d2c688817e98804029c074a623 (patch)
tree7794f24be80ffaad203616bf71162bc6b54c133f /drivers/block/xen-blkback
parent8e3f8755545cc4a7f4da8e9ef76d6d32e0dca576 (diff)
xen-blkback: workaround compiler bug in gcc 4.1
The code generat with gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-54) creates an unbound loop for the second foreach_grant_safe loop in purge_persistent_gnt. The workaround is to avoid having this second loop and instead perform all the work inside the first loop by adding a new variable, clean_used, that will be set when all the desired persistent grants have been removed and we need to iterate over the remaining ones to remove the WAS_ACTIVE flag. Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> Reported-by: Tom O'Neill <toneill@vmem.com> Reported-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'drivers/block/xen-blkback')
-rw-r--r--drivers/block/xen-blkback/blkback.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c
index ea158fe0c9a4..4662217c61be 100644
--- a/drivers/block/xen-blkback/blkback.c
+++ b/drivers/block/xen-blkback/blkback.c
@@ -341,7 +341,7 @@ static void purge_persistent_gnt(struct xen_blkif *blkif)
341 struct persistent_gnt *persistent_gnt; 341 struct persistent_gnt *persistent_gnt;
342 struct rb_node *n; 342 struct rb_node *n;
343 unsigned int num_clean, total; 343 unsigned int num_clean, total;
344 bool scan_used = false; 344 bool scan_used = false, clean_used = false;
345 struct rb_root *root; 345 struct rb_root *root;
346 346
347 if (blkif->persistent_gnt_c < xen_blkif_max_pgrants || 347 if (blkif->persistent_gnt_c < xen_blkif_max_pgrants ||
@@ -358,9 +358,8 @@ static void purge_persistent_gnt(struct xen_blkif *blkif)
358 num_clean = (xen_blkif_max_pgrants / 100) * LRU_PERCENT_CLEAN; 358 num_clean = (xen_blkif_max_pgrants / 100) * LRU_PERCENT_CLEAN;
359 num_clean = blkif->persistent_gnt_c - xen_blkif_max_pgrants + num_clean; 359 num_clean = blkif->persistent_gnt_c - xen_blkif_max_pgrants + num_clean;
360 num_clean = min(blkif->persistent_gnt_c, num_clean); 360 num_clean = min(blkif->persistent_gnt_c, num_clean);
361 if (num_clean > 361 if ((num_clean == 0) ||
362 (blkif->persistent_gnt_c - 362 (num_clean > (blkif->persistent_gnt_c - atomic_read(&blkif->persistent_gnt_in_use))))
363 atomic_read(&blkif->persistent_gnt_in_use)))
364 return; 363 return;
365 364
366 /* 365 /*
@@ -383,6 +382,11 @@ purge_list:
383 BUG_ON(persistent_gnt->handle == 382 BUG_ON(persistent_gnt->handle ==
384 BLKBACK_INVALID_HANDLE); 383 BLKBACK_INVALID_HANDLE);
385 384
385 if (clean_used) {
386 clear_bit(PERSISTENT_GNT_WAS_ACTIVE, persistent_gnt->flags);
387 continue;
388 }
389
386 if (test_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags)) 390 if (test_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags))
387 continue; 391 continue;
388 if (!scan_used && 392 if (!scan_used &&
@@ -400,18 +404,18 @@ purge_list:
400 * grants that were used since last purge in order to cope 404 * grants that were used since last purge in order to cope
401 * with the requested num 405 * with the requested num
402 */ 406 */
403 if (!scan_used) { 407 if (!scan_used && !clean_used) {
404 pr_debug(DRV_PFX "Still missing %u purged frames\n", num_clean); 408 pr_debug(DRV_PFX "Still missing %u purged frames\n", num_clean);
405 scan_used = true; 409 scan_used = true;
406 goto purge_list; 410 goto purge_list;
407 } 411 }
408finished: 412finished:
409 /* Remove the "used" flag from all the persistent grants */ 413 if (!clean_used) {
410 foreach_grant_safe(persistent_gnt, n, root, node) { 414 pr_debug(DRV_PFX "Finished scanning for grants to clean, removing used flag\n");
411 BUG_ON(persistent_gnt->handle == 415 clean_used = true;
412 BLKBACK_INVALID_HANDLE); 416 goto purge_list;
413 clear_bit(PERSISTENT_GNT_WAS_ACTIVE, persistent_gnt->flags);
414 } 417 }
418
415 blkif->persistent_gnt_c -= (total - num_clean); 419 blkif->persistent_gnt_c -= (total - num_clean);
416 blkif->vbd.overflow_max_grants = 0; 420 blkif->vbd.overflow_max_grants = 0;
417 421