On Fri, 24 Apr 2026 18:44:03 -0700 Rosen Penev <[email protected]> wrote:
> Change to a flexible array member to allocate together with the array > struct. > > Simplifies code slightly by removing no longer correct null checks for > pages and removing kfrees. > > Signed-off-by: Rosen Penev <[email protected]> > --- > kernel/trace/tracing_map.c | 32 +++++++++++--------------------- > kernel/trace/tracing_map.h | 2 +- > 2 files changed, 12 insertions(+), 22 deletions(-) > > diff --git a/kernel/trace/tracing_map.c b/kernel/trace/tracing_map.c > index bf1a507695b6..627cc3fdf69e 100644 > --- a/kernel/trace/tracing_map.c > +++ b/kernel/trace/tracing_map.c > @@ -288,9 +288,6 @@ static void tracing_map_array_clear(struct > tracing_map_array *a) > { > unsigned int i; > > - if (!a->pages) > - return; > - > for (i = 0; i < a->n_pages; i++) > memset(a->pages[i], 0, PAGE_SIZE); > } > @@ -302,44 +299,37 @@ static void tracing_map_array_free(struct > tracing_map_array *a) > if (!a) > return; > > - if (!a->pages) > - goto free; > - > for (i = 0; i < a->n_pages; i++) { > if (!a->pages[i]) > break; > kmemleak_free(a->pages[i]); > free_page((unsigned long)a->pages[i]); > } > - > - kfree(a->pages); > - > - free: > - kfree(a); > } Sashiko reported: https://sashiko.dev/?list=org.kernel.vger.linux-trace-kernel#/patchset/20260425014403.440786-1-rosenp%40gmail.com Does this code leak the tracing_map_array struct? While removing kfree(a->pages) is correct since the array is now inline, it looks like we still need kfree(a) to free the container struct itself which is allocated by kzalloc_flex() in tracing_map_array_alloc(). It looks to be correct. Please fix. -- Steve > > static struct tracing_map_array *tracing_map_array_alloc(unsigned int n_elts, > unsigned int entry_size) > { > struct tracing_map_array *a; > + unsigned int entry_size_shift; > + unsigned int entries_per_page; > + unsigned int n_pages; > unsigned int i; > > - a = kzalloc_obj(*a); > + entry_size_shift = fls(roundup_pow_of_two(entry_size) - 1); > + entries_per_page = PAGE_SIZE / (1 << entry_size_shift); > + n_pages = max(1, n_elts / entries_per_page); > + > + a = kzalloc_flex(*a, pages, n_pages); > if (!a) > return NULL; > > - a->entry_size_shift = fls(roundup_pow_of_two(entry_size) - 1); > - a->entries_per_page = PAGE_SIZE / (1 << a->entry_size_shift); > - a->n_pages = n_elts / a->entries_per_page; > - if (!a->n_pages) > - a->n_pages = 1; > + a->entry_size_shift = entry_size_shift; > + a->entries_per_page = entries_per_page; > + a->n_pages = n_pages; > a->entry_shift = fls(a->entries_per_page) - 1; > a->entry_mask = (1 << a->entry_shift) - 1; > > - a->pages = kcalloc(a->n_pages, sizeof(void *), GFP_KERNEL); > - if (!a->pages) > - goto free; > - > for (i = 0; i < a->n_pages; i++) { > a->pages[i] = (void *)get_zeroed_page(GFP_KERNEL); > if (!a->pages[i]) > diff --git a/kernel/trace/tracing_map.h b/kernel/trace/tracing_map.h > index 99c37eeebc16..18a02959d77b 100644 > --- a/kernel/trace/tracing_map.h > +++ b/kernel/trace/tracing_map.h > @@ -167,7 +167,7 @@ struct tracing_map_array { > unsigned int entry_shift; > unsigned int entry_mask; > unsigned int n_pages; > - void **pages; > + void *pages[] __counted_by(n_pages); > }; > > #define TRACING_MAP_ARRAY_ELT(array, idx) \
