]>
Commit | Line | Data |
---|---|---|
101a7448 ŁK |
1 | dm-crypt: avoid deadlock in mempools |
2 | ||
3 | This patch fixes a theoretical deadlock introduced in the previous patch. | |
4 | ||
5 | The function crypt_alloc_buffer may be called concurrently. If we allocate | |
6 | from the mempool concurrently, there is a possibility of deadlock. | |
7 | For example, if we have mempool of 256 pages, two processes, each wanting 256, | |
8 | pages allocate from the mempool concurrently, it may deadlock in a situation | |
9 | where both processes have allocated 128 pages and the mempool is exhausted. | |
10 | ||
11 | In order to avoid this scenarios, we allocate the pages under a mutex. | |
12 | ||
13 | In order to not degrade performance with excessive locking, we try | |
14 | non-blocking allocations without a mutex first and if it fails, we fallback | |
15 | to a blocking allocation with a mutex. | |
16 | ||
17 | Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> | |
18 | ||
19 | --- | |
20 | drivers/md/dm-crypt.c | 36 +++++++++++++++++++++++++++++++++--- | |
21 | 1 file changed, 33 insertions(+), 3 deletions(-) | |
22 | ||
39348b5e | 23 | Index: linux-3.10.4-fast/drivers/md/dm-crypt.c |
101a7448 | 24 | =================================================================== |
39348b5e ŁK |
25 | --- linux-3.10.4-fast.orig/drivers/md/dm-crypt.c 2013-07-31 17:03:21.000000000 +0200 |
26 | +++ linux-3.10.4-fast/drivers/md/dm-crypt.c 2013-07-31 17:03:24.000000000 +0200 | |
101a7448 ŁK |
27 | @@ -118,6 +118,7 @@ struct crypt_config { |
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; | |
35 | @@ -780,24 +781,46 @@ static void crypt_free_buffer_pages(stru | |
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; | |
58 | + gfp_t gfp_mask = GFP_NOWAIT | __GFP_HIGHMEM; | |
59 | unsigned i, len; | |
60 | struct page *page; | |
61 | ||
62 | +retry: | |
63 | + if (unlikely(gfp_mask & __GFP_WAIT)) | |
64 | + mutex_lock(&cc->bio_alloc_lock); | |
65 | + | |
66 | clone = bio_alloc_bioset(GFP_NOIO, nr_iovecs, cc->bs); | |
67 | if (!clone) | |
68 | - return NULL; | |
69 | + goto return_clone; | |
70 | ||
71 | clone_init(io, clone); | |
72 | ||
73 | for (i = 0; i < nr_iovecs; i++) { | |
74 | page = mempool_alloc(cc->page_pool, gfp_mask); | |
75 | + if (!page) { | |
76 | + crypt_free_buffer_pages(cc, clone); | |
77 | + bio_put(clone); | |
78 | + gfp_mask |= __GFP_WAIT; | |
79 | + goto retry; | |
80 | + } | |
81 | ||
82 | len = (size > PAGE_SIZE) ? PAGE_SIZE : size; | |
83 | ||
39348b5e | 84 | @@ -806,12 +829,17 @@ static struct bio *crypt_alloc_buffer(st |
101a7448 ŁK |
85 | mempool_free(page, cc->page_pool); |
86 | crypt_free_buffer_pages(cc, clone); | |
87 | bio_put(clone); | |
88 | - return NULL; | |
89 | + clone = NULL; | |
90 | + goto return_clone; | |
91 | } | |
92 | ||
93 | size -= len; | |
94 | } | |
95 | ||
96 | +return_clone: | |
97 | + if (unlikely(gfp_mask & __GFP_WAIT)) | |
98 | + mutex_unlock(&cc->bio_alloc_lock); | |
99 | + | |
100 | return clone; | |
101 | } | |
102 | ||
39348b5e | 103 | @@ -1483,6 +1511,8 @@ static int crypt_ctr(struct dm_target *t |
101a7448 ŁK |
104 | goto bad; |
105 | } | |
106 | ||
107 | + mutex_init(&cc->bio_alloc_lock); | |
108 | + | |
109 | ret = -EINVAL; | |
110 | if (sscanf(argv[2], "%llu%c", &tmpll, &dummy) != 1) { | |
111 | ti->error = "Invalid iv_offset sector"; |