lkml.org 
[lkml]   [2008]   [Nov]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Subject[RESEND][PATCH] Add /proc/mempool to display mempool usage
From
Date
This patch add a new /proc/mempool file in order to display mempool usage.

The feature can be disabled with CONFIG_PROC_MEMPOOL=N during kernel
configuration.

Patch againt 2.6.28-rc6.

Signed-off-by: Remi Colinet <remi.colinet@gmail.com>
---
Add /proc/mempool to display mempool usage.
Can be disabled with CONFIG_PROC_MEMPOOL=N

Resend #1 : cosmetic cleaning.

block/blk-core.c | 2 +-
drivers/block/pktcdvd.c | 4 ++--
drivers/block/virtio_blk.c | 2 +-
drivers/md/dm-crypt.c | 4 ++--
drivers/md/dm-io.c | 2 +-
drivers/md/dm-raid1.c | 2 +-
drivers/md/dm-region-hash.c | 2 +-
drivers/md/multipath.c | 2 +-
drivers/md/raid1.c | 7 +++----
drivers/md/raid10.c | 5 +++--
fs/bio.c | 2 +-
fs/proc/Kconfig | 6 ++++++
fs/proc/Makefile | 1 +
include/linux/mempool.h | 40
+++++++++++++++++++++++++++++++---------
mm/bounce.c | 4 ++--
mm/mempool.c | 42
+++++++++++++++++++++++++++++++++++++++---
16 files changed, 96 insertions(+), 31 deletions(-)

diff -uNrp linux/block/blk-core.c linux-mempool/block/blk-core.c
--- linux/block/blk-core.c 2008-11-28 22:43:55.000000000 +0100
+++ linux-mempool/block/blk-core.c 2008-11-29 15:49:32.000000000 +0100
@@ -483,7 +483,7 @@ static int blk_init_free_list(struct req
init_waitqueue_head(&rl->wait[WRITE]);

rl->rq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab,
- mempool_free_slab, request_cachep, q->node);
+ mempool_free_slab, request_cachep, q->node, "blk_rq", MEMPOOL_SLAB);

if (!rl->rq_pool)
return -ENOMEM;
diff -uNrp linux/drivers/block/pktcdvd.c linux-mempool/drivers/block/pktcdvd.c
--- linux/drivers/block/pktcdvd.c 2008-11-23 15:22:13.000000000 +0100
+++ linux-mempool/drivers/block/pktcdvd.c 2008-11-29 15:49:32.000000000 +0100
@@ -2879,7 +2879,7 @@ static int pkt_setup_dev(dev_t dev, dev_
goto out_mutex;

pd->rb_pool = mempool_create_kmalloc_pool(PKT_RB_POOL_SIZE,
- sizeof(struct pkt_rb_node));
+ sizeof(struct pkt_rb_node), "pkt_rb");
if (!pd->rb_pool)
goto out_mem;

@@ -3070,7 +3070,7 @@ static int __init pkt_init(void)
mutex_init(&ctl_mutex);

psd_pool = mempool_create_kmalloc_pool(PSD_POOL_SIZE,
- sizeof(struct packet_stacked_data));
+ sizeof(struct packet_stacked_data), "pkt_psd");
if (!psd_pool)
return -ENOMEM;

diff -uNrp linux/drivers/block/virtio_blk.c linux-mempool/drivers/block/virtio_blk.c
--- linux/drivers/block/virtio_blk.c 2008-11-28 22:43:55.000000000 +0100
+++ linux-mempool/drivers/block/virtio_blk.c 2008-11-29 15:49:32.000000000 +0100
@@ -230,7 +230,7 @@ static int virtblk_probe(struct virtio_d
goto out_free_vblk;
}

