aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-verity.c
diff options
context:
space:
mode:
authorMikulas Patocka <mpatocka@redhat.com>2013-03-20 13:21:25 -0400
committerAlasdair G Kergon <agk@redhat.com>2013-03-20 13:21:25 -0400
commit3b6b7813b198b578aa7e04e4047ddb8225c37b7f (patch)
tree3da28b7a3cf8b79b7c48b3875b8483c9de2b2060 /drivers/md/dm-verity.c
parent58051b94e05a59c4d34f9f1a441af40894817c59 (diff)
dm verity: avoid deadlock
A deadlock was found in the prefetch code in the dm verity map function. This patch fixes this by transferring the prefetch to a worker thread and skipping it completely if kmalloc fails. If generic_make_request is called recursively, it queues the I/O request on the current->bio_list without making the I/O request and returns. The routine making the recursive call cannot wait for the I/O to complete. The deadlock occurs when one thread grabs the bufio_client mutex and waits for an I/O to complete but the I/O is queued on another thread's current->bio_list and is waiting to get the mutex held by the first thread. The fix recognises that prefetching is not essential. If memory can be allocated, it queues the prefetch request to the worker thread, but if not, it does nothing. Signed-off-by: Paul Taysom <taysom@chromium.org> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com> Cc: stable@kernel.org
Diffstat (limited to 'drivers/md/dm-verity.c')
-rw-r--r--drivers/md/dm-verity.c39
1 files changed, 34 insertions, 5 deletions
diff --git a/drivers/md/dm-verity.c b/drivers/md/dm-verity.c
index 6ad538375c3c..a746f1d21c66 100644
--- a/drivers/md/dm-verity.c
+++ b/drivers/md/dm-verity.c
@@ -93,6 +93,13 @@ struct dm_verity_io {
93 */ 93 */
94}; 94};
95 95
96struct dm_verity_prefetch_work {
97 struct work_struct work;
98 struct dm_verity *v;
99 sector_t block;
100 unsigned n_blocks;
101};
102
96static struct shash_desc *io_hash_desc(struct dm_verity *v, struct dm_verity_io *io) 103static struct shash_desc *io_hash_desc(struct dm_verity *v, struct dm_verity_io *io)
97{ 104{
98 return (struct shash_desc *)(io + 1); 105 return (struct shash_desc *)(io + 1);
@@ -424,15 +431,18 @@ static void verity_end_io(struct bio *bio, int error)
424 * The root buffer is not prefetched, it is assumed that it will be cached 431 * The root buffer is not prefetched, it is assumed that it will be cached
425 * all the time. 432 * all the time.
426 */ 433 */
427static void verity_prefetch_io(struct dm_verity *v, struct dm_verity_io *io) 434static void verity_prefetch_io(struct work_struct *work)
428{ 435{
436 struct dm_verity_prefetch_work *pw =
437 container_of(work, struct dm_verity_prefetch_work, work);
438 struct dm_verity *v = pw->v;
429 int i; 439 int i;
430 440
431 for (i = v->levels - 2; i >= 0; i--) { 441 for (i = v->levels - 2; i >= 0; i--) {
432 sector_t hash_block_start; 442 sector_t hash_block_start;
433 sector_t hash_block_end; 443 sector_t hash_block_end;
434 verity_hash_at_level(v, io->block, i, &hash_block_start, NULL); 444 verity_hash_at_level(v, pw->block, i, &hash_block_start, NULL);
435 verity_hash_at_level(v, io->block + io->n_blocks - 1, i, &hash_block_end, NULL); 445 verity_hash_at_level(v, pw->block + pw->n_blocks - 1, i, &hash_block_end, NULL);
436 if (!i) { 446 if (!i) {
437 unsigned cluster = ACCESS_ONCE(dm_verity_prefetch_cluster); 447 unsigned cluster = ACCESS_ONCE(dm_verity_prefetch_cluster);
438 448
@@ -452,6 +462,25 @@ no_prefetch_cluster:
452 dm_bufio_prefetch(v->bufio, hash_block_start, 462 dm_bufio_prefetch(v->bufio, hash_block_start,
453 hash_block_end - hash_block_start + 1); 463 hash_block_end - hash_block_start + 1);
454 } 464 }
465
466 kfree(pw);
467}
468
469static void verity_submit_prefetch(struct dm_verity *v, struct dm_verity_io *io)
470{
471 struct dm_verity_prefetch_work *pw;
472
473 pw = kmalloc(sizeof(struct dm_verity_prefetch_work),
474 GFP_NOIO | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN);
475
476 if (!pw)
477 return;
478
479 INIT_WORK(&pw->work, verity_prefetch_io);
480 pw->v = v;
481 pw->block = io->block;
482 pw->n_blocks = io->n_blocks;
483 queue_work(v->verify_wq, &pw->work);
455} 484}
456 485
457/* 486/*
@@ -498,7 +527,7 @@ static int verity_map(struct dm_target *ti, struct bio *bio)
498 memcpy(io->io_vec, bio_iovec(bio), 527 memcpy(io->io_vec, bio_iovec(bio),
499 io->io_vec_size * sizeof(struct bio_vec)); 528 io->io_vec_size * sizeof(struct bio_vec));
500 529
501 verity_prefetch_io(v, io); 530 verity_submit_prefetch(v, io);
502 531
503 generic_make_request(bio); 532 generic_make_request(bio);
504 533
@@ -858,7 +887,7 @@ bad:
858 887
859static struct target_type verity_target = { 888static struct target_type verity_target = {
860 .name = "verity", 889 .name = "verity",
861 .version = {1, 1, 1}, 890 .version = {1, 2, 0},
862 .module = THIS_MODULE, 891 .module = THIS_MODULE,
863 .ctr = verity_ctr, 892 .ctr = verity_ctr,
864 .dtr = verity_dtr, 893 .dtr = verity_dtr,