From patchwork Thu Apr 16 02:29:36 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 2174 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1776306664; bh=vE4VlCPbJ+S22vnFWk0dfWba9I1raOBGVvI5rLxoj/Y=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=SjxdrjHAwtibl+yBOqxsNmZ9eqRUUe54FItwp9AWlrhJKUZBjZ30NE+r83b/cXPbF RxhF9F2hVU4IJ/U/3FkAVkNfJ1iXC19lhfLBSHd9HJvmbobR8Fl6NejFYIPoht7gAo a85ov333l5Ir6bik4Od+2n4idHuK20tSZ/ypl6tw= Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id B0F456A44C for ; Wed, 15 Apr 2026 20:31:04 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id 5syN9h4xEBb4 for ; Wed, 15 Apr 2026 20:31:04 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1776306661; bh=vE4VlCPbJ+S22vnFWk0dfWba9I1raOBGVvI5rLxoj/Y=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=J8y7e633yhuFiVdw8lGmQjweflmlcF8Z5BJWAtzRcvm6wX/2kZgbDYuaOPlkBKhzD dov1sEsFjgCG84w7aCo23f45Do7EZ2irjVqwgc/FEmjVrWB1pKkKhcpmtamMIOBwEC qkwxKpPqZxP20Y2SIqWrSi3YwMHlWilWQEb6hsfg= Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 8CF8F6A4A9 for ; Wed, 15 Apr 2026 20:31:01 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1776306658; bh=IXBqCmtY8X7QQ/RTxypuZZ4Ee8bU56K/SNLT86mArw4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TwaIagVpdols8ur7BjIrbNyjEWNXf39G2OyMViD6gCbpOI4v+0GaxHwSHXz8dK2F5 vOr9BkLOOSyY38hEq6PkJj5felH0g20EP9396mSufPYOsSVUYqWsuCiZcQHsLGPxN6 pkoCmaNeZbT2C90LG9NSwLZGOhGq2cpBzwHnlmkY= Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id A93C96A4A0; Wed, 15 Apr 2026 20:30:58 -0600 (MDT) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id Wg3Sr7cL6a0g; Wed, 15 Apr 2026 20:30:58 -0600 (MDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1776306658; bh=QOEQ3jDjU/ovle2c3wSbkasniayEPBXrs0tf7q7+TjA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=J+FHOGOQGG/NTQevBJYLLGcn4IeyG4/4ZaQDlhqjZKux3/GrBHW8gxYY+efJhUpKu L4CskXSnUMyYoLdZf0Pye2Q9enSei8c/rGalY9AM1z7l1V4J46T5k60N5GX430i5h8 eb/onkF8Yv7KpRM+QU29Z1ZefCEh2fXCCT2fiGLw= Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 1AC7E6A44C; Wed, 15 Apr 2026 20:30:58 -0600 (MDT) From: Simon Glass To: U-Boot Concept Date: Wed, 15 Apr 2026 20:29:36 -0600 Message-ID: <20260416023021.626949-12-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260416023021.626949-1-sjg@u-boot.org> References: <20260416023021.626949-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: QMENKZ6L5GTJA2CPMDGHAYGJEE2R2FVK X-Message-ID-Hash: QMENKZ6L5GTJA2CPMDGHAYGJEE2R2FVK X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Simon Glass X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 11/33] test: common: Target largest free chunk in heap-pressure tests List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass At present common_test_malloc_very_large() asks for what it thinks should be available (TOTAL_MALLOC_LEN - margin) in a single malloc() call. Similarly common_test_malloc_fill_pool() asserts that the running total reaches (TOTAL_MALLOC_LEN - 1 MiB). Both assume the whole pool is a single contiguous region. When earlier tests in the same sandbox session have left scattered leaks the heap is fragmented, and either test can fail even though the help is mostly empty. Use malloc_largest_free() instead so the two tests scale down to what is actually available, and allocate half of that when checking that a large block can still be obtained after the fill-and-free cycle. The tests still exercise the intended behaviour without depending on prior tests not leaking anything. Signed-off-by: Simon Glass --- test/common/malloc.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/test/common/malloc.c b/test/common/malloc.c index c4764a51f6b..198258b5c89 100644 --- a/test/common/malloc.c +++ b/test/common/malloc.c @@ -545,15 +545,17 @@ static int common_test_malloc_very_large(struct unit_test_state *uts) before = get_alloced_size(); /* - * When mcheck is enabled, it adds overhead per allocation (header + - * canaries). With large CONFIG_MCHECK_CALLER_LEN, this can be - * significant. Use a larger margin to account for mcheck overhead. + * Target the largest free chunk rather than the whole pool, so earlier + * test leaks that fragment the heap do not turn this into a flakily + * failing test. When mcheck is enabled, allow for the per-allocation + * header and canaries; otherwise a smaller margin for dlmalloc's own + * chunk alignment is enough. */ if (CONFIG_IS_ENABLED(MCHECK_HEAP_PROTECTION)) margin = SZ_256K; else margin = SZ_64K; - size = TOTAL_MALLOC_LEN - before - margin; + size = malloc_largest_free() - margin; ptr = malloc(size); ut_assertnonnull(ptr); @@ -582,6 +584,7 @@ static int common_test_malloc_fill_pool(struct unit_test_state *uts) { int alloc_size, before, count, i, total; const int ptr_table_size = 0x100000; + size_t largest; void **ptrs; void *ptr; @@ -594,6 +597,14 @@ static int common_test_malloc_fill_pool(struct unit_test_state *uts) before = get_alloced_size(); + /* + * Record the largest contiguous free region up front. Earlier tests + * may have left scattered leaks that fragment the heap, so cap the + * assertion below against what is actually available rather than the + * whole pool. + */ + largest = malloc_largest_free(); + /* Use memory outside malloc pool to store pointers */ ptrs = map_sysmem(0x1000, ptr_table_size); @@ -616,10 +627,10 @@ static int common_test_malloc_fill_pool(struct unit_test_state *uts) ptr_table_size); /* - * Should have allocated most of the pool - if we can't allocate 1MB, - * then at most 1MB is available, so we must have allocated at least - * (pool_size - 1MB). Save the peak before freeing so an assertion - * failure does not leak the entire pool. + * Should have allocated most of the available pool - if we can't + * allocate 1 MB, then at most 1 MB is available, so we must have + * allocated at least (available - 1 MB). Save the peak before + * freeing so an assertion failure does not leak the entire pool. */ ut_assert(count > 0); ut_assert(count < ptr_table_size / sizeof(void *)); @@ -632,13 +643,13 @@ static int common_test_malloc_fill_pool(struct unit_test_state *uts) for (i = 0; i < count; i++) free(ptrs[i]); - ut_assert(alloc_size >= TOTAL_MALLOC_LEN - SZ_1M); + ut_assert(alloc_size - before >= largest - SZ_1M); /* Should be back to starting state */ ut_asserteq(before, get_alloced_size()); - /* Verify we can allocate large blocks again */ - ptr = malloc(TOTAL_MALLOC_LEN / 2); + /* Verify we can allocate a large block again */ + ptr = malloc(largest / 2); ut_assertnonnull(ptr); free(ptr);