From c0bf395cdee1fd11e9246a410dd39621bb5c0685 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Wed, 11 Mar 2026 09:33:28 +0100 Subject: [PATCH] MINOR: task: set execution context on task/tasklet calls It now appears almost everywhere due to callbacks (e.g. ssl_sock_io_cb). Muxes also become visible now on memory profiling. A small test on h1+ssl yields 838 lines of statistics. The number of buckets should definitely be increased, and more grouping criteria should be added. A performance test was conducted to observe the possible effect of setting the execution context on each task switch, and it didn't change at all, remaining at about 1.01 billion ctxsw/s on a 128-thread EPYC. --- include/haproxy/tinfo-t.h | 2 ++ src/task.c | 9 ++++++--- src/tools.c | 4 ++++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/include/haproxy/tinfo-t.h b/include/haproxy/tinfo-t.h index 98b8762a8..bf9108cb8 100644 --- a/include/haproxy/tinfo-t.h +++ b/include/haproxy/tinfo-t.h @@ -87,6 +87,7 @@ enum thread_exec_ctx_type { TH_EX_CTX_ACTION, /* directly registered action function, using .action_kwl */ TH_EX_CTX_FLT, /* filter whose config is in .flt_conf */ TH_EX_CTX_MUX, /* mux whose mux_ops is in .mux_ops */ + TH_EX_CTX_TASK, /* task or tasklet whose function is in .task */ }; struct thread_exec_ctx { @@ -101,6 +102,7 @@ struct thread_exec_ctx { const struct action_kw_list *action_kwl; /* used with TH_EX_CTX_ACTION */ const struct flt_conf *flt_conf; /* used with TH_EX_CTX_FLTCONF */ const struct mux_ops *mux_ops; /* used with TH_EX_CTX_MUX */ + const struct task *(*task)(struct task *, void *, unsigned int); /* used with TH_EX_CTX_TASK */ }; }; diff --git a/src/task.c b/src/task.c index 3a3e3436f..8f03b1dda 100644 --- a/src/task.c +++ b/src/task.c @@ -650,16 +650,19 @@ unsigned int run_tasks_from_lists(unsigned int budgets[]) if (state & TASK_F_TASKLET) { /* this is a tasklet */ - t = process(t, ctx, state); + t = EXEC_CTX_WITH_RET(EXEC_CTX_MAKE(TH_EX_CTX_TASK, process), + process(t, ctx, state)); if (t != NULL) _HA_ATOMIC_AND(&t->state, ~TASK_RUNNING); } else { /* This is a regular task */ if (process == process_stream) - t = process_stream(t, ctx, state); + t = EXEC_CTX_WITH_RET(EXEC_CTX_MAKE(TH_EX_CTX_TASK, process_stream), + process_stream(t, ctx, state)); else - t = process(t, ctx, state); + t = EXEC_CTX_WITH_RET(EXEC_CTX_MAKE(TH_EX_CTX_TASK, process), + process(t, ctx, state)); /* If there is a pending state, we have to wake up the task * immediately, else we defer it into wait queue. diff --git a/src/tools.c b/src/tools.c index 16796afcd..e58f44c53 100644 --- a/src/tools.c +++ b/src/tools.c @@ -7548,6 +7548,10 @@ void chunk_append_thread_ctx(struct buffer *output, const struct thread_exec_ctx case TH_EX_CTX_MUX: chunk_appendf(output,"mux '%s'", ctx->mux_ops->name); break; + case TH_EX_CTX_TASK: + resolve_sym_name(output, "task '", ctx->task); + chunk_appendf(output,"'"); + break; default: chunk_appendf(output,"other ctx %p", ctx->pointer); break;