]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: memprof: prepare to consider exec_ctx in reporting
authorWilly Tarreau <w@1wt.eu>
Tue, 3 Mar 2026 13:02:38 +0000 (14:02 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 12 Mar 2026 17:06:37 +0000 (18:06 +0100)
This now allows to report the same function in multiple bins based on the
th_ctx's exec_ctx discriminant. It's also worth noting that the context is
not atomically committed, but this shouldn't be a problem since a single
entry can get it. In the worst case, a second thread trying to create the
same context in parallel would create a different bin just for this call,
which is harmless. The same situation already exists with the caller
pointer.

include/haproxy/activity-t.h
src/activity.c

index 37fdeb10a4a63ace6f7c6d6dfa74517115c6f350..e84643b95a97e6944ac0d7fea8b88817a5c2f51a 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <haproxy/api-t.h>
 #include <haproxy/freq_ctr-t.h>
+#include <haproxy/tinfo-t.h>
 
 /* bit fields for the "profiling" global variable */
 #define HA_PROF_TASKS_OFF   0x00000000     /* per-task CPU profiling forced disabled */
@@ -84,6 +85,7 @@ struct memprof_stats {
        unsigned long long alloc_tot;
        unsigned long long free_tot;
        void *info; // for pools, ptr to the pool
+       struct thread_exec_ctx exec_ctx;
 };
 #endif
 
index d270a6500b8a5246ce29bf40b6e6a06d3784068c..61648ba40765f7e9c76149b31af3c532a3a5c92b 100644 (file)
@@ -308,9 +308,12 @@ struct memprof_stats *memprof_get_bin(const void *ra, enum memprof_method meth)
                bin = MEMPROF_HASH_BUCKETS;
                goto leave;
        }
-       hash = _ptr_hash(ra);
-       bin = _ptr_hash_reduce(hash, MEMPROF_HASH_BITS);
-       for (; memprof_stats[bin].caller != ra; bin = (bin + (hash | 1)) & (MEMPROF_HASH_BUCKETS - 1)) {
+       hash = _ptr2_hash_arg(ra, th_ctx->exec_ctx.pointer, th_ctx->exec_ctx.type);
+       for (bin = _ptr_hash_reduce(hash, MEMPROF_HASH_BITS);
+            memprof_stats[bin].caller != ra ||
+              memprof_stats[bin].exec_ctx.type != th_ctx->exec_ctx.type ||
+              memprof_stats[bin].exec_ctx.pointer != th_ctx->exec_ctx.pointer;
+            bin = (bin + (hash | 1)) & (MEMPROF_HASH_BUCKETS - 1)) {
                if (!--retries) {
                        bin = MEMPROF_HASH_BUCKETS;
                        break;
@@ -319,6 +322,7 @@ struct memprof_stats *memprof_get_bin(const void *ra, enum memprof_method meth)
                old = NULL;
                if (!memprof_stats[bin].caller &&
                    HA_ATOMIC_CAS(&memprof_stats[bin].caller, &old, ra)) {
+                       memprof_stats[bin].exec_ctx = th_ctx->exec_ctx;
                        memprof_stats[bin].method = meth;
                        break;
                }
@@ -923,6 +927,14 @@ static int cmp_memprof_stats(const void *a, const void *b)
                return -1;
        else if (l->alloc_tot + l->free_tot < r->alloc_tot + r->free_tot)
                return 1;
+       else if (l->exec_ctx.type > r->exec_ctx.type)
+               return -1;
+       else if (l->exec_ctx.type < r->exec_ctx.type)
+               return 1;
+       else if (l->exec_ctx.pointer > r->exec_ctx.pointer)
+               return -1;
+       else if (l->exec_ctx.pointer < r->exec_ctx.pointer)
+               return 1;
        else
                return 0;
 }
@@ -936,6 +948,14 @@ static int cmp_memprof_addr(const void *a, const void *b)
                return -1;
        else if (l->caller < r->caller)
                return 1;
+       else if (l->exec_ctx.type > r->exec_ctx.type)
+               return -1;
+       else if (l->exec_ctx.type < r->exec_ctx.type)
+               return 1;
+       else if (l->exec_ctx.pointer > r->exec_ctx.pointer)
+               return -1;
+       else if (l->exec_ctx.pointer < r->exec_ctx.pointer)
+               return 1;
        else
                return 0;
 }