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

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
Loading
Loading
Loading
Loading
+21 −4
Original line number Diff line number Diff line
@@ -145,6 +145,8 @@ struct dm_raid1_read_record {
	struct dm_bio_details details;
};

static struct kmem_cache *_dm_raid1_read_record_cache;

/*
 * Every mirror should look like this one.
 */
@@ -764,9 +766,9 @@ static struct mirror_set *alloc_context(unsigned int nr_mirrors,
	atomic_set(&ms->suspend, 0);
	atomic_set(&ms->default_mirror, DEFAULT_MIRROR);

	len = sizeof(struct dm_raid1_read_record);
	ms->read_record_pool = mempool_create_kmalloc_pool(MIN_READ_RECORDS,
							   len);
	ms->read_record_pool = mempool_create_slab_pool(MIN_READ_RECORDS,
						_dm_raid1_read_record_cache);

	if (!ms->read_record_pool) {
		ti->error = "Error creating mirror read_record_pool";
		kfree(ms);
@@ -1279,16 +1281,31 @@ static int __init dm_mirror_init(void)
{
	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);
	if (r < 0)
	if (r < 0) {
		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;
}

static void __exit dm_mirror_exit(void)
{
	dm_unregister_target(&mirror_target);
	kmem_cache_destroy(_dm_raid1_read_record_cache);
}

/* Module hooks */