- vblk->pool = mempool_create_kmalloc_pool(1,sizeof(struct virtblk_req));
+ vblk->pool = mempool_create_kmalloc_pool(1, sizeof(struct virtblk_req), "vblk");
if (!vblk->pool) {
err = -ENOMEM;
goto out_free_vq;
diff -uNrp linux/drivers/md/dm-crypt.c linux-mempool/drivers/md/dm-crypt.c
--- linux/drivers/md/dm-crypt.c 2008-11-28 22:43:55.000000000 +0100
+++ linux-mempool/drivers/md/dm-crypt.c 2008-11-29 15:49:32.000000000 +0100
@@ -1047,14 +1047,14 @@ static int crypt_ctr(struct dm_target *t
~(crypto_tfm_ctx_alignment() - 1);

cc->req_pool = mempool_create_kmalloc_pool(MIN_IOS, cc->dmreq_start +
- sizeof(struct dm_crypt_request) + cc->iv_size);
+ sizeof(struct dm_crypt_request) + cc->iv_size, "dm-crypt_req");
if (!cc->req_pool) {
ti->error = "Cannot allocate crypt request mempool";
goto bad_req_pool;
}
cc->req = NULL;

- cc->page_pool = mempool_create_page_pool(MIN_POOL_PAGES, 0);
+ cc->page_pool = mempool_create_page_pool(MIN_POOL_PAGES, 0, "dm-crypt_page");
if (!cc->page_pool) {
ti->error = "Cannot allocate page mempool";
goto bad_page_pool;
diff -uNrp linux/drivers/md/dm-io.c linux-mempool/drivers/md/dm-io.c
--- linux/drivers/md/dm-io.c 2008-11-23 15:25:56.000000000 +0100
+++ linux-mempool/drivers/md/dm-io.c 2008-11-29 15:49:32.000000000 +0100
@@ -52,7 +52,7 @@ struct dm_io_client *dm_io_client_create
if (!client)
return ERR_PTR(-ENOMEM);

- client->pool = mempool_create_kmalloc_pool(ios, sizeof(struct io));
+ client->pool = mempool_create_kmalloc_pool(ios, sizeof(struct io), "dm-io_client");
if (!client->pool)
goto bad;

diff -uNrp linux/drivers/md/dm-raid1.c linux-mempool/drivers/md/dm-raid1.c
--- linux/drivers/md/dm-raid1.c 2008-11-28 22:43:55.000000000 +0100
+++ linux-mempool/drivers/md/dm-raid1.c 2008-11-29 15:49:32.000000000 +0100
@@ -766,7 +766,7 @@ static struct mirror_set *alloc_context(

len = sizeof(struct dm_raid1_read_record);
ms->read_record_pool = mempool_create_kmalloc_pool(MIN_READ_RECORDS,
- len);
+ len, "dm-raid read record");
if (!ms->read_record_pool) {
ti->error = "Error creating mirror read_record_pool";
kfree(ms);
diff -uNrp linux/drivers/md/dm-region-hash.c linux-mempool/drivers/md/dm-region-hash.c
--- linux/drivers/md/dm-region-hash.c 2008-11-23 17:39:20.000000000 +0100
+++ linux-mempool/drivers/md/dm-region-hash.c 2008-11-29 15:49:32.000000000 +0100
@@ -214,7 +214,7 @@ struct dm_region_hash *dm_region_hash_cr
INIT_LIST_HEAD(&rh->failed_recovered_regions);

rh->region_pool = mempool_create_kmalloc_pool(MIN_REGIONS,
- sizeof(struct dm_region));
+ sizeof(struct dm_region), "md-region-hash");
if (!rh->region_pool) {
vfree(rh->buckets);
kfree(rh);
diff -uNrp linux/drivers/md/multipath.c linux-mempool/drivers/md/multipath.c
--- linux/drivers/md/multipath.c 2008-11-28 22:43:55.000000000 +0100
+++ linux-mempool/drivers/md/multipath.c 2008-11-29 15:49:32.000000000 +0100
@@ -475,7 +475,7 @@ static int multipath_run (mddev_t *mddev
mddev->degraded = conf->raid_disks - conf->working_disks;

conf->pool = mempool_create_kzalloc_pool(NR_RESERVED_BUFS,
- sizeof(struct multipath_bh));
+ sizeof(struct multipath_bh), "multipath_bh");
if (conf->pool == NULL) {
printk(KERN_ERR
"multipath: couldn't allocate memory for %s\n",
diff -uNrp linux/drivers/md/raid10.c linux-mempool/drivers/md/raid10.c
--- linux/drivers/md/raid10.c 2008-11-28 22:43:55.000000000 +0100
+++ linux-mempool/drivers/md/raid10.c 2008-11-29 15:49:32.000000000 +0100
@@ -1636,7 +1636,8 @@ static int init_resync(conf_t *conf)

buffs = RESYNC_WINDOW / RESYNC_BLOCK_SIZE;
BUG_ON(conf->r10buf_pool);
- conf->r10buf_pool = mempool_create(buffs, r10buf_pool_alloc, r10buf_pool_free, conf);
+ conf->r10buf_pool = mempool_create(buffs, r10buf_pool_alloc, r10buf_pool_free, conf,
+ "md_r10buf", MEMPOOL_PRIVATE);
if (!conf->r10buf_pool)
return -ENOMEM;
conf->next_resync = 0;
@@ -2097,7 +2098,7 @@ static int run(mddev_t *mddev)
conf->stride = stride << conf->chunk_shift;

conf->r10bio_pool = mempool_create(NR_RAID10_BIOS, r10bio_pool_alloc,
- r10bio_pool_free, conf);
+ r10bio_pool_free, conf, "md_r10bio", MEMPOOL_PRIVATE);
if (!conf->r10bio_pool) {
printk(KERN_ERR "raid10: couldn't allocate memory for %s\n",
mdname(mddev));
diff -uNrp linux/drivers/md/raid1.c linux-mempool/drivers/md/raid1.c
--- linux/drivers/md/raid1.c 2008-11-28 22:43:55.000000000 +0100
+++ linux-mempool/drivers/md/raid1.c 2008-11-29 15:49:32.000000000 +0100
@@ -1678,7 +1678,7 @@ static int init_resync(conf_t *conf)
buffs = RESYNC_WINDOW / RESYNC_BLOCK_SIZE;
BUG_ON(conf->r1buf_pool);
conf->r1buf_pool = mempool_create(buffs, r1buf_pool_alloc, r1buf_pool_free,
- conf->poolinfo);
+ conf->poolinfo, "md_r1buf", MEMPOOL_PRIVATE);
if (!conf->r1buf_pool)
return -ENOMEM;
conf->next_resync = 0;
@@ -1955,8 +1955,7 @@ static int run(mddev_t *mddev)
conf->poolinfo->mddev = mddev;
conf->poolinfo->raid_disks = mddev->raid_disks;
conf->r1bio_pool = mempool_create(NR_RAID1_BIOS, r1bio_pool_alloc,
- r1bio_pool_free,
- conf->poolinfo);
+ r1bio_pool_free, conf->poolinfo, "md_r1bio", MEMPOOL_PRIVATE);
if (!conf->r1bio_pool)
goto out_no_mem;

@@ -2170,7 +2169,7 @@ static int raid1_reshape(mddev_t *mddev)
newpoolinfo->raid_disks = raid_disks;

newpool = mempool_create(NR_RAID1_BIOS, r1bio_pool_alloc,
- r1bio_pool_free, newpoolinfo);
+ r1bio_pool_free, newpoolinfo, "md_raid1", MEMPOOL_PRIVATE);
if (!newpool) {
kfree(newpoolinfo);
return -ENOMEM;
diff -uNrp linux/fs/bio.c linux-mempool/fs/bio.c
--- linux/fs/bio.c 2008-11-23 15:31:14.000000000 +0100
+++ linux-mempool/fs/bio.c 2008-11-29 15:49:32.000000000 +0100
@@ -1428,7 +1428,7 @@ static int __init init_bio(void)
panic("bio: can't allocate bios\n");

bio_split_pool = mempool_create_kmalloc_pool(BIO_SPLIT_ENTRIES,
- sizeof(struct bio_pair));
+ sizeof(struct bio_pair), "bio_pair");
if (!bio_split_pool)
panic("bio: can't create split pool\n");

diff -uNrp linux/fs/proc/Kconfig linux-mempool/fs/proc/Kconfig
--- linux/fs/proc/Kconfig 2008-11-23 15:18:54.000000000 +0100
+++ linux-mempool/fs/proc/Kconfig 2008-11-29 15:49:32.000000000 +0100
@@ -67,3 +67,9 @@ config PROC_PAGE_MONITOR
/proc/pid/smaps, /proc/pid/clear_refs, /proc/pid/pagemap,
/proc/kpagecount, and /proc/kpageflags. Disabling these
interfaces will reduce the size of the kernel by approximately 4kb.
+
+config PROC_MEMPOOL
+ default y
+ bool "Enable /proc mempool"
+ help
+ Display mempool created and usage
diff -uNrp linux/fs/proc/Makefile linux-mempool/fs/proc/Makefile
--- linux/fs/proc/Makefile 2008-11-28 22:43:59.000000000 +0100
+++ linux-mempool/fs/proc/Makefile 2008-11-29 15:49:32.000000000 +0100
@@ -26,3 +26,4 @@ proc-$(CONFIG_PROC_VMCORE) += vmcore.o
proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o
proc-$(CONFIG_PRINTK) += kmsg.o
proc-$(CONFIG_PROC_PAGE_MONITOR) += page.o
+proc-$(CONFIG_PROC_MEMPOOL) += mempool.o
diff -uNrp linux/include/linux/mempool.h linux-mempool/include/linux/mempool.h
--- linux/include/linux/mempool.h 2008-11-23 15:10:51.000000000 +0100
+++ linux-mempool/include/linux/mempool.h 2008-11-29 15:49:32.000000000 +0100
@@ -18,15 +18,33 @@ typedef struct mempool_s {
void **elements;

void *pool_data;
+ struct list_head list;
+ char* name;
+ unsigned int size;
+ unsigned short type;
mempool_alloc_t *alloc;
mempool_free_t *free;
wait_queue_head_t wait;
} mempool_t;

+extern struct list_head mempool_list;
+extern rwlock_t mempool_lock;
+
+enum MEMPOOL_TYPE {
+ MEMPOOL_SLAB,
+ MEMPOOL_KMALLOC,
+ MEMPOOL_KZALLOC,
+ MEMPOOL_PAGE,
+ MEMPOOL_PRIVATE, /* For private or default usage */
+ MEMPOOL_NR_TYPES
+};
+
extern mempool_t *mempool_create(int min_nr, mempool_alloc_t *alloc_fn,
- mempool_free_t *free_fn, void *pool_data);
+ mempool_free_t *free_fn, void *pool_data, const char *name,
+ unsigned short type);
extern mempool_t *mempool_create_node(int min_nr, mempool_alloc_t *alloc_fn,
- mempool_free_t *free_fn, void *pool_data, int nid);
+ mempool_free_t *free_fn, void *pool_data, int nid, const char *name,
+ unsigned short type);

