]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: memory: add accounting for failed allocations
authorWilly Tarreau <w@1wt.eu>
Wed, 28 Oct 2015 15:24:21 +0000 (16:24 +0100)
committerWilly Tarreau <w@1wt.eu>
Wed, 28 Oct 2015 15:24:21 +0000 (16:24 +0100)
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.

include/common/memory.h
src/dumpstats.c
src/memory.c

index 410c97ffcfcb4fe0a4cf54bd1d9053b7b70c7633..2b7121b420b5830c87fb11ce4439bce5957ad872 100644 (file)
@@ -53,6 +53,7 @@ struct pool_head {
        unsigned int size;      /* chunk size */
        unsigned int flags;     /* MEM_F_* */
        unsigned int users;     /* number of pools sharing this zone */
+       unsigned int failed;    /* failed allocations */
        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(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>.
index b83dfb80b6bf7d39e7d3b172d51da43aab36728c..67686d3d461690244a0ec40a82be174010abd33f 100644 (file)
@@ -2672,6 +2672,9 @@ static int stats_dump_info_to_buffer(struct stream_interface *si)
                     "Uptime: %dd %dh%02dm%02ds\n"
                     "Uptime_sec: %d\n"
                     "Memmax_MB: %d\n"
+                    "PoolAlloc_MB: %d\n"
+                    "PoolUsed_MB: %d\n"
+                    "PoolFailed: %d\n"
                     "Ulimit-n: %d\n"
                     "Maxsock: %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,
                     global.rlimit_memmax,
+                    (int)(pool_total_allocated() / 1048576L),
+                    (int)(pool_total_used() / 1048576L),
+                    pool_total_failures(),
                     global.rlimit_nofile,
                     global.maxsock, global.maxconn, global.hardmaxconn,
                     actconn, totalconn, global.req_count,
index 691e1e34a362857ac2bc8785fb1b1bba5908ff8e..036f78607d9404489816cde4b0958d218b1e8df6 100644 (file)
@@ -103,6 +103,7 @@ void *pool_refill_alloc(struct pool_head *pool, unsigned int avail)
 
                ptr = MALLOC(pool->size + POOL_EXTRA);
                if (!ptr) {
+                       pool->failed++;
                        if (failed)
                                return NULL;
                        failed++;
@@ -206,9 +207,9 @@ void dump_pools_to_trash()
        allocated = used = nbpools = 0;
        chunk_printf(&trash, "Dumping pools usage. Use SIGQUIT to flush them.\n");
        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->size * entry->allocated, entry->used,
+                        entry->size * entry->allocated, entry->used, entry->failed,
                         entry->users, (entry->flags & MEM_F_SHARED) ? " [SHARED]" : "");
 
                allocated += entry->allocated * entry->size;
@@ -226,6 +227,39 @@ void dump_pools(void)
        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:
  *  c-indent-level: 8