diff options
author | Mikulas Patocka <mpatocka@redhat.com> | 2023-06-26 16:46:57 +0200 |
---|---|---|
committer | Mike Snitzer <snitzer@kernel.org> | 2023-06-27 22:05:50 +0200 |
commit | 3be1622895af25101f7046ed0b2286bead2219d4 (patch) | |
tree | fd06a22896a7a4011e3a11c7930e8b50d86f94dc /drivers/md | |
parent | dm integrity: only allocate recalculate buffer when needed (diff) | |
download | linux-3be1622895af25101f7046ed0b2286bead2219d4.tar.xz linux-3be1622895af25101f7046ed0b2286bead2219d4.zip |
dm integrity: scale down the recalculate buffer if memory allocation fails
If memory allocation fails, try to reduce the size of the recalculate
buffer and continue with that smaller buffer.
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@kernel.org>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/dm-integrity.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c index 16d1aa263066..5ca3fc62e8f3 100644 --- a/drivers/md/dm-integrity.c +++ b/drivers/md/dm-integrity.c @@ -2658,19 +2658,25 @@ static void integrity_recalc(struct work_struct *w) unsigned int i; int r; unsigned int super_counter = 0; + unsigned recalc_sectors = RECALC_SECTORS; - recalc_buffer = __vmalloc(RECALC_SECTORS << SECTOR_SHIFT, GFP_NOIO); +retry: + recalc_buffer = __vmalloc(recalc_sectors << SECTOR_SHIFT, GFP_NOIO); if (!recalc_buffer) { +oom: + recalc_sectors >>= 1; + if (recalc_sectors >= 1U << ic->sb->log2_sectors_per_block) + goto retry; DMCRIT("out of memory for recalculate buffer - recalculation disabled"); goto free_ret; } - recalc_tags_size = (RECALC_SECTORS >> ic->sb->log2_sectors_per_block) * ic->tag_size; + recalc_tags_size = (recalc_sectors >> ic->sb->log2_sectors_per_block) * ic->tag_size; if (crypto_shash_digestsize(ic->internal_hash) > ic->tag_size) recalc_tags_size += crypto_shash_digestsize(ic->internal_hash) - ic->tag_size; recalc_tags = kvmalloc(recalc_tags_size, GFP_NOIO); if (!recalc_tags) { - DMCRIT("out of memory for recalculate buffer - recalculation disabled"); - goto free_ret; + vfree(recalc_buffer); + goto oom; } DEBUG_print("start recalculation... (position %llx)\n", le64_to_cpu(ic->sb->recalc_sector)); @@ -2693,7 +2699,7 @@ next_chunk: } get_area_and_offset(ic, range.logical_sector, &area, &offset); - range.n_sectors = min((sector_t)RECALC_SECTORS, ic->provided_data_sectors - range.logical_sector); + range.n_sectors = min((sector_t)recalc_sectors, ic->provided_data_sectors - range.logical_sector); if (!ic->meta_dev) range.n_sectors = min(range.n_sectors, ((sector_t)1U << ic->sb->log2_interleave_sectors) - (unsigned int)offset); |