diff options
author | Mikulas Patocka <mpatocka@redhat.com> | 2009-04-02 14:55:24 -0400 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2009-04-02 14:55:24 -0400 |
commit | 95f8fac8dc6139fedfb87746e0c8fda9b803cb46 (patch) | |
tree | 36c980967ee188865d0a58be2e1281b5bf77cbae /drivers/md/dm-raid1.c | |
parent | a920f6b3accc77d9dddbc98a7426be23ee479625 (diff) |
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: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md/dm-raid1.c')
-rw-r--r-- | drivers/md/dm-raid1.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 4d6bc101962e..62d594889ac3 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c | |||
@@ -145,6 +145,8 @@ struct dm_raid1_read_record { | |||
145 | struct dm_bio_details details; | 145 | struct dm_bio_details details; |
146 | }; | 146 | }; |
147 | 147 | ||
148 | static struct kmem_cache *_dm_raid1_read_record_cache; | ||
149 | |||
148 | /* | 150 | /* |
149 | * Every mirror should look like this one. | 151 | * Every mirror should look like this one. |
150 | */ | 152 | */ |
@@ -764,9 +766,9 @@ static struct mirror_set *alloc_context(unsigned int nr_mirrors, | |||
764 | atomic_set(&ms->suspend, 0); | 766 | atomic_set(&ms->suspend, 0); |
765 | atomic_set(&ms->default_mirror, DEFAULT_MIRROR); | 767 | atomic_set(&ms->default_mirror, DEFAULT_MIRROR); |
766 | 768 | ||
767 | len = sizeof(struct dm_raid1_read_record); | 769 | ms->read_record_pool = mempool_create_slab_pool(MIN_READ_RECORDS, |
768 | ms->read_record_pool = mempool_create_kmalloc_pool(MIN_READ_RECORDS, | 770 | _dm_raid1_read_record_cache); |
769 | len); | 771 | |
770 | if (!ms->read_record_pool) { | 772 | if (!ms->read_record_pool) { |
771 | ti->error = "Error creating mirror read_record_pool"; | 773 | ti->error = "Error creating mirror read_record_pool"; |
772 | kfree(ms); | 774 | kfree(ms); |
@@ -1279,16 +1281,31 @@ static int __init dm_mirror_init(void) | |||
1279 | { | 1281 | { |
1280 | int r; | 1282 | int r; |
1281 | 1283 | ||
1284 | _dm_raid1_read_record_cache = KMEM_CACHE(dm_raid1_read_record, 0); | ||
1285 | if (!_dm_raid1_read_record_cache) { | ||
1286 | DMERR("Can't allocate dm_raid1_read_record cache"); | ||
1287 | r = -ENOMEM; | ||
1288 | goto bad_cache; | ||
1289 | } | ||
1290 | |||
1282 | r = dm_register_target(&mirror_target); | 1291 | r = dm_register_target(&mirror_target); |
1283 | if (r < 0) | 1292 | if (r < 0) { |
1284 | DMERR("Failed to register mirror target"); | 1293 | DMERR("Failed to register mirror target"); |
1294 | goto bad_target; | ||
1295 | } | ||
1296 | |||
1297 | return 0; | ||
1285 | 1298 | ||
1299 | bad_target: | ||
1300 | kmem_cache_destroy(_dm_raid1_read_record_cache); | ||
1301 | bad_cache: | ||
1286 | return r; | 1302 | return r; |
1287 | } | 1303 | } |
1288 | 1304 | ||
1289 | static void __exit dm_mirror_exit(void) | 1305 | static void __exit dm_mirror_exit(void) |
1290 | { | 1306 | { |
1291 | dm_unregister_target(&mirror_target); | 1307 | dm_unregister_target(&mirror_target); |
1308 | kmem_cache_destroy(_dm_raid1_read_record_cache); | ||
1292 | } | 1309 | } |
1293 | 1310 | ||
1294 | /* Module hooks */ | 1311 | /* Module hooks */ |