diff options
author | Mike Snitzer <snitzer@redhat.com> | 2014-10-19 07:52:44 -0400 |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2014-11-10 15:25:29 -0500 |
commit | 42d6a8ce3c3f70bf77a40ace385f59e1b5b9918f (patch) | |
tree | 2ef4bbd2701d73074c429f784a6eddfee2aaab0a /drivers/md | |
parent | 9d094eebd7fd3d3432a974f46490c32cae35edfe (diff) |
dm thin: refactor requeue_io to eliminate spinlock bouncing
Also refactor some other bio_list erroring helpers.
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/dm-thin.c | 43 |
1 files changed, 23 insertions, 20 deletions
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index 575e3ed723cc..fb05f6a4bbfd 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c | |||
@@ -457,21 +457,32 @@ struct dm_thin_endio_hook { | |||
457 | struct rb_node rb_node; | 457 | struct rb_node rb_node; |
458 | }; | 458 | }; |
459 | 459 | ||
460 | static void requeue_bio_list(struct thin_c *tc, struct bio_list *master) | 460 | static void __merge_bio_list(struct bio_list *bios, struct bio_list *master) |
461 | { | ||
462 | bio_list_merge(bios, master); | ||
463 | bio_list_init(master); | ||
464 | } | ||
465 | |||
466 | static void error_bio_list(struct bio_list *bios, int error) | ||
461 | { | 467 | { |
462 | struct bio *bio; | 468 | struct bio *bio; |
469 | |||
470 | while ((bio = bio_list_pop(bios))) | ||
471 | bio_endio(bio, error); | ||
472 | } | ||
473 | |||
474 | static void error_thin_bio_list(struct thin_c *tc, struct bio_list *master, int error) | ||
475 | { | ||
463 | struct bio_list bios; | 476 | struct bio_list bios; |
464 | unsigned long flags; | 477 | unsigned long flags; |
465 | 478 | ||
466 | bio_list_init(&bios); | 479 | bio_list_init(&bios); |
467 | 480 | ||
468 | spin_lock_irqsave(&tc->lock, flags); | 481 | spin_lock_irqsave(&tc->lock, flags); |
469 | bio_list_merge(&bios, master); | 482 | __merge_bio_list(&bios, master); |
470 | bio_list_init(master); | ||
471 | spin_unlock_irqrestore(&tc->lock, flags); | 483 | spin_unlock_irqrestore(&tc->lock, flags); |
472 | 484 | ||
473 | while ((bio = bio_list_pop(&bios))) | 485 | error_bio_list(&bios, error); |
474 | bio_endio(bio, DM_ENDIO_REQUEUE); | ||
475 | } | 486 | } |
476 | 487 | ||
477 | static void requeue_deferred_cells(struct thin_c *tc) | 488 | static void requeue_deferred_cells(struct thin_c *tc) |
@@ -493,26 +504,18 @@ static void requeue_deferred_cells(struct thin_c *tc) | |||
493 | 504 | ||
494 | static void requeue_io(struct thin_c *tc) | 505 | static void requeue_io(struct thin_c *tc) |
495 | { | 506 | { |
496 | requeue_bio_list(tc, &tc->deferred_bio_list); | ||
497 | requeue_bio_list(tc, &tc->retry_on_resume_list); | ||
498 | requeue_deferred_cells(tc); | ||
499 | } | ||
500 | |||
501 | static void error_thin_retry_list(struct thin_c *tc) | ||
502 | { | ||
503 | struct bio *bio; | ||
504 | unsigned long flags; | ||
505 | struct bio_list bios; | 507 | struct bio_list bios; |
508 | unsigned long flags; | ||
506 | 509 | ||
507 | bio_list_init(&bios); | 510 | bio_list_init(&bios); |
508 | 511 | ||
509 | spin_lock_irqsave(&tc->lock, flags); | 512 | spin_lock_irqsave(&tc->lock, flags); |
510 | bio_list_merge(&bios, &tc->retry_on_resume_list); | 513 | __merge_bio_list(&bios, &tc->deferred_bio_list); |
511 | bio_list_init(&tc->retry_on_resume_list); | 514 | __merge_bio_list(&bios, &tc->retry_on_resume_list); |
512 | spin_unlock_irqrestore(&tc->lock, flags); | 515 | spin_unlock_irqrestore(&tc->lock, flags); |
513 | 516 | ||
514 | while ((bio = bio_list_pop(&bios))) | 517 | error_bio_list(&bios, DM_ENDIO_REQUEUE); |
515 | bio_io_error(bio); | 518 | requeue_deferred_cells(tc); |
516 | } | 519 | } |
517 | 520 | ||
518 | static void error_retry_list(struct pool *pool) | 521 | static void error_retry_list(struct pool *pool) |
@@ -521,7 +524,7 @@ static void error_retry_list(struct pool *pool) | |||
521 | 524 | ||
522 | rcu_read_lock(); | 525 | rcu_read_lock(); |
523 | list_for_each_entry_rcu(tc, &pool->active_thins, list) | 526 | list_for_each_entry_rcu(tc, &pool->active_thins, list) |
524 | error_thin_retry_list(tc); | 527 | error_thin_bio_list(tc, &tc->retry_on_resume_list, -EIO); |
525 | rcu_read_unlock(); | 528 | rcu_read_unlock(); |
526 | } | 529 | } |
527 | 530 | ||
@@ -1752,7 +1755,7 @@ static void process_thin_deferred_bios(struct thin_c *tc) | |||
1752 | unsigned count = 0; | 1755 | unsigned count = 0; |
1753 | 1756 | ||
1754 | if (tc->requeue_mode) { | 1757 | if (tc->requeue_mode) { |
1755 | requeue_bio_list(tc, &tc->deferred_bio_list); | 1758 | error_thin_bio_list(tc, &tc->deferred_bio_list, DM_ENDIO_REQUEUE); |
1756 | return; | 1759 | return; |
1757 | } | 1760 | } |
1758 | 1761 | ||