Skip to content

Commit 79fbd05

Browse files
Mikulas Patockagregkh
authored andcommitted
dm crypt: limit the number of allocated pages
commit 5059353 upstream. dm-crypt consumes an excessive amount memory when the user attempts to zero a dm-crypt device with "blkdiscard -z". The command "blkdiscard -z" calls the BLKZEROOUT ioctl, it goes to the function __blkdev_issue_zeroout, __blkdev_issue_zeroout sends a large amount of write bios that contain the zero page as their payload. For each incoming page, dm-crypt allocates another page that holds the encrypted data, so when processing "blkdiscard -z", dm-crypt tries to allocate the amount of memory that is equal to the size of the device. This can trigger OOM killer or cause system crash. Fix this by limiting the amount of memory that dm-crypt allocates to 2% of total system memory. This limit is system-wide and is divided by the number of active dm-crypt devices and each device receives an equal share. Cc: [email protected] Signed-off-by: Mikulas Patocka <[email protected]> Signed-off-by: Mike Snitzer <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent e7793f2 commit 79fbd05

File tree

1 file changed

+65
-1
lines changed

1 file changed

+65
-1
lines changed

drivers/md/dm-crypt.c

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ struct crypt_config {
148148
mempool_t *tag_pool;
149149
unsigned tag_pool_max_sectors;
150150

151+
struct percpu_counter n_allocated_pages;
152+
151153
struct bio_set *bs;
152154
struct mutex bio_alloc_lock;
153155

@@ -219,6 +221,12 @@ struct crypt_config {
219221
#define MAX_TAG_SIZE 480
220222
#define POOL_ENTRY_SIZE 512
221223

224+
static DEFINE_SPINLOCK(dm_crypt_clients_lock);
225+
static unsigned dm_crypt_clients_n = 0;
226+
static volatile unsigned long dm_crypt_pages_per_client;
227+
#define DM_CRYPT_MEMORY_PERCENT 2
228+
#define DM_CRYPT_MIN_PAGES_PER_CLIENT (BIO_MAX_PAGES * 16)
229+
222230
static void clone_init(struct dm_crypt_io *, struct bio *);
223231
static void kcryptd_queue_crypt(struct dm_crypt_io *io);
224232
static struct scatterlist *crypt_get_sg_data(struct crypt_config *cc,
@@ -2156,6 +2164,43 @@ static int crypt_wipe_key(struct crypt_config *cc)
21562164
return r;
21572165
}
21582166

2167+
static void crypt_calculate_pages_per_client(void)
2168+
{
2169+
unsigned long pages = (totalram_pages - totalhigh_pages) * DM_CRYPT_MEMORY_PERCENT / 100;
2170+
2171+
if (!dm_crypt_clients_n)
2172+
return;
2173+
2174+
pages /= dm_crypt_clients_n;
2175+
if (pages < DM_CRYPT_MIN_PAGES_PER_CLIENT)
2176+
pages = DM_CRYPT_MIN_PAGES_PER_CLIENT;
2177+
dm_crypt_pages_per_client = pages;
2178+
}
2179+
2180+
static void *crypt_page_alloc(gfp_t gfp_mask, void *pool_data)
2181+
{
2182+
struct crypt_config *cc = pool_data;
2183+
struct page *page;
2184+
2185+
if (unlikely(percpu_counter_compare(&cc->n_allocated_pages, dm_crypt_pages_per_client) >= 0) &&
2186+
likely(gfp_mask & __GFP_NORETRY))
2187+
return NULL;
2188+
2189+
page = alloc_page(gfp_mask);
2190+
if (likely(page != NULL))
2191+
percpu_counter_add(&cc->n_allocated_pages, 1);
2192+
2193+
return page;
2194+
}
2195+
2196+
static void crypt_page_free(void *page, void *pool_data)
2197+
{
2198+
struct crypt_config *cc = pool_data;
2199+
2200+
__free_page(page);
2201+
percpu_counter_sub(&cc->n_allocated_pages, 1);
2202+
}
2203+
21592204
static void crypt_dtr(struct dm_target *ti)
21602205
{
21612206
struct crypt_config *cc = ti->private;
@@ -2182,6 +2227,10 @@ static void crypt_dtr(struct dm_target *ti)
21822227
mempool_destroy(cc->req_pool);
21832228
mempool_destroy(cc->tag_pool);
21842229

2230+
if (cc->page_pool)
2231+
WARN_ON(percpu_counter_sum(&cc->n_allocated_pages) != 0);
2232+
percpu_counter_destroy(&cc->n_allocated_pages);
2233+
21852234
if (cc->iv_gen_ops && cc->iv_gen_ops->dtr)
21862235
cc->iv_gen_ops->dtr(cc);
21872236

@@ -2196,6 +2245,12 @@ static void crypt_dtr(struct dm_target *ti)
21962245

21972246
/* Must zero key material before freeing */
21982247
kzfree(cc);
2248+
2249+
spin_lock(&dm_crypt_clients_lock);
2250+
WARN_ON(!dm_crypt_clients_n);
2251+
dm_crypt_clients_n--;
2252+
crypt_calculate_pages_per_client();
2253+
spin_unlock(&dm_crypt_clients_lock);
21992254
}
22002255

22012256
static int crypt_ctr_ivmode(struct dm_target *ti, const char *ivmode)
@@ -2643,6 +2698,15 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
26432698

26442699
ti->private = cc;
26452700

2701+
spin_lock(&dm_crypt_clients_lock);
2702+
dm_crypt_clients_n++;
2703+
crypt_calculate_pages_per_client();
2704+
spin_unlock(&dm_crypt_clients_lock);
2705+
2706+
ret = percpu_counter_init(&cc->n_allocated_pages, 0, GFP_KERNEL);
2707+
if (ret < 0)
2708+
goto bad;
2709+
26462710
/* Optional parameters need to be read before cipher constructor */
26472711
if (argc > 5) {
26482712
ret = crypt_ctr_optional(ti, argc - 5, &argv[5]);
@@ -2697,7 +2761,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
26972761
ALIGN(sizeof(struct dm_crypt_io) + cc->dmreq_start + additional_req_size,
26982762
ARCH_KMALLOC_MINALIGN);
26992763

2700-
cc->page_pool = mempool_create_page_pool(BIO_MAX_PAGES, 0);
2764+
cc->page_pool = mempool_create(BIO_MAX_PAGES, crypt_page_alloc, crypt_page_free, cc);
27012765
if (!cc->page_pool) {
27022766
ti->error = "Cannot allocate page mempool";
27032767
goto bad;

0 commit comments

Comments
 (0)