[PATCH 3/6] alloc_tag: add size-based filtering to ioctl
From: Abhishek Bapat
Date: Mon May 04 2026 - 19:37:46 EST
Extend the allocinfo filtering mechanism to allow users to filter tags
based on the total number of bytes allocated [min_size, max_size]. The
size range is inclusive.
Filtering by size involves retrieving allocinfo per-CPU counters, which
is an expensive operation. Hence, the performance of size-based
filtering will be worse than other filters.
Signed-off-by: Abhishek Bapat <abhishekbapat@xxxxxxxxxx>
---
include/uapi/linux/alloc_tag.h | 8 +++++++-
lib/alloc_tag.c | 15 +++++++++++++++
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/include/uapi/linux/alloc_tag.h b/include/uapi/linux/alloc_tag.h
index 0cc9db5298c6..229068efd24c 100644
--- a/include/uapi/linux/alloc_tag.h
+++ b/include/uapi/linux/alloc_tag.h
@@ -20,6 +20,8 @@ struct allocinfo_tag {
char function[ALLOCINFO_STR_SIZE];
char filename[ALLOCINFO_STR_SIZE];
__u64 lineno;
+ __u64 min_size;
+ __u64 max_size;
};
struct allocinfo_counter {
@@ -39,13 +41,17 @@ enum {
ALLOCINFO_FILTER_FUNCTION,
ALLOCINFO_FILTER_FILENAME,
ALLOCINFO_FILTER_LINENO,
- __ALLOCINFO_FILTER_LAST = ALLOCINFO_FILTER_LINENO
+ ALLOCINFO_FILTER_MIN_SIZE,
+ ALLOCINFO_FILTER_MAX_SIZE,
+ __ALLOCINFO_FILTER_LAST = ALLOCINFO_FILTER_MAX_SIZE
};
#define ALLOCINFO_FILTER_MASK_MODNAME (1 << ALLOCINFO_FILTER_MODNAME)
#define ALLOCINFO_FILTER_MASK_FUNCTION (1 << ALLOCINFO_FILTER_FUNCTION)
#define ALLOCINFO_FILTER_MASK_FILENAME (1 << ALLOCINFO_FILTER_FILENAME)
#define ALLOCINFO_FILTER_MASK_LINENO (1 << ALLOCINFO_FILTER_LINENO)
+#define ALLOCINFO_FILTER_MASK_MIN_SIZE (1 << ALLOCINFO_FILTER_MIN_SIZE)
+#define ALLOCINFO_FILTER_MASK_MAX_SIZE (1 << ALLOCINFO_FILTER_MAX_SIZE)
#define ALLOCINFO_FILTER_MASKS \
((1 << (__ALLOCINFO_FILTER_LAST + 1)) - 1)
diff --git a/lib/alloc_tag.c b/lib/alloc_tag.c
index 7ff936e15e97..98a27c302928 100644
--- a/lib/alloc_tag.c
+++ b/lib/alloc_tag.c
@@ -195,6 +195,9 @@ static int allocinfo_ioctl_get_content_id(struct seq_file *m, void __user *arg)
static bool matches_filter(struct codetag *ct, struct allocinfo_filter *filter)
{
+ struct alloc_tag *tag;
+ struct alloc_tag_counters counters;
+
if (!ct || !filter || !filter->mask)
return true;
@@ -214,6 +217,18 @@ static bool matches_filter(struct codetag *ct, struct allocinfo_filter *filter)
ct->lineno != filter->fields.lineno)
return false;
+ if ((filter->mask & ALLOCINFO_FILTER_MASK_MIN_SIZE) ||
+ (filter->mask & ALLOCINFO_FILTER_MASK_MAX_SIZE)) {
+ tag = ct_to_alloc_tag(ct);
+ counters = alloc_tag_read(tag);
+ if ((filter->mask & ALLOCINFO_FILTER_MASK_MIN_SIZE) &&
+ counters.bytes < filter->fields.min_size)
+ return false;
+ if ((filter->mask & ALLOCINFO_FILTER_MASK_MAX_SIZE) &&
+ counters.bytes > filter->fields.max_size)
+ return false;
+ }
+
return true;
}
--
2.54.0.545.g6539524ca2-goog