extern int mempool_resize(mempool_t *pool, int new_min_nr, gfp_t gfp_mask);
extern void mempool_destroy(mempool_t *pool);
@@ -42,8 +60,9 @@ void mempool_free_slab(void *element, vo
static inline mempool_t *
mempool_create_slab_pool(int min_nr, struct kmem_cache *kc)
{
+ const char *name = kmem_cache_name(kc);
return mempool_create(min_nr, mempool_alloc_slab, mempool_free_slab,
- (void *) kc);
+ (void *) kc, name, MEMPOOL_SLAB);
}

/*
@@ -53,15 +72,17 @@ mempool_create_slab_pool(int min_nr, str
void *mempool_kmalloc(gfp_t gfp_mask, void *pool_data);
void *mempool_kzalloc(gfp_t gfp_mask, void *pool_data);
void mempool_kfree(void *element, void *pool_data);
-static inline mempool_t *mempool_create_kmalloc_pool(int min_nr, size_t size)
+static inline mempool_t *mempool_create_kmalloc_pool(int min_nr, size_t size,
+ const char* name)
{
return mempool_create(min_nr, mempool_kmalloc, mempool_kfree,
- (void *) size);
+ (void *) size, name, MEMPOOL_KMALLOC);
}
-static inline mempool_t *mempool_create_kzalloc_pool(int min_nr, size_t size)
+static inline mempool_t *mempool_create_kzalloc_pool(int min_nr, size_t size,
+ const char* name)
{
return mempool_create(min_nr, mempool_kzalloc, mempool_kfree,
- (void *) size);
+ (void *) size, name, MEMPOOL_KMALLOC);
}

/*
@@ -70,10 +91,11 @@ static inline mempool_t *mempool_create_
*/
void *mempool_alloc_pages(gfp_t gfp_mask, void *pool_data);
void mempool_free_pages(void *element, void *pool_data);
-static inline mempool_t *mempool_create_page_pool(int min_nr, int order)
+static inline mempool_t *mempool_create_page_pool(int min_nr, int order,
+ const char* name)
{
return mempool_create(min_nr, mempool_alloc_pages, mempool_free_pages,
- (void *)(long)order);
+ (void *)(long)order, name, MEMPOOL_PAGE);
}

