Thread (42 messages) flat view 42 messages, 7 authors, 4d ago
COOLING4d

Revision v2 of 2 in this series.

Revisions (2)
  1. v2 current
  2. v3 [diff vs current]

[PATCH v2 6/7] trace2: remove use of ALLOC_GROW()

From: Derrick Stolee via GitGitGadget <hidden>
Date: 2026-08-25 18:56:36
Subsystem: the rest · Maintainer: Linus Torvalds

From: Derrick Stolee <redacted>

The ALLOC_GROW() helper can call die() on a failed memory allocation.
We need to remove this from the trace2 API code to prevent a recursive
die() handler.

This helper is used to track the nested region stack. Use a new
skipped_regions member to track how many times a region was entered
without being added to the stack, and decrease that amount as we leave
each region. This allows us to avoid a failure and instead stop
deepening the stack, giving as much nesting behavior as possible without
failing the entire process.

Signed-off-by: Derrick Stolee <redacted>
---
 banned-die.h     |  3 +++
 trace2/tr2_tls.c | 34 +++++++++++++++++++++++++++++++++-
 trace2/tr2_tls.h |  1 +
 3 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/banned-die.h b/banned-die.h
index 14aecfdc7a..423e7b607d 100644
--- a/banned-die.h
+++ b/banned-die.h
@@ -23,4 +23,7 @@
 #undef ALLOC_ARRAY
 #define ALLOC_ARRAY(x, alloc) BANNED(ALLOC_ARRAY)
 
+#undef ALLOC_GROW
+#define ALLOC_GROW(x, nr, alloc) BANNED(ALLOC_GROW)
+
 #endif /* BANNED_DIE_H */
diff --git a/trace2/tr2_tls.c b/trace2/tr2_tls.c
index ae2d39d2f5..8596292a94 100644
--- a/trace2/tr2_tls.c
+++ b/trace2/tr2_tls.c
@@ -108,8 +108,33 @@ void tr2tls_unset_self(void)
 void tr2tls_push_self(uint64_t us_now)
 {
 	struct tr2tls_thread_ctx *ctx = tr2tls_get_self();
+	uint64_t *new_array;
+	size_t new_alloc;
+
+	if (ctx->nr_skipped_regions) {
+		ctx->nr_skipped_regions++;
+		return;
+	}
+
+	if (ctx->nr_open_regions < ctx->alloc)
+		return;
+
+	if (ctx->alloc > SIZE_MAX / (2 * sizeof(*ctx->array_us_start))) {
+		ctx->nr_skipped_regions++;
+		return;
+	}
+	new_alloc = ctx->alloc * 2;
+
+	new_array = realloc(ctx->array_us_start,
+			    new_alloc * sizeof(*ctx->array_us_start));
+	if (!new_array) {
+		ctx->nr_skipped_regions++;
+		return;
+	}
+
+	ctx->array_us_start = new_array;
+	ctx->alloc = new_alloc;
 
-	ALLOC_GROW(ctx->array_us_start, ctx->nr_open_regions + 1, ctx->alloc);
 	ctx->array_us_start[ctx->nr_open_regions++] = us_now;
 }
 
@@ -117,6 +142,11 @@ void tr2tls_pop_self(void)
 {
 	struct tr2tls_thread_ctx *ctx = tr2tls_get_self();
 
+	if (ctx->nr_skipped_regions) {
+		ctx->nr_skipped_regions--;
+		return;
+	}
+
 	if (!ctx->nr_open_regions)
 		BUG("no open regions in thread '%s'", ctx->thread_name);
 
@@ -137,6 +167,8 @@ uint64_t tr2tls_region_elasped_self(uint64_t us)
 	uint64_t us_start;
 
 	ctx = tr2tls_get_self();
+	if (ctx->nr_skipped_regions)
+		return 0;
 	if (!ctx->nr_open_regions)
 		return 0;
 
diff --git a/trace2/tr2_tls.h b/trace2/tr2_tls.h
index 3bdbf4d275..c365017923 100644
--- a/trace2/tr2_tls.h
+++ b/trace2/tr2_tls.h
@@ -20,6 +20,7 @@ struct tr2tls_thread_ctx {
 	uint64_t *array_us_start;
 	size_t alloc;
 	size_t nr_open_regions; /* plays role of "nr" in ALLOC_GROW */
+	size_t nr_skipped_regions;
 	int thread_id;
 	struct tr2_timer_block timer_block;
 	struct tr2_counter_block counter_block;
-- 
gitgitgadget
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help