public inbox for bpf@vger.kernel.org
 help / color / mirror / Atom feed
From: Puranjay Mohan <puranjay@kernel.org>
To: Eduard Zingerman <eddyz87@gmail.com>,
	bpf@vger.kernel.org, ast@kernel.org, andrii@kernel.org
Cc: daniel@iogearbox.net, martin.lau@linux.dev, kernel-team@fb.com,
	yonghong.song@linux.dev, eddyz87@gmail.com,
	cupertino.miranda@oracle.com
Subject: Re: [PATCH 3/4] selftests/bpf: impose global ordering for test decl_tags
Date: Mon, 30 Mar 2026 16:36:15 +0100	[thread overview]
Message-ID: <m24ilxpbww.fsf@kernel.org> (raw)
In-Reply-To: <20260326-selftests-global-tags-ordering-v1-3-5dd2ced5d9ad@gmail.com>

Eduard Zingerman <eddyz87@gmail.com> writes:

> Impose global ordering for all decl tags used by test_loader.c based
> tests (__success, __failure, __msg, etc):
> - change every tag to expand as
>   __attribute__((btf_decl_tag("comment:" XSTR(__COUNTER__) ...)))
> - change parse_test_spec() to collect all decl tags before
>   processing and sort them using strverscmp().
>
> The ordering is necessary for gcc-bpf.
> Neither GCC nor the C standard defines the order in which function
> attributes are consumed. While Clang tends to preserve definition order,
> GCC may process them out of sequence. This inconsistency causes BPF
> tests with multiple __msg entries to fail when compiled with GCC.
>
> Co-developed-by: Cupertino Miranda <cupertino.miranda@oracle.com>
> Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
> ---
>  tools/testing/selftests/bpf/progs/bpf_misc.h |  60 ++++-----
>  tools/testing/selftests/bpf/test_loader.c    | 174 +++++++++++++++------------
>  2 files changed, 130 insertions(+), 104 deletions(-)
>
> diff --git a/tools/testing/selftests/bpf/progs/bpf_misc.h b/tools/testing/selftests/bpf/progs/bpf_misc.h
> index 52cf9f3cccd0ccd8034b9786d787e53992a4a6d8..32e06c575fbe1f36264c8965cbd84e4432a434d8 100644
> --- a/tools/testing/selftests/bpf/progs/bpf_misc.h
> +++ b/tools/testing/selftests/bpf/progs/bpf_misc.h
> @@ -130,39 +130,41 @@
>   * __linear_size     Specify the size of the linear area of non-linear skbs, or
>   *                   0 for linear skbs.
>   */
> -#define __msg(msg)		__attribute__((btf_decl_tag("comment:test_expect_msg=" XSTR(__COUNTER__) "=" msg)))
> -#define __not_msg(msg)		__attribute__((btf_decl_tag("comment:test_expect_not_msg=" XSTR(__COUNTER__) "=" msg)))
> -#define __xlated(msg)		__attribute__((btf_decl_tag("comment:test_expect_xlated=" XSTR(__COUNTER__) "=" msg)))
> -#define __jited(msg)		__attribute__((btf_decl_tag("comment:test_jited=" XSTR(__COUNTER__) "=" msg)))
> -#define __failure		__attribute__((btf_decl_tag("comment:test_expect_failure")))
> -#define __success		__attribute__((btf_decl_tag("comment:test_expect_success")))
> -#define __description(desc)	__attribute__((btf_decl_tag("comment:test_description=" desc)))
> -#define __msg_unpriv(msg)	__attribute__((btf_decl_tag("comment:test_expect_msg_unpriv=" XSTR(__COUNTER__) "=" msg)))
> -#define __not_msg_unpriv(msg)	__attribute__((btf_decl_tag("comment:test_expect_not_msg_unpriv=" XSTR(__COUNTER__) "=" msg)))
> -#define __xlated_unpriv(msg)	__attribute__((btf_decl_tag("comment:test_expect_xlated_unpriv=" XSTR(__COUNTER__) "=" msg)))
> -#define __jited_unpriv(msg)	__attribute__((btf_decl_tag("comment:test_jited_unpriv=" XSTR(__COUNTER__) "=" msg)))
> -#define __failure_unpriv	__attribute__((btf_decl_tag("comment:test_expect_failure_unpriv")))
> -#define __success_unpriv	__attribute__((btf_decl_tag("comment:test_expect_success_unpriv")))
> -#define __log_level(lvl)	__attribute__((btf_decl_tag("comment:test_log_level="#lvl)))
> -#define __flag(flag)		__attribute__((btf_decl_tag("comment:test_prog_flags="#flag)))
> -#define __retval(val)		__attribute__((btf_decl_tag("comment:test_retval="XSTR(val))))
> -#define __retval_unpriv(val)	__attribute__((btf_decl_tag("comment:test_retval_unpriv="XSTR(val))))
> -#define __auxiliary		__attribute__((btf_decl_tag("comment:test_auxiliary")))
> -#define __auxiliary_unpriv	__attribute__((btf_decl_tag("comment:test_auxiliary_unpriv")))
> -#define __btf_path(path)	__attribute__((btf_decl_tag("comment:test_btf_path=" path)))
> -#define __arch(arch)		__attribute__((btf_decl_tag("comment:test_arch=" arch)))
> +#define __test_tag(tag)		__attribute__((btf_decl_tag("comment:" XSTR(__COUNTER__) ":" tag)))
> +
> +#define __msg(msg)		__test_tag("test_expect_msg=" msg)
> +#define __not_msg(msg)		__test_tag("test_expect_not_msg=" msg)
> +#define __xlated(msg)		__test_tag("test_expect_xlated=" msg)
> +#define __jited(msg)		__test_tag("test_jited=" msg)
> +#define __failure		__test_tag("test_expect_failure")
> +#define __success		__test_tag("test_expect_success")
> +#define __description(desc)	__test_tag("test_description=" desc)
> +#define __msg_unpriv(msg)	__test_tag("test_expect_msg_unpriv=" msg)
> +#define __not_msg_unpriv(msg)	__test_tag("test_expect_not_msg_unpriv=" msg)
> +#define __xlated_unpriv(msg)	__test_tag("test_expect_xlated_unpriv=" msg)
> +#define __jited_unpriv(msg)	__test_tag("test_jited_unpriv=" msg)
> +#define __failure_unpriv	__test_tag("test_expect_failure_unpriv")
> +#define __success_unpriv	__test_tag("test_expect_success_unpriv")
> +#define __log_level(lvl)	__test_tag("test_log_level=" #lvl)
> +#define __flag(flag)		__test_tag("test_prog_flags=" #flag)
> +#define __retval(val)		__test_tag("test_retval=" XSTR(val))
> +#define __retval_unpriv(val)	__test_tag("test_retval_unpriv=" XSTR(val))
> +#define __auxiliary		__test_tag("test_auxiliary")
> +#define __auxiliary_unpriv	__test_tag("test_auxiliary_unpriv")
> +#define __btf_path(path)	__test_tag("test_btf_path=" path)
> +#define __arch(arch)		__test_tag("test_arch=" arch)
>  #define __arch_x86_64		__arch("X86_64")
>  #define __arch_arm64		__arch("ARM64")
>  #define __arch_riscv64		__arch("RISCV64")
>  #define __arch_s390x		__arch("s390x")
> -#define __caps_unpriv(caps)	__attribute__((btf_decl_tag("comment:test_caps_unpriv=" EXPAND_QUOTE(caps))))
> -#define __load_if_JITed()	__attribute__((btf_decl_tag("comment:load_mode=jited")))
> -#define __load_if_no_JITed()	__attribute__((btf_decl_tag("comment:load_mode=no_jited")))
> -#define __stderr(msg)		__attribute__((btf_decl_tag("comment:test_expect_stderr=" XSTR(__COUNTER__) "=" msg)))
> -#define __stderr_unpriv(msg)	__attribute__((btf_decl_tag("comment:test_expect_stderr_unpriv=" XSTR(__COUNTER__) "=" msg)))
> -#define __stdout(msg)		__attribute__((btf_decl_tag("comment:test_expect_stdout=" XSTR(__COUNTER__) "=" msg)))
> -#define __stdout_unpriv(msg)	__attribute__((btf_decl_tag("comment:test_expect_stdout_unpriv=" XSTR(__COUNTER__) "=" msg)))
> -#define __linear_size(sz)	__attribute__((btf_decl_tag("comment:test_linear_size=" XSTR(sz))))
> +#define __caps_unpriv(caps)	__test_tag("test_caps_unpriv=" EXPAND_QUOTE(caps))
> +#define __load_if_JITed()	__test_tag("load_mode=jited")
> +#define __load_if_no_JITed()	__test_tag("load_mode=no_jited")
> +#define __stderr(msg)		__test_tag("test_expect_stderr=" msg)
> +#define __stderr_unpriv(msg)	__test_tag("test_expect_stderr_unpriv=" msg)
> +#define __stdout(msg)		__test_tag("test_expect_stdout=" msg)
> +#define __stdout_unpriv(msg)	__test_tag("test_expect_stdout_unpriv=" msg)
> +#define __linear_size(sz)	__test_tag("test_linear_size=" XSTR(sz))
>  
>  /* Define common capabilities tested using __caps_unpriv */
>  #define CAP_NET_ADMIN		12
> diff --git a/tools/testing/selftests/bpf/test_loader.c b/tools/testing/selftests/bpf/test_loader.c
> index f1eb99f829e112f0e738bfe44e7e61a49120ec85..2779f0ecf0ada9985a5b1dfbc049c0d0ed824a76 100644
> --- a/tools/testing/selftests/bpf/test_loader.c
> +++ b/tools/testing/selftests/bpf/test_loader.c
> @@ -1,6 +1,7 @@
>  // SPDX-License-Identifier: GPL-2.0-only
>  /* Copyright (c) 2022 Meta Platforms, Inc. and affiliates. */
>  #include <linux/capability.h>
> +#include <linux/err.h>
>  #include <stdlib.h>
>  #include <test_progs.h>
>  #include <bpf/btf.h>
> @@ -20,34 +21,34 @@ static inline const char *str_has_pfx(const char *str, const char *pfx)
>  
>  #define TEST_LOADER_LOG_BUF_SZ 2097152
>  
> -#define TEST_TAG_EXPECT_FAILURE "comment:test_expect_failure"
> -#define TEST_TAG_EXPECT_SUCCESS "comment:test_expect_success"
> -#define TEST_TAG_EXPECT_MSG_PFX "comment:test_expect_msg="
> -#define TEST_TAG_EXPECT_NOT_MSG_PFX "comment:test_expect_not_msg="
> -#define TEST_TAG_EXPECT_XLATED_PFX "comment:test_expect_xlated="
> -#define TEST_TAG_EXPECT_FAILURE_UNPRIV "comment:test_expect_failure_unpriv"
> -#define TEST_TAG_EXPECT_SUCCESS_UNPRIV "comment:test_expect_success_unpriv"
> -#define TEST_TAG_EXPECT_MSG_PFX_UNPRIV "comment:test_expect_msg_unpriv="
> -#define TEST_TAG_EXPECT_NOT_MSG_PFX_UNPRIV "comment:test_expect_not_msg_unpriv="
> -#define TEST_TAG_EXPECT_XLATED_PFX_UNPRIV "comment:test_expect_xlated_unpriv="
> -#define TEST_TAG_LOG_LEVEL_PFX "comment:test_log_level="
> -#define TEST_TAG_PROG_FLAGS_PFX "comment:test_prog_flags="
> -#define TEST_TAG_DESCRIPTION_PFX "comment:test_description="
> -#define TEST_TAG_RETVAL_PFX "comment:test_retval="
> -#define TEST_TAG_RETVAL_PFX_UNPRIV "comment:test_retval_unpriv="
> -#define TEST_TAG_AUXILIARY "comment:test_auxiliary"
> -#define TEST_TAG_AUXILIARY_UNPRIV "comment:test_auxiliary_unpriv"
> -#define TEST_BTF_PATH "comment:test_btf_path="
> -#define TEST_TAG_ARCH "comment:test_arch="
> -#define TEST_TAG_JITED_PFX "comment:test_jited="
> -#define TEST_TAG_JITED_PFX_UNPRIV "comment:test_jited_unpriv="
> -#define TEST_TAG_CAPS_UNPRIV "comment:test_caps_unpriv="
> -#define TEST_TAG_LOAD_MODE_PFX "comment:load_mode="
> -#define TEST_TAG_EXPECT_STDERR_PFX "comment:test_expect_stderr="
> -#define TEST_TAG_EXPECT_STDERR_PFX_UNPRIV "comment:test_expect_stderr_unpriv="
> -#define TEST_TAG_EXPECT_STDOUT_PFX "comment:test_expect_stdout="
> -#define TEST_TAG_EXPECT_STDOUT_PFX_UNPRIV "comment:test_expect_stdout_unpriv="
> -#define TEST_TAG_LINEAR_SIZE "comment:test_linear_size="
> +#define TEST_TAG_EXPECT_FAILURE "test_expect_failure"
> +#define TEST_TAG_EXPECT_SUCCESS "test_expect_success"
> +#define TEST_TAG_EXPECT_MSG_PFX "test_expect_msg="
> +#define TEST_TAG_EXPECT_NOT_MSG_PFX "test_expect_not_msg="
> +#define TEST_TAG_EXPECT_XLATED_PFX "test_expect_xlated="
> +#define TEST_TAG_EXPECT_FAILURE_UNPRIV "test_expect_failure_unpriv"
> +#define TEST_TAG_EXPECT_SUCCESS_UNPRIV "test_expect_success_unpriv"
> +#define TEST_TAG_EXPECT_MSG_PFX_UNPRIV "test_expect_msg_unpriv="
> +#define TEST_TAG_EXPECT_NOT_MSG_PFX_UNPRIV "test_expect_not_msg_unpriv="
> +#define TEST_TAG_EXPECT_XLATED_PFX_UNPRIV "test_expect_xlated_unpriv="
> +#define TEST_TAG_LOG_LEVEL_PFX "test_log_level="
> +#define TEST_TAG_PROG_FLAGS_PFX "test_prog_flags="
> +#define TEST_TAG_DESCRIPTION_PFX "test_description="
> +#define TEST_TAG_RETVAL_PFX "test_retval="
> +#define TEST_TAG_RETVAL_PFX_UNPRIV "test_retval_unpriv="
> +#define TEST_TAG_AUXILIARY "test_auxiliary"
> +#define TEST_TAG_AUXILIARY_UNPRIV "test_auxiliary_unpriv"
> +#define TEST_BTF_PATH "test_btf_path="
> +#define TEST_TAG_ARCH "test_arch="
> +#define TEST_TAG_JITED_PFX "test_jited="
> +#define TEST_TAG_JITED_PFX_UNPRIV "test_jited_unpriv="
> +#define TEST_TAG_CAPS_UNPRIV "test_caps_unpriv="
> +#define TEST_TAG_LOAD_MODE_PFX "load_mode="
> +#define TEST_TAG_EXPECT_STDERR_PFX "test_expect_stderr="
> +#define TEST_TAG_EXPECT_STDERR_PFX_UNPRIV "test_expect_stderr_unpriv="
> +#define TEST_TAG_EXPECT_STDOUT_PFX "test_expect_stdout="
> +#define TEST_TAG_EXPECT_STDOUT_PFX_UNPRIV "test_expect_stdout_unpriv="
> +#define TEST_TAG_LINEAR_SIZE "test_linear_size="
>  
>  /* Warning: duplicated in bpf_misc.h */
>  #define POINTER_VALUE	0xbadcafe
> @@ -347,33 +348,54 @@ static void update_flags(int *flags, int flag, bool clear)
>  		*flags |= flag;
>  }
>  
> -/* Matches a string of form '<pfx>[^=]=.*' and returns it's suffix.
> - * Used to parse btf_decl_tag values.
> - * Such values require unique prefix because compiler does not add
> - * same __attribute__((btf_decl_tag(...))) twice.
> - * Test suite uses two-component tags for such cases:
> - *
> - *   <pfx> __COUNTER__ '='
> - *
> - * For example, two consecutive __msg tags '__msg("foo") __msg("foo")'
> - * would be encoded as:
> - *
> - *   [18] DECL_TAG 'comment:test_expect_msg=0=foo' type_id=15 component_idx=-1
> - *   [19] DECL_TAG 'comment:test_expect_msg=1=foo' type_id=15 component_idx=-1
> - *
> - * And the purpose of this function is to extract 'foo' from the above.
> +static const char *skip_decl_tag_pfx(const char *s)
> +{
> +	int n = 0;
> +
> +	if (sscanf(s, "comment:%*d:%n", &n) < 0 || !n)
> +		return s;
> +	return s + n;
> +}
> +
> +static void *realloc_or_free(void *ptr, size_t size)
> +{
> +	void *new = realloc(ptr, size);
> +
> +	if (!new)
> +		free(ptr);
> +	return new;
> +}
> +
> +static int compare_decl_tags(const void *a, const void *b)
> +{
> +	return strverscmp(*(const char **)a, *(const char **)b);
> +}
> +
> +/*
> + * Compilers don't guarantee order in which BTF attributes would be generated,
> + * while order is important for test tags like __msg.
> + * Each test tag has the following prefix: "comment:" __COUNTER__,
> + * when sorted using strverscmp this gives same order as in the original C code.
>   */
> -static const char *skip_dynamic_pfx(const char *s, const char *pfx)
> +static const char **collect_decl_tags(struct btf *btf, int id, int *cnt)
>  {
> -	const char *msg;
> -
> -	if (strncmp(s, pfx, strlen(pfx)) != 0)
> -		return NULL;
> -	msg = s + strlen(pfx);
> -	msg = strchr(msg, '=');
> -	if (!msg)
> -		return NULL;
> -	return msg + 1;
> +	const struct btf_type *t;
> +	const char **tags = NULL;
> +	int i;
> +
> +	*cnt = 0;
> +	for (i = 1; i < btf__type_cnt(btf); i++) {
> +		t = btf__type_by_id(btf, i);
> +		if (!btf_is_decl_tag(t) || t->type != id || btf_decl_tag(t)->component_idx != -1)
> +			continue;
> +		tags = realloc_or_free(tags, (*cnt + 1) * sizeof(*tags));
> +		if (!tags)
> +			return ERR_PTR(-ENOMEM);
> +		tags[(*cnt)++] = btf__str_by_offset(btf, t->name_off);
> +	}
> +
> +	qsort(tags, *cnt, sizeof(*tags), compare_decl_tags);

Nit: As you will do a re-spin anyway, both claude and gemini say:

If a BTF type has no declaration tags attached, tags will remain NULL and
*cnt will be 0. Could this cause an issue with qsort()?
Passing a NULL pointer as the first argument to qsort(), even when the
number of elements is 0, is undefined behavior in C. This can trigger
UBSAN faults during selftest execution because glibc declares qsort with
__attribute__((nonnull(1, 4))).
Should we add a check for *cnt > 0 before calling qsort()?

this is from https://sashiko.dev/#/patchset/20260326-selftests-global-tags-ordering-v1-0-5dd2ced5d9ad%40gmail.com

> +	return tags;
>  }
>  
>  enum arch {
> @@ -419,7 +441,9 @@ static int parse_test_spec(struct test_loader *tester,
>  	bool stdout_on_next_line = true;
>  	bool unpriv_stdout_on_next_line = true;
>  	bool collect_jit = false;
> -	int func_id, i, err = 0;
> +	const char **tags = NULL;
> +	int func_id, i, nr_tags;
> +	int err = 0;
>  	u32 arch_mask = 0;
>  	u32 load_mask = 0;
>  	struct btf *btf;
> @@ -442,20 +466,18 @@ static int parse_test_spec(struct test_loader *tester,
>  		return -EINVAL;
>  	}
>  
> -	for (i = 1; i < btf__type_cnt(btf); i++) {
> +	tags = collect_decl_tags(btf, func_id, &nr_tags);
> +	if (IS_ERR(tags))
> +		return PTR_ERR(tags);
> +
> +	for (i = 0; i < nr_tags; i++) {
>  		const char *s, *val, *msg;
> -		const struct btf_type *t;
>  		bool clear;
>  		int flags;
>  
> -		t = btf__type_by_id(btf, i);
> -		if (!btf_is_decl_tag(t))
> +		s = skip_decl_tag_pfx(tags[i]);
> +		if (!s)
>  			continue;
> -
> -		if (t->type != func_id || btf_decl_tag(t)->component_idx != -1)
> -			continue;
> -
> -		s = btf__str_by_offset(btf, t->name_off);
>  		if ((val = str_has_pfx(s, TEST_TAG_DESCRIPTION_PFX))) {
>  			description = val;
>  		} else if (strcmp(s, TEST_TAG_EXPECT_FAILURE) == 0) {
> @@ -478,27 +500,27 @@ static int parse_test_spec(struct test_loader *tester,
>  		} else if (strcmp(s, TEST_TAG_AUXILIARY_UNPRIV) == 0) {
>  			spec->auxiliary = true;
>  			spec->mode_mask |= UNPRIV;
> -		} else if ((msg = skip_dynamic_pfx(s, TEST_TAG_EXPECT_MSG_PFX))) {
> +		} else if ((msg = str_has_pfx(s, TEST_TAG_EXPECT_MSG_PFX))) {
>  			err = push_msg(msg, false, &spec->priv.expect_msgs);
>  			if (err)
>  				goto cleanup;
>  			spec->mode_mask |= PRIV;
> -		} else if ((msg = skip_dynamic_pfx(s, TEST_TAG_EXPECT_NOT_MSG_PFX))) {
> +		} else if ((msg = str_has_pfx(s, TEST_TAG_EXPECT_NOT_MSG_PFX))) {
>  			err = push_msg(msg, true, &spec->priv.expect_msgs);
>  			if (err)
>  				goto cleanup;
>  			spec->mode_mask |= PRIV;
> -		} else if ((msg = skip_dynamic_pfx(s, TEST_TAG_EXPECT_MSG_PFX_UNPRIV))) {
> +		} else if ((msg = str_has_pfx(s, TEST_TAG_EXPECT_MSG_PFX_UNPRIV))) {
>  			err = push_msg(msg, false, &spec->unpriv.expect_msgs);
>  			if (err)
>  				goto cleanup;
>  			spec->mode_mask |= UNPRIV;
> -		} else if ((msg = skip_dynamic_pfx(s, TEST_TAG_EXPECT_NOT_MSG_PFX_UNPRIV))) {
> +		} else if ((msg = str_has_pfx(s, TEST_TAG_EXPECT_NOT_MSG_PFX_UNPRIV))) {
>  			err = push_msg(msg, true, &spec->unpriv.expect_msgs);
>  			if (err)
>  				goto cleanup;
>  			spec->mode_mask |= UNPRIV;
> -		} else if ((msg = skip_dynamic_pfx(s, TEST_TAG_JITED_PFX))) {
> +		} else if ((msg = str_has_pfx(s, TEST_TAG_JITED_PFX))) {
>  			if (arch_mask == 0) {
>  				PRINT_FAIL("__jited used before __arch_*");
>  				goto cleanup;
> @@ -510,7 +532,7 @@ static int parse_test_spec(struct test_loader *tester,
>  					goto cleanup;
>  				spec->mode_mask |= PRIV;
>  			}
> -		} else if ((msg = skip_dynamic_pfx(s, TEST_TAG_JITED_PFX_UNPRIV))) {
> +		} else if ((msg = str_has_pfx(s, TEST_TAG_JITED_PFX_UNPRIV))) {
>  			if (arch_mask == 0) {
>  				PRINT_FAIL("__unpriv_jited used before __arch_*");
>  				goto cleanup;
> @@ -522,13 +544,13 @@ static int parse_test_spec(struct test_loader *tester,
>  					goto cleanup;
>  				spec->mode_mask |= UNPRIV;
>  			}
> -		} else if ((msg = skip_dynamic_pfx(s, TEST_TAG_EXPECT_XLATED_PFX))) {
> +		} else if ((msg = str_has_pfx(s, TEST_TAG_EXPECT_XLATED_PFX))) {
>  			err = push_disasm_msg(msg, &xlated_on_next_line,
>  					      &spec->priv.expect_xlated);
>  			if (err)
>  				goto cleanup;
>  			spec->mode_mask |= PRIV;
> -		} else if ((msg = skip_dynamic_pfx(s, TEST_TAG_EXPECT_XLATED_PFX_UNPRIV))) {
> +		} else if ((msg = str_has_pfx(s, TEST_TAG_EXPECT_XLATED_PFX_UNPRIV))) {
>  			err = push_disasm_msg(msg, &unpriv_xlated_on_next_line,
>  					      &spec->unpriv.expect_xlated);
>  			if (err)
> @@ -611,22 +633,22 @@ static int parse_test_spec(struct test_loader *tester,
>  				err = -EINVAL;
>  				goto cleanup;
>  			}
> -		} else if ((msg = skip_dynamic_pfx(s, TEST_TAG_EXPECT_STDERR_PFX))) {
> +		} else if ((msg = str_has_pfx(s, TEST_TAG_EXPECT_STDERR_PFX))) {
>  			err = push_disasm_msg(msg, &stderr_on_next_line,
>  					      &spec->priv.stderr);
>  			if (err)
>  				goto cleanup;
> -		} else if ((msg = skip_dynamic_pfx(s, TEST_TAG_EXPECT_STDERR_PFX_UNPRIV))) {
> +		} else if ((msg = str_has_pfx(s, TEST_TAG_EXPECT_STDERR_PFX_UNPRIV))) {
>  			err = push_disasm_msg(msg, &unpriv_stderr_on_next_line,
>  					      &spec->unpriv.stderr);
>  			if (err)
>  				goto cleanup;
> -		} else if ((msg = skip_dynamic_pfx(s, TEST_TAG_EXPECT_STDOUT_PFX))) {
> +		} else if ((msg = str_has_pfx(s, TEST_TAG_EXPECT_STDOUT_PFX))) {
>  			err = push_disasm_msg(msg, &stdout_on_next_line,
>  					      &spec->priv.stdout);
>  			if (err)
>  				goto cleanup;
> -		} else if ((msg = skip_dynamic_pfx(s, TEST_TAG_EXPECT_STDOUT_PFX_UNPRIV))) {
> +		} else if ((msg = str_has_pfx(s, TEST_TAG_EXPECT_STDOUT_PFX_UNPRIV))) {
>  			err = push_disasm_msg(msg, &unpriv_stdout_on_next_line,
>  					      &spec->unpriv.stdout);
>  			if (err)
> @@ -706,9 +728,11 @@ static int parse_test_spec(struct test_loader *tester,
>  
>  	spec->valid = true;
>  
> +	free(tags);
>  	return 0;
>  
>  cleanup:
> +	free(tags);
>  	free_test_spec(spec);
>  	return err;
>  }
>
> -- 
> 2.53.0

  parent reply	other threads:[~2026-03-30 15:36 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-26 17:39 [PATCH 0/4] selftests/bpf: impose global ordering for test decl_tags Eduard Zingerman
2026-03-26 17:39 ` [PATCH 1/4] selftests/bpf: fix __jited_unpriv tag name Eduard Zingerman
2026-03-27 21:52   ` Ihor Solodrai
2026-03-26 17:39 ` [PATCH 2/4] selftests/bpf: make str_has_pfx return pointer past the prefix Eduard Zingerman
2026-03-27 21:54   ` Ihor Solodrai
2026-03-27 21:57     ` Eduard Zingerman
2026-03-30 15:32   ` Puranjay Mohan
2026-03-30 22:52     ` Eduard Zingerman
2026-03-26 17:39 ` [PATCH 3/4] selftests/bpf: impose global ordering for test decl_tags Eduard Zingerman
2026-03-26 22:47   ` Andrii Nakryiko
2026-03-26 22:51     ` Eduard Zingerman
2026-03-26 23:00       ` Andrii Nakryiko
2026-03-26 23:30         ` Eduard Zingerman
2026-03-27 22:00   ` Ihor Solodrai
2026-03-27 22:07     ` Eduard Zingerman
2026-03-30 15:30   ` Puranjay Mohan
2026-03-30 22:53     ` Eduard Zingerman
2026-03-30 15:36   ` Puranjay Mohan [this message]
2026-03-30 22:58     ` Eduard Zingerman
2026-03-26 17:39 ` [PATCH 4/4] selftests/bpf: inline TEST_TAG constants in test_loader.c Eduard Zingerman
2026-03-27 22:04   ` Ihor Solodrai
2026-03-26 22:28 ` [PATCH 0/4] selftests/bpf: impose global ordering for test decl_tags Eduard Zingerman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=m24ilxpbww.fsf@kernel.org \
    --to=puranjay@kernel.org \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=cupertino.miranda@oracle.com \
    --cc=daniel@iogearbox.net \
    --cc=eddyz87@gmail.com \
    --cc=kernel-team@fb.com \
    --cc=martin.lau@linux.dev \
    --cc=yonghong.song@linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox