aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikulas Patocka <mpatocka@redhat.com>2015-02-13 08:24:41 -0500
committerMike Snitzer <snitzer@redhat.com>2015-02-16 11:11:13 -0500
commit7145c241a1bf2841952c3e297c4080b357b3e52d (patch)
tree12c9a8ffce670390ea5b518fbe6d9b64f90f05b9
parentcf2f1abfbd0dba701f7f16ef619e4d2485de3366 (diff)
dm crypt: avoid deadlock in mempools
Fix a theoretical deadlock introduced in the previous commit ("dm crypt: don't allocate pages for a partial request"). The function crypt_alloc_buffer may be called concurrently. If we allocate from the mempool concurrently, there is a possibility of deadlock. For example, if we have mempool of 256 pages, two processes, each wanting 256, pages allocate from the mempool concurrently, it may deadlock in a situation where both processes have allocated 128 pages and the mempool is exhausted. To avoid such a scenario we allocate the pages under a mutex. In order to not degrade performance with excessive locking, we try non-blocking allocations without a mutex first and if that fails, we fallback to a blocking allocations with a mutex. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
-rw-r--r--drivers/md/dm-crypt.c41
1 files changed, 36 insertions, 5 deletions
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 6199245ea6a6..fa1dba1d06f7 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -124,6 +124,7 @@ struct crypt_config {
124 mempool_t *req_pool; 124 mempool_t *req_pool;
125 mempool_t *page_pool; 125 mempool_t *page_pool;
126 struct bio_set *bs; 126 struct bio_set *bs;
127 struct mutex bio_alloc_lock;
127 128
128 struct workqueue_struct *io_queue; 129 struct workqueue_struct *io_queue;
129 struct workqueue_struct *crypt_queue; 130 struct workqueue_struct *crypt_queue;
@@ -949,27 +950,51 @@ static void crypt_free_buffer_pages(struct crypt_config *cc, struct bio *clone);
949/* 950/*
950 * Generate a new unfragmented bio with the given size 951 * Generate a new unfragmented bio with the given size
951 * This should never violate the device limitations 952 * This should never violate the device limitations
953 *
954 * This function may be called concurrently. If we allocate from the mempool
955 * concurrently, there is a possibility of deadlock. For example, if we have
956 * mempool of 256 pages, two processes, each wanting 256, pages allocate from
957 * the mempool concurrently, it may deadlock in a situation where both processes
958 * have allocated 128 pages and the mempool is exhausted.
959 *
960 * In order to avoid this scenario we allocate the pages under a mutex.
961 *
962 * In order to not degrade performance with excessive locking, we try
963 * non-blocking allocations without a mutex first but on failure we fallback
964 * to blocking allocations with a mutex.
952 */ 965 */
953static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned size) 966static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned size)
954{ 967{
955 struct crypt_config *cc = io->cc; 968 struct crypt_config *cc = io->cc;
956 struct bio *clone; 969 struct bio *clone;
957 unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; 970 unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
958 gfp_t gfp_mask = GFP_NOIO | __GFP_HIGHMEM; 971 gfp_t gfp_mask = GFP_NOWAIT | __GFP_HIGHMEM;
959 unsigned i, len; 972 unsigned i, len, remaining_size;
960 struct page *page; 973 struct page *page;
961 struct bio_vec *bvec; 974 struct bio_vec *bvec;
962 975
976retry:
977 if (unlikely(gfp_mask & __GFP_WAIT))
978 mutex_lock(&cc->bio_alloc_lock);
979
963 clone = bio_alloc_bioset(GFP_NOIO, nr_iovecs, cc->bs); 980 clone = bio_alloc_bioset(GFP_NOIO, nr_iovecs, cc->bs);
964 if (!clone) 981 if (!clone)
965 return NULL; 982 goto return_clone;
966 983
967 clone_init(io, clone); 984 clone_init(io, clone);
968 985
986 remaining_size = size;
987
969 for (i = 0; i < nr_iovecs; i++) { 988 for (i = 0; i < nr_iovecs; i++) {
970 page = mempool_alloc(cc->page_pool, gfp_mask); 989 page = mempool_alloc(cc->page_pool, gfp_mask);
990 if (!page) {
991 crypt_free_buffer_pages(cc, clone);
992 bio_put(clone);
993 gfp_mask |= __GFP_WAIT;
994 goto retry;
995 }
971 996
972 len = (size > PAGE_SIZE) ? PAGE_SIZE : size; 997 len = (remaining_size > PAGE_SIZE) ? PAGE_SIZE : remaining_size;
973 998
974 bvec = &clone->bi_io_vec[clone->bi_vcnt++]; 999 bvec = &clone->bi_io_vec[clone->bi_vcnt++];
975 bvec->bv_page = page; 1000 bvec->bv_page = page;
@@ -978,9 +1003,13 @@ static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned size)
978 1003
979 clone->bi_iter.bi_size += len; 1004 clone->bi_iter.bi_size += len;
980 1005
981 size -= len; 1006 remaining_size -= len;
982 } 1007 }
983 1008
1009return_clone:
1010 if (unlikely(gfp_mask & __GFP_WAIT))
1011 mutex_unlock(&cc->bio_alloc_lock);
1012
984 return clone; 1013 return clone;
985} 1014}
986 1015
@@ -1679,6 +1708,8 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
1679 goto bad; 1708 goto bad;
1680 } 1709 }
1681 1710
1711 mutex_init(&cc->bio_alloc_lock);
1712
1682 ret = -EINVAL; 1713 ret = -EINVAL;
1683 if (sscanf(argv[2], "%llu%c", &tmpll, &dummy) != 1) { 1714 if (sscanf(argv[2], "%llu%c", &tmpll, &dummy) != 1) {
1684 ti->error = "Invalid iv_offset sector"; 1715 ti->error = "Invalid iv_offset sector";