From: Hao Ge <hao.ge@linux.dev>
To: Abhishek Bapat <abhishekbapat@google.com>,
Suren Baghdasaryan <surenb@google.com>,
Andrew Morton <akpm@linux-foundation.org>,
Kent Overstreet <kent.overstreet@linux.dev>
Cc: Shuah Khan <skhan@linuxfoundation.org>,
Jonathan Corbet <corbet@lwn.net>,
linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-mm@kvack.org, Sourav Panda <souravpanda@google.com>
Subject: Re: [PATCH v8 6/6] kselftest: alloc_tag: extend the allocinfo ioctl kselftest
Date: Thu, 9 Jul 2026 15:47:28 +0800 [thread overview]
Message-ID: <9d92b421-b4f5-40b1-9f17-6039cd0571e9@linux.dev> (raw)
In-Reply-To: <e5171926b48802531284c1cb5f04734017141341.1783532853.git.abhishekbapat@google.com>
Hi Abhishek
On 2026/7/9 02:01, Abhishek Bapat wrote:
> Add the following 2 scenarios to the allocinfo ioctl kselftest:
> 1. Validate size based filtering
> 2. Validate lineno based filtering
>
> The first test uses "do_init_module" as the candidate function for the
> test. This is because the associated site will only allocate memory when
> a kernel module is loaded. The return value of get_content_id() changes
> every time modules are loaded or unloaded. Hence, as long as
> get_content_id() values at the start and the end of the test are the
> same, the memory allocated by the do_init_module call site should also
> remain the same. Consequently, the test can assume consistency between
> the value returned by the ioctl and the procfs resulting in less
> flakiness.
>
> Signed-off-by: Abhishek Bapat <abhishekbapat@google.com>
Tested-by: Hao Ge <hao.ge@linux.dev>
Acked-by: Hao Ge <hao.ge@linux.dev>
> ---
> .../alloc_tag/allocinfo_ioctl_test.c | 216 +++++++++++++++++-
> 1 file changed, 215 insertions(+), 1 deletion(-)
>
> diff --git a/tools/testing/selftests/alloc_tag/allocinfo_ioctl_test.c b/tools/testing/selftests/alloc_tag/allocinfo_ioctl_test.c
> index 9ce7b53078b1..7d94abb785a1 100644
> --- a/tools/testing/selftests/alloc_tag/allocinfo_ioctl_test.c
> +++ b/tools/testing/selftests/alloc_tag/allocinfo_ioctl_test.c
> @@ -5,6 +5,7 @@
> * Copyright (C) 2026 Google, Inc.
> */
>
> +#include <errno.h>
> #include <fcntl.h>
> #include <stdio.h>
> #include <stdlib.h>
> @@ -312,11 +313,212 @@ static int test_function_filter(void)
> return run_filter_test(&filter);
> }
>
> +static int test_size_filter(void)
> +{
> + int fd;
> + struct allocinfo_tag_data_vec *tags = malloc(sizeof(*tags));
> + struct allocinfo_tag_data_vec *procfs_entries = malloc(sizeof(*procfs_entries));
> + struct allocinfo_filter filter;
> + int ret = KSFT_PASS;
> + __u64 target_size, i, pos;
> + struct allocinfo_tag_data *found_tag = NULL;
> + const char *target_function = "do_init_module";
> + struct allocinfo_content_id start_cont_id, end_cont_id;
> + int retry = 0;
> + const int max_retries = 10;
> +
> + if (!tags || !procfs_entries) {
> + ksft_print_msg("Memory allocation failed.\n");
> + ret = KSFT_FAIL;
> + goto freemem;
> + }
> +
> + fd = open(ALLOCINFO_PROC, O_RDONLY);
> + if (fd < 0) {
> + ksft_print_msg("Failed to open " ALLOCINFO_PROC ": %s\n", strerror(errno));
> + ret = KSFT_SKIP;
> + goto freemem;
> + }
> +
> + do {
> + found_tag = NULL;
> + pos = 0;
> +
> + if (__allocinfo_get_content_id(fd, &start_cont_id)) {
> + ksft_print_msg("allocinfo_get_content_id failed\n");
> + ret = KSFT_FAIL;
> + goto exit;
> + }
> +
> + memset(&filter, 0, sizeof(filter));
> + filter.mask |= ALLOCINFO_FILTER_MASK_FUNCTION;
> + strncpy(filter.fields.function, target_function, ALLOCINFO_STR_SIZE);
> +
> + if (get_filtered_procfs_entries(procfs_entries, &filter)) {
> + ksft_print_msg("Error retrieving entries from " ALLOCINFO_PROC "\n");
> + ret = KSFT_SKIP;
> + goto exit;
> + }
> +
> + if (procfs_entries->count == 0) {
> + ksft_print_msg("Function %s not found in procfs\n", target_function);
> + ret = KSFT_SKIP;
> + goto exit;
> + }
> +
> + target_size = procfs_entries->tag[0].counter.bytes;
> +
> + memset(&filter, 0, sizeof(filter));
> + filter.mask |= ALLOCINFO_FILTER_MASK_MIN_SIZE | ALLOCINFO_FILTER_MASK_MAX_SIZE;
> + filter.min_size = target_size;
> + filter.max_size = target_size;
> +
> + while (1) {
> + struct allocinfo_get_at get_at_params;
> +
> + memset(&get_at_params, 0, sizeof(get_at_params));
> + memcpy(&get_at_params.filter, &filter, sizeof(filter));
> + get_at_params.pos = pos;
> +
> + if (__allocinfo_get_at(fd, &get_at_params))
> + break;
> +
> + tags->count = 0;
> + memcpy(&tags->tag[tags->count++], &get_at_params.data,
> + sizeof(get_at_params.data));
> +
> + while (tags->count < VEC_MAX_ENTRIES &&
> + __allocinfo_get_next(fd, &tags->tag[tags->count]) == 0)
> + tags->count++;
> +
> + for (i = 0; i < tags->count; i++) {
> + if (strcmp(tags->tag[i].tag.function, target_function) == 0) {
> + found_tag = &tags->tag[i];
> + break;
> + }
> + }
> +
> + if (found_tag || tags->count < VEC_MAX_ENTRIES)
> + break;
> +
> + pos += tags->count;
> + }
> +
> + if (__allocinfo_get_content_id(fd, &end_cont_id)) {
> + ksft_print_msg("allocinfo_get_content_id failed\n");
> + ret = KSFT_FAIL;
> + goto exit;
> + }
> +
> + if (start_cont_id.id == end_cont_id.id)
> + break;
> +
> + ksft_print_msg("Module load detected during size verification, retrying...\n");
> + } while (retry++ < max_retries);
> +
> + if (start_cont_id.id == end_cont_id.id && !found_tag) {
> + ksft_print_msg("Entry with function %s not found in IOCTL results\n",
> + target_function);
> + ret = KSFT_FAIL;
> + } else if (start_cont_id.id != end_cont_id.id) {
> + ksft_print_msg("Failed to match content_ids for procfs and IOCTL, skipping...\n");
> + ret = KSFT_SKIP;
> + } else if (found_tag && found_tag->counter.bytes != target_size) {
> + ksft_print_msg("IOCTL entry size %llu does not match target size %llu\n",
> + found_tag->counter.bytes, target_size);
> + ret = KSFT_FAIL;
> + }
> +
> +exit:
> + close(fd);
> +freemem:
> + free(tags);
> + free(procfs_entries);
> + return ret;
> +}
> +
> +static int test_lineno_filter(void)
> +{
> + struct allocinfo_tag_data_vec *tags = malloc(sizeof(*tags));
> + struct allocinfo_tag_data_vec *procfs_entries = malloc(sizeof(*procfs_entries));
> + struct allocinfo_filter filter;
> + enum ioctl_ret ioctl_status;
> + int ret = KSFT_PASS;
> + __u64 target_lineno, i;
> + struct allocinfo_tag_data *target_tag;
> + bool found = false;
> +
> + if (!tags || !procfs_entries) {
> + ksft_print_msg("Memory allocation failed.\n");
> + ret = KSFT_FAIL;
> + goto exit;
> + }
> +
> + memset(&filter, 0, sizeof(filter));
> +
> + if (get_filtered_procfs_entries(procfs_entries, &filter)) {
> + ksft_print_msg("Error retrieving entries from " ALLOCINFO_PROC "\n");
> + ret = KSFT_SKIP;
> + goto exit;
> + }
> + if (procfs_entries->count == 0) {
> + ksft_print_msg("Could not retrieve procfs entries\n");
> + ret = KSFT_SKIP;
> + goto exit;
> + }
> + /*
> + * We depend on the procfs results to determine the line number for the filter before
> + * making the ioctl query. Hence, we cannot reuse run_filter_test here.
> + */
> + target_tag = &procfs_entries->tag[0];
> + target_lineno = target_tag->tag.lineno;
> +
> + filter.mask |= ALLOCINFO_FILTER_MASK_LINENO;
> + filter.fields.lineno = target_lineno;
> +
> + ioctl_status = get_filtered_ioctl_entries(tags, &filter, 0);
> + if (ioctl_status == IOCTL_INVALID_DATA) {
> + ksft_print_msg("Trouble retrieving valid IOCTL entries, skipping.\n");
> + ret = KSFT_SKIP;
> + goto exit;
> + }
> + if (ioctl_status == IOCTL_FAILURE) {
> + ksft_print_msg("Error retrieving IOCTL entries.\n");
> + ret = KSFT_FAIL;
> + goto exit;
> + }
> +
> + for (i = 0; i < tags->count; i++) {
> + if (tags->tag[i].tag.lineno != target_lineno) {
> + ksft_print_msg("IOCTL entry %llu has incorrect lineno %llu.\n",
> + i, tags->tag[i].tag.lineno);
> + ret = KSFT_FAIL;
> + goto exit;
> + }
> +
> + if (strncmp(tags->tag[i].tag.function, target_tag->tag.function,
> + ALLOCINFO_STR_SIZE) == 0 &&
> + strncmp(tags->tag[i].tag.filename, target_tag->tag.filename,
> + ALLOCINFO_STR_SIZE) == 0)
> + found = true;
> + }
> +
> + if (!found) {
> + ksft_print_msg("Original procfs entry not found in IOCTL lineno filter results.\n");
> + ret = KSFT_FAIL;
> + }
> +
> +exit:
> + free(tags);
> + free(procfs_entries);
> + return ret;
> +}
> +
> int main(int argc, char *argv[])
> {
> int ret;
>
> - ksft_set_plan(2);
> + ksft_set_plan(4);
>
> ret = test_filename_filter();
> if (ret == KSFT_SKIP)
> @@ -330,5 +532,17 @@ int main(int argc, char *argv[])
> else
> ksft_test_result(ret == KSFT_PASS, "test_function_filter\n");
>
> + ret = test_size_filter();
> + if (ret == KSFT_SKIP)
> + ksft_test_result_skip("Skipping test_size_filter\n");
> + else
> + ksft_test_result(ret == KSFT_PASS, "test_size_filter\n");
> +
> + ret = test_lineno_filter();
> + if (ret == KSFT_SKIP)
> + ksft_test_result_skip("Skipping test_lineno_filter\n");
> + else
> + ksft_test_result(ret == KSFT_PASS, "test_lineno_filter\n");
> +
> ksft_finished();
> }
next prev parent reply other threads:[~2026-07-09 7:47 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-08 18:01 [PATCH v8 0/6] alloc_tag: introduce IOCTL-based filtering for MAP Abhishek Bapat
2026-07-08 18:01 ` [PATCH v8 1/6] alloc_tag: add ioctl to /proc/allocinfo Abhishek Bapat
2026-07-08 18:01 ` [PATCH v8 2/6] alloc_tag: add ioctl filters " Abhishek Bapat
2026-07-08 18:01 ` [PATCH v8 3/6] alloc_tag: add size-based filtering to ioctl Abhishek Bapat
2026-07-08 18:01 ` [PATCH v8 4/6] alloc_tag: add accuracy based " Abhishek Bapat
2026-07-08 18:01 ` [PATCH v8 5/6] kselftest: alloc_tag: add kselftest for ioctl interface Abhishek Bapat
2026-07-09 7:32 ` Hao Ge
2026-07-08 18:01 ` [PATCH v8 6/6] kselftest: alloc_tag: extend the allocinfo ioctl kselftest Abhishek Bapat
2026-07-09 7:47 ` Hao Ge [this message]
2026-07-08 21:13 ` [PATCH v8 0/6] alloc_tag: introduce IOCTL-based filtering for MAP Andrew Morton
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=9d92b421-b4f5-40b1-9f17-6039cd0571e9@linux.dev \
--to=hao.ge@linux.dev \
--cc=abhishekbapat@google.com \
--cc=akpm@linux-foundation.org \
--cc=corbet@lwn.net \
--cc=kent.overstreet@linux.dev \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=skhan@linuxfoundation.org \
--cc=souravpanda@google.com \
--cc=surenb@google.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.