aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorMikulas Patocka <mpatocka@redhat.com>2012-03-28 13:41:22 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-04-02 12:27:19 -0400
commit48d068c8d59686d228c8154d0781ed5e48361109 (patch)
tree80a716b8957e540fc74316b421bfd2b2d28174ad /drivers/md
parentbc9d8a3ba0a4b0c136c78ba5e35906401d7dc5ba (diff)
dm crypt: fix mempool deadlock
commit aeb2deae2660a1773c83d3c6e9e6575daa3855d6 upstream. This patch fixes a possible deadlock in dm-crypt's mempool use. Currently, dm-crypt reserves a mempool of MIN_BIO_PAGES reserved pages. It allocates first MIN_BIO_PAGES with non-failing allocation (the allocation cannot fail and waits until the mempool is refilled). Further pages are allocated with different gfp flags that allow failing. Because allocations may be done in parallel, this code can deadlock. Example: There are two processes, each tries to allocate MIN_BIO_PAGES and the processes run simultaneously. It may end up in a situation where each process allocates (MIN_BIO_PAGES / 2) pages. The mempool is exhausted. Each process waits for more pages to be freed to the mempool, which never happens. To avoid this deadlock scenario, this patch changes the code so that only the first page is allocated with non-failing gfp mask. Allocation of further pages may fail. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Milan Broz <mbroz@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-crypt.c10
1 files changed, 4 insertions, 6 deletions
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index c8827ffd85b..adedca602bc 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -177,7 +177,6 @@ struct crypt_config {
177 177
178#define MIN_IOS 16 178#define MIN_IOS 16
179#define MIN_POOL_PAGES 32 179#define MIN_POOL_PAGES 32
180#define MIN_BIO_PAGES 8
181 180
182static struct kmem_cache *_crypt_io_pool; 181static struct kmem_cache *_crypt_io_pool;
183 182
@@ -849,12 +848,11 @@ static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned size,
849 } 848 }
850 849
851 /* 850 /*
852 * if additional pages cannot be allocated without waiting, 851 * If additional pages cannot be allocated without waiting,
853 * return a partially allocated bio, the caller will then try 852 * return a partially-allocated bio. The caller will then try
854 * to allocate additional bios while submitting this partial bio 853 * to allocate more bios while submitting this partial bio.
855 */ 854 */
856 if (i == (MIN_BIO_PAGES - 1)) 855 gfp_mask = (gfp_mask | __GFP_NOWARN) & ~__GFP_WAIT;
857 gfp_mask = (gfp_mask | __GFP_NOWARN) & ~__GFP_WAIT;
858 856
859 len = (size > PAGE_SIZE) ? PAGE_SIZE : size; 857 len = (size > PAGE_SIZE) ? PAGE_SIZE : size;
860 858