Commit 95f8fac8 authored by Mikulas Patocka's avatar Mikulas Patocka Committed by Alasdair G Kergon

dm raid1: switch read_record from kmalloc to slab to save memory

With my previous patch to save bi_io_vec, the size of dm_raid1_read_record
is significantly increased (the vector list takes 3072 bytes on 32-bit machines
and 4096 bytes on 64-bit machines).

The structure dm_raid1_read_record used to be allocated with kmalloc,
but kmalloc aligns the size on the next power-of-two so an object
slightly greater than 4096 will allocate 8192 bytes of memory and half of
that memory will be wasted.

This patch turns kmalloc into a slab cache which doesn't have this
padding so it will reduce the memory consumed.

Cc: stable@kernel.org
Signed-off-by: default avatarMikulas Patocka <mpatocka@redhat.com>
Signed-off-by: default avatarAlasdair G Kergon <agk@redhat.com>
parent a920f6b3
...@@ -145,6 +145,8 @@ struct dm_raid1_read_record { ...@@ -145,6 +145,8 @@ struct dm_raid1_read_record {
struct dm_bio_details details; struct dm_bio_details details;
}; };
static struct kmem_cache *_dm_raid1_read_record_cache;
/* /*
* Every mirror should look like this one. * Every mirror should look like this one.
*/ */
...@@ -764,9 +766,9 @@ static struct mirror_set *alloc_context(unsigned int nr_mirrors, ...@@ -764,9 +766,9 @@ static struct mirror_set *alloc_context(unsigned int nr_mirrors,
atomic_set(&ms->suspend, 0); atomic_set(&ms->suspend, 0);
atomic_set(&ms->default_mirror, DEFAULT_MIRROR); atomic_set(&ms->default_mirror, DEFAULT_MIRROR);
len = sizeof(struct dm_raid1_read_record); ms->read_record_pool = mempool_create_slab_pool(MIN_READ_RECORDS,
ms->read_record_pool = mempool_create_kmalloc_pool(MIN_READ_RECORDS, _dm_raid1_read_record_cache);
len);
if (!ms->read_record_pool) { if (!ms->read_record_pool) {
ti->error = "Error creating mirror read_record_pool"; ti->error = "Error creating mirror read_record_pool";
kfree(ms); kfree(ms);
...@@ -1279,16 +1281,31 @@ static int __init dm_mirror_init(void) ...@@ -1279,16 +1281,31 @@ static int __init dm_mirror_init(void)
{ {
int r; int r;
_dm_raid1_read_record_cache = KMEM_CACHE(dm_raid1_read_record, 0);
if (!_dm_raid1_read_record_cache) {
DMERR("Can't allocate dm_raid1_read_record cache");
r = -ENOMEM;
goto bad_cache;
}
r = dm_register_target(&mirror_target); r = dm_register_target(&mirror_target);
if (r < 0) if (r < 0) {
DMERR("Failed to register mirror target"); DMERR("Failed to register mirror target");
goto bad_target;
}
return 0;
bad_target:
kmem_cache_destroy(_dm_raid1_read_record_cache);
bad_cache:
return r; return r;
} }
static void __exit dm_mirror_exit(void) static void __exit dm_mirror_exit(void)
{ {
dm_unregister_target(&mirror_target); dm_unregister_target(&mirror_target);
kmem_cache_destroy(_dm_raid1_read_record_cache);
} }
/* Module hooks */ /* Module hooks */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment