]> git.pld-linux.org Git - packages/kernel.git/blame - dm-crypt-fix-allocation-deadlock.patch
fix initrd file for new-kernel-pkg script
[packages/kernel.git] / dm-crypt-fix-allocation-deadlock.patch
CommitLineData
101a7448
ŁK
1dm-crypt: avoid deadlock in mempools
2
3This patch fixes a theoretical deadlock introduced in the previous patch.
4
5The function crypt_alloc_buffer may be called concurrently. If we allocate
6from the mempool concurrently, there is a possibility of deadlock.
7For example, if we have mempool of 256 pages, two processes, each wanting 256,
8pages allocate from the mempool concurrently, it may deadlock in a situation
9where both processes have allocated 128 pages and the mempool is exhausted.
10
11In order to avoid this scenarios, we allocate the pages under a mutex.
12
13In order to not degrade performance with excessive locking, we try
14non-blocking allocations without a mutex first and if it fails, we fallback
15to a blocking allocation with a mutex.
16
17Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
18
19---
0a2e4279
ŁK
20 drivers/md/dm-crypt.c | 41 ++++++++++++++++++++++++++++++++++++-----
21 1 file changed, 36 insertions(+), 5 deletions(-)
101a7448 22
0a2e4279 23Index: linux-3.14/drivers/md/dm-crypt.c
101a7448 24===================================================================
0a2e4279
ŁK
25--- linux-3.14.orig/drivers/md/dm-crypt.c 2014-04-04 20:59:46.000000000 +0200
26+++ linux-3.14/drivers/md/dm-crypt.c 2014-04-04 21:04:40.000000000 +0200
27@@ -124,6 +124,7 @@ struct crypt_config {
101a7448
ŁK
28 mempool_t *req_pool;
29 mempool_t *page_pool;
30 struct bio_set *bs;
31+ struct mutex bio_alloc_lock;
32
33 struct workqueue_struct *io_queue;
34 struct workqueue_struct *crypt_queue;
0a2e4279 35@@ -954,27 +955,51 @@ static void crypt_free_buffer_pages(stru
101a7448
ŁK
36 /*
37 * Generate a new unfragmented bio with the given size
38 * This should never violate the device limitations
39+ *
40+ * This function may be called concurrently. If we allocate from the mempool
41+ * concurrently, there is a possibility of deadlock. For example, if we have
42+ * mempool of 256 pages, two processes, each wanting 256, pages allocate from
43+ * the mempool concurrently, it may deadlock in a situation where both processes
44+ * have allocated 128 pages and the mempool is exhausted.
45+ *
46+ * In order to avoid this scenarios, we allocate the pages under a mutex.
47+ *
48+ * In order to not degrade performance with excessive locking, we try
49+ * non-blocking allocations without a mutex first and if it fails, we fallback
50+ * to a blocking allocation with a mutex.
51 */
52 static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned size)
53 {
54 struct crypt_config *cc = io->cc;
55 struct bio *clone;
56 unsigned int nr_iovecs = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
57- gfp_t gfp_mask = GFP_NOIO | __GFP_HIGHMEM;
0a2e4279 58- unsigned i, len;
101a7448 59+ gfp_t gfp_mask = GFP_NOWAIT | __GFP_HIGHMEM;
0a2e4279 60+ unsigned i, len, remaining_size;
101a7448 61 struct page *page;
0a2e4279 62 struct bio_vec *bvec;
101a7448
ŁK
63
64+retry:
65+ if (unlikely(gfp_mask & __GFP_WAIT))
66+ mutex_lock(&cc->bio_alloc_lock);
67+
68 clone = bio_alloc_bioset(GFP_NOIO, nr_iovecs, cc->bs);
69 if (!clone)
70- return NULL;
71+ goto return_clone;
72
73 clone_init(io, clone);
74
0a2e4279
ŁK
75+ remaining_size = size;
76+
101a7448
ŁK
77 for (i = 0; i < nr_iovecs; i++) {
78 page = mempool_alloc(cc->page_pool, gfp_mask);
79+ if (!page) {
80+ crypt_free_buffer_pages(cc, clone);
81+ bio_put(clone);
82+ gfp_mask |= __GFP_WAIT;
83+ goto retry;
84+ }
85
0a2e4279
ŁK
86- len = (size > PAGE_SIZE) ? PAGE_SIZE : size;
87+ len = (remaining_size > PAGE_SIZE) ? PAGE_SIZE : remaining_size;
88
89 bvec = &clone->bi_io_vec[clone->bi_vcnt++];
90 bvec->bv_page = page;
91@@ -983,9 +1008,13 @@ static struct bio *crypt_alloc_buffer(st
101a7448 92
0a2e4279 93 clone->bi_iter.bi_size += len;
101a7448 94
0a2e4279
ŁK
95- size -= len;
96+ remaining_size -= len;
101a7448
ŁK
97 }
98
99+return_clone:
100+ if (unlikely(gfp_mask & __GFP_WAIT))
101+ mutex_unlock(&cc->bio_alloc_lock);
102+
103 return clone;
104 }
105
0a2e4279 106@@ -1671,6 +1700,8 @@ static int crypt_ctr(struct dm_target *t
101a7448
ŁK
107 goto bad;
108 }
109
110+ mutex_init(&cc->bio_alloc_lock);
111+
112 ret = -EINVAL;
113 if (sscanf(argv[2], "%llu%c", &tmpll, &dummy) != 1) {
114 ti->error = "Invalid iv_offset sector";
This page took 0.060253 seconds and 4 git commands to generate.