#endif /* _LINUX_MEMPOOL_H */
diff -uNrp linux/mm/bounce.c linux-mempool/mm/bounce.c
--- linux/mm/bounce.c 2008-11-23 15:09:22.000000000 +0100
+++ linux-mempool/mm/bounce.c 2008-11-29 15:49:32.000000000 +0100
@@ -31,7 +31,7 @@ static __init int init_emergency_pool(vo
if (!i.totalhigh)
return 0;

- page_pool = mempool_create_page_pool(POOL_SIZE, 0);
+ page_pool = mempool_create_page_pool(POOL_SIZE, 0, "highmem_bounce");
BUG_ON(!page_pool);
printk("highmem bounce pool size: %d pages\n", POOL_SIZE);

@@ -80,7 +80,7 @@ int init_emergency_isa_pool(void)
return 0;

isa_page_pool = mempool_create(ISA_POOL_SIZE, mempool_alloc_pages_isa,
- mempool_free_pages, (void *) 0);
+ mempool_free_pages, (void *) 0, "isa_page_pool", MEMPOOL_PAGE);
BUG_ON(!isa_page_pool);

printk("isa bounce pool size: %d pages\n", ISA_POOL_SIZE);
diff -uNrp linux/mm/mempool.c linux-mempool/mm/mempool.c
--- linux/mm/mempool.c 2008-11-23 14:59:51.000000000 +0100
+++ linux-mempool/mm/mempool.c 2008-11-29 15:49:32.000000000 +0100
@@ -15,6 +15,9 @@
#include <linux/blkdev.h>
#include <linux/writeback.h>

