Re: [RFC PATCH 1/3] alloc_tag: skip percpu counter allocation when profiling is disabled

Suren Baghdasaryan <[email protected]>
Newsgroups org.kernel.vger.linux-modules,org.kernel.vger.linux-kernel,org.kvack.linux-mm
Message-ID <CAJuCfpHAzhCC1Sx3uJr7kbhBzc7RFqwLhMyjo04hqZz=HBJH8Q@mail.gmail.com>
On Thu, Aug 13, 2026 at 2:34 AM Hao Ge <[email protected]> wrote:
>
> After shutdown_mem_profiling() clears mem_profiling_support,
> needs_section_mem() returns false, so later modules have their codetag
> section placed as regular data and never enter the alloc_tag maple tree.
> codetag_load_module() still called load_module(), which allocated a percpu
> counter for every tag; release_module_tags() could not find these modules
> on unload, so the counters leaked.
>
> Return CODETAG_MODULE_EXCLUDED from load_module() when profiling is off:
> codetag_module_init() drops the module's cmod and no counters are
> allocated. codetag_unload_module() now always calls free_section_mem(),
> since an excluded module may still hold a reserved section.
>
> Fixes: 4835f747d3ed ("alloc_tag: support for page allocation tag compression")
> Signed-off-by: Hao Ge <[email protected]>

Thanks for the fix. I think it could be done simpler, see below.

> ---
>  include/linux/codetag.h | 4 ++++
>  lib/codetag.c           | 8 +++++---
>  mm/alloc_tag.c          | 8 ++++++--
>  3 files changed, 15 insertions(+), 5 deletions(-)
>
> diff --git a/include/linux/codetag.h b/include/linux/codetag.h
> index a25a085c2df1..88081c618673 100644
> --- a/include/linux/codetag.h
> +++ b/include/linux/codetag.h
> @@ -52,6 +52,10 @@ struct codetag_type_desc {
>  #endif
>  };
>
> +/* module_load() return values */
> +#define CODETAG_MODULE_LOAD    0       /* module loads with its tags */
> +#define CODETAG_MODULE_EXCLUDED        1       /* module loads without its tags */

I see no reason for adding these special values. You could simply
return -ENOTSUP when profiling is disabled.

> +
>  struct codetag_iterator {
>         struct codetag_type *cttype;
>         struct codetag_module *cmod;
> diff --git a/lib/codetag.c b/lib/codetag.c
> index a9cda4c962a3..8506ecab9ea7 100644
> --- a/lib/codetag.c
> +++ b/lib/codetag.c
> @@ -238,9 +238,10 @@ static int codetag_module_init(struct codetag_type *cttype, struct module *mod)
>         }
>         up_write(&cttype->mod_lock);
>
> -       if (err < 0) {
> +       if (err) {
> +               /* Error or excluded: cmod is dropped, free it. */

IIUC here you want to call kfree() if profiling got disabled. If you
return -ENOTSUP instead of CODETAG_MODULE_EXCLUDED then this condition
does not need to change.

>                 kfree(cmod);
> -               return err;
> +               return err < 0 ? err : 0;

Here you can do:
                    if (err && err != -ENOTSUP)
                            return err;
                   return 0;

>         }
>
>         return 0;
> @@ -388,7 +389,8 @@ void codetag_unload_module(struct module *mod)
>                         ++cttype->content_id;
>                 }
>                 up_write(&cttype->mod_lock);
> -               if (found && cttype->desc.free_section_mem)
> +               /* an excluded module may still hold section memory */
> +               if (cttype->desc.free_section_mem)
>                         cttype->desc.free_section_mem(mod, true);
>         }
>         mutex_unlock(&codetag_lock);
> diff --git a/mm/alloc_tag.c b/mm/alloc_tag.c
> index 0a7b657fe2de..461fa87fbb0b 100644
> --- a/mm/alloc_tag.c
> +++ b/mm/alloc_tag.c
> @@ -977,9 +977,13 @@ static int load_module(struct module *mod, struct codetag *start, struct codetag
>         struct alloc_tag *stop_tag;
>         struct alloc_tag *tag;
>
> +       /* Profiling disabled: load the module but exclude its tags. */
> +       if (!mem_profiling_support)
> +               return CODETAG_MODULE_EXCLUDED;

Return -ENOTSUP here.



> +
>         /* percpu counters for core allocations are already statically allocated */
>         if (!mod)
> -               return 0;
> +               return CODETAG_MODULE_LOAD;
>
>         start_tag = ct_to_alloc_tag(start);
>         stop_tag = ct_to_alloc_tag(stop);
> @@ -1002,7 +1006,7 @@ static int load_module(struct module *mod, struct codetag *start, struct codetag
>                  */
>                 kmemleak_ignore_percpu(tag->counters);
>         }
> -       return 0;
> +       return CODETAG_MODULE_LOAD;
>  }
>
>  static void replace_module(struct module *mod, struct module *new_mod)
> --
> 2.25.1
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.