mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-21 22:01:31 +02:00
MEDIUM: memory: add accounting for failed allocations
We now keep a per-pool counter of failed memory allocations and we report that, as well as the amount of memory allocated and used on the CLI.
This commit is contained in:
parent
de30a684ca
commit
58102cf30b
@ -53,6 +53,7 @@ struct pool_head {
|
|||||||
unsigned int size; /* chunk size */
|
unsigned int size; /* chunk size */
|
||||||
unsigned int flags; /* MEM_F_* */
|
unsigned int flags; /* MEM_F_* */
|
||||||
unsigned int users; /* number of pools sharing this zone */
|
unsigned int users; /* number of pools sharing this zone */
|
||||||
|
unsigned int failed; /* failed allocations */
|
||||||
char name[12]; /* name of the pool */
|
char name[12]; /* name of the pool */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -94,6 +95,9 @@ struct pool_head *create_pool(char *name, unsigned int size, unsigned int flags)
|
|||||||
*/
|
*/
|
||||||
void dump_pools_to_trash();
|
void dump_pools_to_trash();
|
||||||
void dump_pools(void);
|
void dump_pools(void);
|
||||||
|
int pool_total_failures();
|
||||||
|
unsigned long pool_total_allocated();
|
||||||
|
unsigned long pool_total_used();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function frees whatever can be freed in pool <pool>.
|
* This function frees whatever can be freed in pool <pool>.
|
||||||
|
@ -2672,6 +2672,9 @@ static int stats_dump_info_to_buffer(struct stream_interface *si)
|
|||||||
"Uptime: %dd %dh%02dm%02ds\n"
|
"Uptime: %dd %dh%02dm%02ds\n"
|
||||||
"Uptime_sec: %d\n"
|
"Uptime_sec: %d\n"
|
||||||
"Memmax_MB: %d\n"
|
"Memmax_MB: %d\n"
|
||||||
|
"PoolAlloc_MB: %d\n"
|
||||||
|
"PoolUsed_MB: %d\n"
|
||||||
|
"PoolFailed: %d\n"
|
||||||
"Ulimit-n: %d\n"
|
"Ulimit-n: %d\n"
|
||||||
"Maxsock: %d\n"
|
"Maxsock: %d\n"
|
||||||
"Maxconn: %d\n"
|
"Maxconn: %d\n"
|
||||||
@ -2724,6 +2727,9 @@ static int stats_dump_info_to_buffer(struct stream_interface *si)
|
|||||||
up / 86400, (up % 86400) / 3600, (up % 3600) / 60, (up % 60),
|
up / 86400, (up % 86400) / 3600, (up % 3600) / 60, (up % 60),
|
||||||
up,
|
up,
|
||||||
global.rlimit_memmax,
|
global.rlimit_memmax,
|
||||||
|
(int)(pool_total_allocated() / 1048576L),
|
||||||
|
(int)(pool_total_used() / 1048576L),
|
||||||
|
pool_total_failures(),
|
||||||
global.rlimit_nofile,
|
global.rlimit_nofile,
|
||||||
global.maxsock, global.maxconn, global.hardmaxconn,
|
global.maxsock, global.maxconn, global.hardmaxconn,
|
||||||
actconn, totalconn, global.req_count,
|
actconn, totalconn, global.req_count,
|
||||||
|
38
src/memory.c
38
src/memory.c
@ -103,6 +103,7 @@ void *pool_refill_alloc(struct pool_head *pool, unsigned int avail)
|
|||||||
|
|
||||||
ptr = MALLOC(pool->size + POOL_EXTRA);
|
ptr = MALLOC(pool->size + POOL_EXTRA);
|
||||||
if (!ptr) {
|
if (!ptr) {
|
||||||
|
pool->failed++;
|
||||||
if (failed)
|
if (failed)
|
||||||
return NULL;
|
return NULL;
|
||||||
failed++;
|
failed++;
|
||||||
@ -206,9 +207,9 @@ void dump_pools_to_trash()
|
|||||||
allocated = used = nbpools = 0;
|
allocated = used = nbpools = 0;
|
||||||
chunk_printf(&trash, "Dumping pools usage. Use SIGQUIT to flush them.\n");
|
chunk_printf(&trash, "Dumping pools usage. Use SIGQUIT to flush them.\n");
|
||||||
list_for_each_entry(entry, &pools, list) {
|
list_for_each_entry(entry, &pools, list) {
|
||||||
chunk_appendf(&trash, " - Pool %s (%d bytes) : %d allocated (%u bytes), %d used, %d users%s\n",
|
chunk_appendf(&trash, " - Pool %s (%d bytes) : %d allocated (%u bytes), %d used, %d failures, %d users%s\n",
|
||||||
entry->name, entry->size, entry->allocated,
|
entry->name, entry->size, entry->allocated,
|
||||||
entry->size * entry->allocated, entry->used,
|
entry->size * entry->allocated, entry->used, entry->failed,
|
||||||
entry->users, (entry->flags & MEM_F_SHARED) ? " [SHARED]" : "");
|
entry->users, (entry->flags & MEM_F_SHARED) ? " [SHARED]" : "");
|
||||||
|
|
||||||
allocated += entry->allocated * entry->size;
|
allocated += entry->allocated * entry->size;
|
||||||
@ -226,6 +227,39 @@ void dump_pools(void)
|
|||||||
qfprintf(stderr, "%s", trash.str);
|
qfprintf(stderr, "%s", trash.str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This function returns the total number of failed pool allocations */
|
||||||
|
int pool_total_failures()
|
||||||
|
{
|
||||||
|
struct pool_head *entry;
|
||||||
|
int failed = 0;
|
||||||
|
|
||||||
|
list_for_each_entry(entry, &pools, list)
|
||||||
|
failed += entry->failed;
|
||||||
|
return failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function returns the total amount of memory allocated in pools (in bytes) */
|
||||||
|
unsigned long pool_total_allocated()
|
||||||
|
{
|
||||||
|
struct pool_head *entry;
|
||||||
|
unsigned long allocated = 0;
|
||||||
|
|
||||||
|
list_for_each_entry(entry, &pools, list)
|
||||||
|
allocated += entry->allocated * entry->size;
|
||||||
|
return allocated;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function returns the total amount of memory used in pools (in bytes) */
|
||||||
|
unsigned long pool_total_used()
|
||||||
|
{
|
||||||
|
struct pool_head *entry;
|
||||||
|
unsigned long used = 0;
|
||||||
|
|
||||||
|
list_for_each_entry(entry, &pools, list)
|
||||||
|
used += entry->used * entry->size;
|
||||||
|
return used;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Local variables:
|
* Local variables:
|
||||||
* c-indent-level: 8
|
* c-indent-level: 8
|
||||||
|
Loading…
x
Reference in New Issue
Block a user