+LIST_HEAD(mempool_list);
+DEFINE_RWLOCK(mempool_lock);
+
static void add_element(mempool_t *pool, void *element)
{
BUG_ON(pool->curr_nr >= pool->min_nr);
@@ -44,6 +47,8 @@ static void free_pool(mempool_t *pool)
* @alloc_fn: user-defined element-allocation function.
* @free_fn: user-defined element-freeing function.
* @pool_data: optional private data available to the user-defined functions.
+ * @name: name of the mempool
+ * @type: type of the mempool (PAGE, SLAB, KMALLOC, KZALLOC, PRIVATE)
*
* this function creates and allocates a guaranteed size, preallocated
* memory pool. The pool can be used from the mempool_alloc() and mempool_free()
@@ -52,14 +57,16 @@ static void free_pool(mempool_t *pool)
* from IRQ contexts.
*/
mempool_t *mempool_create(int min_nr, mempool_alloc_t *alloc_fn,
- mempool_free_t *free_fn, void *pool_data)
+ mempool_free_t *free_fn, void *pool_data, const char *name,
+ unsigned short type)
{
- return mempool_create_node(min_nr,alloc_fn,free_fn, pool_data,-1);
+ return mempool_create_node(min_nr,alloc_fn,free_fn, pool_data,-1, name, type);
}
EXPORT_SYMBOL(mempool_create);

mempool_t *mempool_create_node(int min_nr, mempool_alloc_t *alloc_fn,
- mempool_free_t *free_fn, void *pool_data, int node_id)
+ mempool_free_t *free_fn, void *pool_data, int node_id, const char *name,
+ unsigned short type)
{
mempool_t *pool;
pool = kmalloc_node(sizeof(*pool), GFP_KERNEL | __GFP_ZERO, node_id);
@@ -91,6 +98,35 @@ mempool_t *mempool_create_node(int min_n
}
add_element(pool, element);
}
+
+ /*
+ * Setup name of the mempool
+ */
+ pool->name = kmalloc(strlen(name), GFP_KERNEL);
+ if (pool->name == NULL) {
+ /* should release other memory allocations */
+ return ERR_PTR(-ENOMEM);
+ }
+
+ strcpy(pool->name, name);
+ pool->type = type;
+ if (type == MEMPOOL_KZALLOC || type == MEMPOOL_KMALLOC)
+ pool->size = (int)(long) pool_data;
+ if (type == MEMPOOL_PAGE)
+ pool->size = (int)(PAGE_SIZE << (int)(long) pool_data);
+ if (type == MEMPOOL_SLAB) {
+ struct kmem_cache *kc = pool_data;
+ pool->size = kmem_cache_size(kc);
+ }
+ if (type == MEMPOOL_PRIVATE)
+ pool->size = 0;
+
+ /*
+ * Add the mempool to the global list
+ */
+ write_lock(&mempool_lock);
+ list_add_tail(&pool->list, &mempool_list);
+ write_unlock(&mempool_lock);
return pool;
}
EXPORT_SYMBOL(mempool_create_node);



\
 
 \ /
  Last update: 2008-11-29 18:49    [W:0.080 / U:0.176 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site