mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
pool debugging
This commit is contained in:
parent
d528aaa63f
commit
bd46a496c7
@ -1,5 +1,6 @@
|
|||||||
Version 2.00.26 - 23rd November 2004
|
Version 2.00.26 - 23rd November 2004
|
||||||
====================================
|
====================================
|
||||||
|
Improve pool debugging stats.
|
||||||
Detect partition table signature.
|
Detect partition table signature.
|
||||||
pvcreate wipes md superblocks. (With --uuid or --restorefile it prompts.)
|
pvcreate wipes md superblocks. (With --uuid or --restorefile it prompts.)
|
||||||
Separate out md superblock detection code.
|
Separate out md superblock detection code.
|
||||||
|
@ -919,7 +919,7 @@ struct dev_manager *dev_manager_create(struct cmd_context *cmd,
|
|||||||
struct pool *mem;
|
struct pool *mem;
|
||||||
struct dev_manager *dm;
|
struct dev_manager *dm;
|
||||||
|
|
||||||
if (!(mem = pool_create(16 * 1024))) {
|
if (!(mem = pool_create("dev_manager", 16 * 1024))) {
|
||||||
stack;
|
stack;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -828,7 +828,7 @@ struct cmd_context *create_toolcontext(struct arg *the_args)
|
|||||||
if (*cmd->sys_dir && !create_dir(cmd->sys_dir))
|
if (*cmd->sys_dir && !create_dir(cmd->sys_dir))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!(cmd->libmem = pool_create(4 * 1024))) {
|
if (!(cmd->libmem = pool_create("library", 4 * 1024))) {
|
||||||
log_error("Library memory pool creation failed");
|
log_error("Library memory pool creation failed");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -859,7 +859,7 @@ struct cmd_context *create_toolcontext(struct arg *the_args)
|
|||||||
if (!_init_filters(cmd))
|
if (!_init_filters(cmd))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!(cmd->mem = pool_create(4 * 1024))) {
|
if (!(cmd->mem = pool_create("command", 4 * 1024))) {
|
||||||
log_error("Command memory pool creation failed");
|
log_error("Command memory pool creation failed");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ static int _tok_match(const char *str, const char *b, const char *e)
|
|||||||
struct config_tree *create_config_tree(const char *filename)
|
struct config_tree *create_config_tree(const char *filename)
|
||||||
{
|
{
|
||||||
struct cs *c;
|
struct cs *c;
|
||||||
struct pool *mem = pool_create(10 * 1024);
|
struct pool *mem = pool_create("config", 10 * 1024);
|
||||||
|
|
||||||
if (!mem) {
|
if (!mem) {
|
||||||
stack;
|
stack;
|
||||||
|
@ -387,7 +387,7 @@ int dev_cache_init(void)
|
|||||||
{
|
{
|
||||||
_cache.names = NULL;
|
_cache.names = NULL;
|
||||||
|
|
||||||
if (!(_cache.mem = pool_create(10 * 1024))) {
|
if (!(_cache.mem = pool_create("dev_cache", 10 * 1024))) {
|
||||||
stack;
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ static int _build_matcher(struct rfilter *rf, struct config_value *val)
|
|||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
int i, r = 0;
|
int i, r = 0;
|
||||||
|
|
||||||
if (!(scratch = pool_create(1024))) {
|
if (!(scratch = pool_create("filter matcher", 1024))) {
|
||||||
stack;
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -201,7 +201,7 @@ static void _destroy(struct dev_filter *f)
|
|||||||
|
|
||||||
struct dev_filter *regex_filter_create(struct config_value *patterns)
|
struct dev_filter *regex_filter_create(struct config_value *patterns)
|
||||||
{
|
{
|
||||||
struct pool *mem = pool_create(10 * 1024);
|
struct pool *mem = pool_create("filter regex", 10 * 1024);
|
||||||
struct rfilter *rf;
|
struct rfilter *rf;
|
||||||
struct dev_filter *f;
|
struct dev_filter *f;
|
||||||
|
|
||||||
|
@ -265,7 +265,7 @@ struct dev_filter *sysfs_filter_create(const char *proc)
|
|||||||
if (!_locate_sysfs_blocks(proc, sys_block, sizeof(sys_block)))
|
if (!_locate_sysfs_blocks(proc, sys_block, sizeof(sys_block)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!(mem = pool_create(256))) {
|
if (!(mem = pool_create("sysfs", 256))) {
|
||||||
log_error("sysfs pool creation failed");
|
log_error("sysfs pool creation failed");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -183,7 +183,7 @@ static struct volume_group *_vg_read(struct format_instance *fid,
|
|||||||
const char *vg_name,
|
const char *vg_name,
|
||||||
struct metadata_area *mda)
|
struct metadata_area *mda)
|
||||||
{
|
{
|
||||||
struct pool *mem = pool_create(1024 * 10);
|
struct pool *mem = pool_create("lvm1 vg_read", 1024 * 10);
|
||||||
struct list pvs;
|
struct list pvs;
|
||||||
struct volume_group *vg = NULL;
|
struct volume_group *vg = NULL;
|
||||||
list_init(&pvs);
|
list_init(&pvs);
|
||||||
@ -276,7 +276,7 @@ static int _flatten_vg(struct format_instance *fid, struct pool *mem,
|
|||||||
static int _vg_write(struct format_instance *fid, struct volume_group *vg,
|
static int _vg_write(struct format_instance *fid, struct volume_group *vg,
|
||||||
struct metadata_area *mda)
|
struct metadata_area *mda)
|
||||||
{
|
{
|
||||||
struct pool *mem = pool_create(1024 * 10);
|
struct pool *mem = pool_create("lvm1 vg_write", 1024 * 10);
|
||||||
struct list pvds;
|
struct list pvds;
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
|
||||||
@ -299,7 +299,7 @@ static int _vg_write(struct format_instance *fid, struct volume_group *vg,
|
|||||||
static int _pv_read(const struct format_type *fmt, const char *pv_name,
|
static int _pv_read(const struct format_type *fmt, const char *pv_name,
|
||||||
struct physical_volume *pv, struct list *mdas)
|
struct physical_volume *pv, struct list *mdas)
|
||||||
{
|
{
|
||||||
struct pool *mem = pool_create(1024);
|
struct pool *mem = pool_create("lvm1 pv_read", 1024);
|
||||||
struct disk_list *dl;
|
struct disk_list *dl;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
int r = 0;
|
int r = 0;
|
||||||
@ -421,7 +421,7 @@ static int _pv_write(const struct format_type *fmt, struct physical_volume *pv,
|
|||||||
pv->pe_size = pv->pe_count = 0;
|
pv->pe_size = pv->pe_count = 0;
|
||||||
pv->pe_start = PE_ALIGN;
|
pv->pe_start = PE_ALIGN;
|
||||||
|
|
||||||
if (!(mem = pool_create(1024))) {
|
if (!(mem = pool_create("lvm1 pv_write", 1024))) {
|
||||||
stack;
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -344,7 +344,7 @@ int import_extents(struct cmd_context *cmd, struct volume_group *vg,
|
|||||||
struct list *pvds)
|
struct list *pvds)
|
||||||
{
|
{
|
||||||
int r = 0;
|
int r = 0;
|
||||||
struct pool *scratch = pool_create(10 * 1024);
|
struct pool *scratch = pool_create("lvm1 import_extents", 10 * 1024);
|
||||||
struct hash_table *maps;
|
struct hash_table *maps;
|
||||||
|
|
||||||
if (!scratch) {
|
if (!scratch) {
|
||||||
|
@ -30,7 +30,7 @@ int get_free_vg_number(struct format_instance *fid, struct dev_filter *filter,
|
|||||||
struct list *pvh;
|
struct list *pvh;
|
||||||
struct list all_pvs;
|
struct list all_pvs;
|
||||||
struct disk_list *dl;
|
struct disk_list *dl;
|
||||||
struct pool *mem = pool_create(10 * 1024);
|
struct pool *mem = pool_create("lvm1 vg_number", 10 * 1024);
|
||||||
int numbers[MAX_VG], i, r = 0;
|
int numbers[MAX_VG], i, r = 0;
|
||||||
|
|
||||||
list_init(&all_pvs);
|
list_init(&all_pvs);
|
||||||
|
@ -259,7 +259,7 @@ static int _read_vg_pds(const struct format_type *fmt, struct pool *mem,
|
|||||||
|
|
||||||
/* FIXME: maybe should return a different error in memory
|
/* FIXME: maybe should return a different error in memory
|
||||||
* allocation failure */
|
* allocation failure */
|
||||||
if (!(tmpmem = pool_create(512))) {
|
if (!(tmpmem = pool_create("pool read_vg", 512))) {
|
||||||
stack;
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -181,7 +181,7 @@ static struct volume_group *_vg_read(struct format_instance *fid,
|
|||||||
const char *vg_name,
|
const char *vg_name,
|
||||||
struct metadata_area *mda)
|
struct metadata_area *mda)
|
||||||
{
|
{
|
||||||
struct pool *mem = pool_create(1024);
|
struct pool *mem = pool_create("pool vg_read", 1024);
|
||||||
struct list pds;
|
struct list pds;
|
||||||
struct volume_group *vg = NULL;
|
struct volume_group *vg = NULL;
|
||||||
|
|
||||||
@ -227,7 +227,7 @@ static int _pv_setup(const struct format_type *fmt,
|
|||||||
static int _pv_read(const struct format_type *fmt, const char *pv_name,
|
static int _pv_read(const struct format_type *fmt, const char *pv_name,
|
||||||
struct physical_volume *pv, struct list *mdas)
|
struct physical_volume *pv, struct list *mdas)
|
||||||
{
|
{
|
||||||
struct pool *mem = pool_create(1024);
|
struct pool *mem = pool_create("pool pv_read", 1024);
|
||||||
struct pool_list *pl;
|
struct pool_list *pl;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
@ -652,7 +652,7 @@ static int _build_pv_names(struct formatter *f, struct volume_group *vg)
|
|||||||
struct physical_volume *pv;
|
struct physical_volume *pv;
|
||||||
char buffer[32], *name;
|
char buffer[32], *name;
|
||||||
|
|
||||||
if (!(f->mem = pool_create(512))) {
|
if (!(f->mem = pool_create("text pv_names", 512))) {
|
||||||
stack;
|
stack;
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
@ -458,7 +458,7 @@ static int _allocate(struct volume_group *vg, struct logical_volume *lv,
|
|||||||
if (segtype->flags & SEG_VIRTUAL)
|
if (segtype->flags & SEG_VIRTUAL)
|
||||||
return _alloc_virtual(lv, allocated, segtype);
|
return _alloc_virtual(lv, allocated, segtype);
|
||||||
|
|
||||||
if (!(scratch = pool_create(1024))) {
|
if (!(scratch = pool_create("allocation", 1024))) {
|
||||||
stack;
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -22,38 +22,64 @@ struct block {
|
|||||||
void *data;
|
void *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned block_serialno; /* Non-decreasing serialno of block */
|
||||||
|
unsigned blocks_allocated; /* Current number of blocks allocated */
|
||||||
|
unsigned blocks_max; /* Max no of concurrently-allocated blocks */
|
||||||
|
unsigned int bytes, maxbytes;
|
||||||
|
} pool_stats;
|
||||||
|
|
||||||
struct pool {
|
struct pool {
|
||||||
|
const char *name;
|
||||||
|
|
||||||
int begun;
|
int begun;
|
||||||
struct block *object;
|
struct block *object;
|
||||||
|
|
||||||
struct block *blocks;
|
struct block *blocks;
|
||||||
struct block *tail;
|
struct block *tail;
|
||||||
|
|
||||||
|
pool_stats stats;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* by default things come out aligned for doubles */
|
/* by default things come out aligned for doubles */
|
||||||
#define DEFAULT_ALIGNMENT __alignof__ (double)
|
#define DEFAULT_ALIGNMENT __alignof__ (double)
|
||||||
|
|
||||||
struct pool *pool_create(size_t chunk_hint)
|
struct pool *pool_create(const char *name, size_t chunk_hint)
|
||||||
{
|
{
|
||||||
struct pool *mem = dbg_malloc(sizeof(*mem));
|
struct pool *mem = dbg_malloc(sizeof(*mem));
|
||||||
|
|
||||||
if (!mem) {
|
if (!mem) {
|
||||||
log_error("Couldn't create memory pool (size %" PRIsize_t ")",
|
log_error("Couldn't create memory pool %s (size %"
|
||||||
sizeof(*mem));
|
PRIsize_t ")", name, sizeof(*mem));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mem->name = name;
|
||||||
mem->begun = 0;
|
mem->begun = 0;
|
||||||
mem->object = 0;
|
mem->object = 0;
|
||||||
mem->blocks = mem->tail = NULL;
|
mem->blocks = mem->tail = NULL;
|
||||||
|
|
||||||
|
mem->stats.block_serialno = 0;
|
||||||
|
mem->stats.blocks_allocated = 0;
|
||||||
|
mem->stats.blocks_max = 0;
|
||||||
|
mem->stats.bytes = 0;
|
||||||
|
mem->stats.maxbytes = 0;
|
||||||
|
|
||||||
|
#ifdef DEBUG_POOL
|
||||||
|
log_debug("Created mempool %s", name);
|
||||||
|
#endif
|
||||||
|
|
||||||
return mem;
|
return mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _free_blocks(struct block *b)
|
static void _free_blocks(struct pool *p, struct block *b)
|
||||||
{
|
{
|
||||||
struct block *n;
|
struct block *n;
|
||||||
|
|
||||||
while (b) {
|
while (b) {
|
||||||
|
p->stats.bytes -= b->size;
|
||||||
|
p->stats.blocks_allocated--;
|
||||||
|
|
||||||
n = b->next;
|
n = b->next;
|
||||||
dbg_free(b->data);
|
dbg_free(b->data);
|
||||||
dbg_free(b);
|
dbg_free(b);
|
||||||
@ -61,9 +87,22 @@ static void _free_blocks(struct block *b)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _pool_stats(struct pool *p, const char *action)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_POOL
|
||||||
|
log_debug("%s mempool %s: %u/%u bytes, %u/%u blocks, "
|
||||||
|
"%u allocations)", action, p->name, p->stats.bytes,
|
||||||
|
p->stats.maxbytes, p->stats.blocks_allocated,
|
||||||
|
p->stats.blocks_max, p->stats.block_serialno);
|
||||||
|
#else
|
||||||
|
;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void pool_destroy(struct pool *p)
|
void pool_destroy(struct pool *p)
|
||||||
{
|
{
|
||||||
_free_blocks(p->blocks);
|
_pool_stats(p, "Destroying");
|
||||||
|
_free_blocks(p, p->blocks);
|
||||||
dbg_free(p);
|
dbg_free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,6 +118,15 @@ static void _append_block(struct pool *p, struct block *b)
|
|||||||
p->tail = b;
|
p->tail = b;
|
||||||
} else
|
} else
|
||||||
p->blocks = p->tail = b;
|
p->blocks = p->tail = b;
|
||||||
|
|
||||||
|
p->stats.block_serialno++;
|
||||||
|
p->stats.blocks_allocated++;
|
||||||
|
if (p->stats.blocks_allocated > p->stats.blocks_max)
|
||||||
|
p->stats.blocks_max = p->stats.blocks_allocated;
|
||||||
|
|
||||||
|
p->stats.bytes += b->size;
|
||||||
|
if (p->stats.bytes > p->stats.maxbytes)
|
||||||
|
p->stats.maxbytes = p->stats.bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct block *_new_block(size_t s, unsigned alignment)
|
static struct block *_new_block(size_t s, unsigned alignment)
|
||||||
@ -121,12 +169,14 @@ void *pool_alloc_aligned(struct pool *p, size_t s, unsigned alignment)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
_append_block(p, b);
|
_append_block(p, b);
|
||||||
|
|
||||||
return b->data;
|
return b->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pool_empty(struct pool *p)
|
void pool_empty(struct pool *p)
|
||||||
{
|
{
|
||||||
_free_blocks(p->blocks);
|
_pool_stats(p, "Emptying");
|
||||||
|
_free_blocks(p, p->blocks);
|
||||||
p->blocks = p->tail = NULL;
|
p->blocks = p->tail = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,6 +184,8 @@ void pool_free(struct pool *p, void *ptr)
|
|||||||
{
|
{
|
||||||
struct block *b, *prev = NULL;
|
struct block *b, *prev = NULL;
|
||||||
|
|
||||||
|
_pool_stats(p, "Freeing (before)");
|
||||||
|
|
||||||
for (b = p->blocks; b; b = b->next) {
|
for (b = p->blocks; b; b = b->next) {
|
||||||
if (b->data == ptr)
|
if (b->data == ptr)
|
||||||
break;
|
break;
|
||||||
@ -147,13 +199,15 @@ void pool_free(struct pool *p, void *ptr)
|
|||||||
*/
|
*/
|
||||||
assert(b);
|
assert(b);
|
||||||
|
|
||||||
_free_blocks(b);
|
_free_blocks(p, b);
|
||||||
|
|
||||||
if (prev) {
|
if (prev) {
|
||||||
p->tail = prev;
|
p->tail = prev;
|
||||||
prev->next = NULL;
|
prev->next = NULL;
|
||||||
} else
|
} else
|
||||||
p->blocks = p->tail = NULL;
|
p->blocks = p->tail = NULL;
|
||||||
|
|
||||||
|
_pool_stats(p, "Freeing (after)");
|
||||||
}
|
}
|
||||||
|
|
||||||
int pool_begin_object(struct pool *p, size_t init_size)
|
int pool_begin_object(struct pool *p, size_t init_size)
|
||||||
|
@ -36,14 +36,14 @@ struct chunk *_new_chunk(struct pool *p, size_t s);
|
|||||||
/* by default things come out aligned for doubles */
|
/* by default things come out aligned for doubles */
|
||||||
#define DEFAULT_ALIGNMENT __alignof__ (double)
|
#define DEFAULT_ALIGNMENT __alignof__ (double)
|
||||||
|
|
||||||
struct pool *pool_create(size_t chunk_hint)
|
struct pool *pool_create(const char *name, size_t chunk_hint)
|
||||||
{
|
{
|
||||||
size_t new_size = 1024;
|
size_t new_size = 1024;
|
||||||
struct pool *p = dbg_malloc(sizeof(*p));
|
struct pool *p = dbg_malloc(sizeof(*p));
|
||||||
|
|
||||||
if (!p) {
|
if (!p) {
|
||||||
log_error("Couldn't create memory pool (size %" PRIsize_t ")",
|
log_error("Couldn't create memory pool %s (size %"
|
||||||
sizeof(*p));
|
PRIsize_t ")", name, sizeof(*p));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
memset(p, 0, sizeof(*p));
|
memset(p, 0, sizeof(*p));
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
struct pool;
|
struct pool;
|
||||||
|
|
||||||
/* constructor and destructor */
|
/* constructor and destructor */
|
||||||
struct pool *pool_create(size_t chunk_hint);
|
struct pool *pool_create(const char *name, size_t chunk_hint);
|
||||||
void pool_destroy(struct pool *p);
|
void pool_destroy(struct pool *p);
|
||||||
|
|
||||||
/* simple allocation/free routines */
|
/* simple allocation/free routines */
|
||||||
|
@ -275,7 +275,7 @@ struct matcher *matcher_create(struct pool *mem, const char **patterns,
|
|||||||
int i;
|
int i;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
struct rx_node *rx;
|
struct rx_node *rx;
|
||||||
struct pool *scratch = pool_create(10 * 1024);
|
struct pool *scratch = pool_create("regex matcher", 10 * 1024);
|
||||||
struct matcher *m;
|
struct matcher *m;
|
||||||
|
|
||||||
if (!scratch) {
|
if (!scratch) {
|
||||||
|
@ -1081,7 +1081,7 @@ void *report_init(struct cmd_context *cmd, const char *format, const char *keys,
|
|||||||
rh->field_prefix = "";
|
rh->field_prefix = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(rh->mem = pool_create(10 * 1024))) {
|
if (!(rh->mem = pool_create("report", 10 * 1024))) {
|
||||||
log_error("Allocation of memory pool for report failed");
|
log_error("Allocation of memory pool for report failed");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user