2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-12-25 13:43:55 +08:00

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>
This commit is contained in:
Mike Snitzer 2014-10-19 07:52:44 -04:00
parent 9d094eebd7
commit 42d6a8ce3c

View File

@ -457,21 +457,32 @@ struct dm_thin_endio_hook {
struct rb_node rb_node; struct rb_node rb_node;
}; };
static void requeue_bio_list(struct thin_c *tc, struct bio_list *master) static void __merge_bio_list(struct bio_list *bios, struct bio_list *master)
{
bio_list_merge(bios, master);
bio_list_init(master);
}
static void error_bio_list(struct bio_list *bios, int error)
{ {
struct bio *bio; struct bio *bio;
while ((bio = bio_list_pop(bios)))
bio_endio(bio, error);
}
static void error_thin_bio_list(struct thin_c *tc, struct bio_list *master, int error)
{
struct bio_list bios; struct bio_list bios;
unsigned long flags; unsigned long flags;
bio_list_init(&bios); bio_list_init(&bios);
spin_lock_irqsave(&tc->lock, flags); spin_lock_irqsave(&tc->lock, flags);
bio_list_merge(&bios, master); __merge_bio_list(&bios, master);
bio_list_init(master);
spin_unlock_irqrestore(&tc->lock, flags); spin_unlock_irqrestore(&tc->lock, flags);
while ((bio = bio_list_pop(&bios))) error_bio_list(&bios, error);
bio_endio(bio, DM_ENDIO_REQUEUE);
} }
static void requeue_deferred_cells(struct thin_c *tc) static void requeue_deferred_cells(struct thin_c *tc)
@ -493,26 +504,18 @@ static void requeue_deferred_cells(struct thin_c *tc)
static void requeue_io(struct thin_c *tc) static void requeue_io(struct thin_c *tc)
{ {
requeue_bio_list(tc, &tc->deferred_bio_list);
requeue_bio_list(tc, &tc->retry_on_resume_list);
requeue_deferred_cells(tc);
}
static void error_thin_retry_list(struct thin_c *tc)
{
struct bio *bio;
unsigned long flags;
struct bio_list bios; struct bio_list bios;
unsigned long flags;
bio_list_init(&bios); bio_list_init(&bios);
spin_lock_irqsave(&tc->lock, flags); spin_lock_irqsave(&tc->lock, flags);
bio_list_merge(&bios, &tc->retry_on_resume_list); __merge_bio_list(&bios, &tc->deferred_bio_list);
bio_list_init(&tc->retry_on_resume_list); __merge_bio_list(&bios, &tc->retry_on_resume_list);
spin_unlock_irqrestore(&tc->lock, flags); spin_unlock_irqrestore(&tc->lock, flags);
while ((bio = bio_list_pop(&bios))) error_bio_list(&bios, DM_ENDIO_REQUEUE);
bio_io_error(bio); requeue_deferred_cells(tc);
} }
static void error_retry_list(struct pool *pool) static void error_retry_list(struct pool *pool)
@ -521,7 +524,7 @@ static void error_retry_list(struct pool *pool)
rcu_read_lock(); rcu_read_lock();
list_for_each_entry_rcu(tc, &pool->active_thins, list) list_for_each_entry_rcu(tc, &pool->active_thins, list)
error_thin_retry_list(tc); error_thin_bio_list(tc, &tc->retry_on_resume_list, -EIO);
rcu_read_unlock(); rcu_read_unlock();
} }
@ -1752,7 +1755,7 @@ static void process_thin_deferred_bios(struct thin_c *tc)
unsigned count = 0; unsigned count = 0;
if (tc->requeue_mode) { if (tc->requeue_mode) {
requeue_bio_list(tc, &tc->deferred_bio_list); error_thin_bio_list(tc, &tc->deferred_bio_list, DM_ENDIO_REQUEUE);
return; return;
} }