[PATCH v2 2/3] malloc: Remove code conditional on USE_MTAG
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Wed May 20 20:28:08 GMT 2026
On 20/05/26 10:27, Yury Khrustalev wrote:
> Further malloc refactoring related to memory tagging.
>
> Remove code that was only compiled when macro USE_MTAG was defined
> except for the AArch64-specific assembly MTE code that is going to
> be compiled unconditionally from now on.
>
> As a result, we change 'mtag_mmap_flags' to 'extra_mmap_prot' that
> is now always defined. Change of the name due to this being used
> as part of PROT options in mmap syscalls rather than part of flags.
>
> Remove 'mtag_enabled' that would become compile-time false. Also
> remove any code that would never be compiled when 'mtag_enabled'
> is false.
LGTM, thanks. I think maybe it would be better to just squash all
the patches in only one.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> ---
> malloc/arena.c | 18 +----
> malloc/malloc-check.c | 10 ---
> malloc/malloc.c | 73 +------------------
> sysdeps/aarch64/__mtag_tag_region.S | 3 -
> sysdeps/aarch64/__mtag_tag_zero_region.S | 3 -
> sysdeps/aarch64/cpu-features.h | 3 +-
> sysdeps/aarch64/libc-mtag.h | 5 +-
> .../unix/sysv/linux/aarch64/cpu-features.c | 28 -------
> 8 files changed, 8 insertions(+), 135 deletions(-)
>
> diff --git a/malloc/arena.c b/malloc/arena.c
> index ddde32c712..023cb3ba06 100644
> --- a/malloc/arena.c
> +++ b/malloc/arena.c
> @@ -252,20 +252,6 @@ __ptmalloc_init (void)
> tcache_key_initialize ();
> #endif
>
> -#ifdef USE_MTAG
> - if ((TUNABLE_GET_FULL (glibc, mem, tagging, int32_t, NULL) & 1) != 0)
> - {
> - /* If the tunable says that we should be using tagged memory
> - and that morecore does not support tagged regions, then
> - disable it. */
> - if (__MTAG_SBRK_UNTAGGED)
> - __always_fail_morecore = true;
> -
> - mtag_enabled = true;
> - mtag_mmap_flags = __MTAG_MMAP_FLAGS;
> - }
> -#endif
> -
> #if defined SHARED && IS_IN (libc)
> /* In case this libc copy is in a non-default namespace, never use
> brk. Likewise if dlopened from statically linked program. The
> @@ -417,7 +403,7 @@ alloc_new_heap (size_t size, size_t top_pad, size_t pagesize,
> }
> }
> }
> - if (__mprotect (p2, size, mtag_mmap_flags | PROT_READ | PROT_WRITE) != 0)
> + if (__mprotect (p2, size, extra_mmap_prot | PROT_READ | PROT_WRITE) != 0)
> {
> __munmap (p2, max_size);
> return NULL;
> @@ -471,7 +457,7 @@ grow_heap (heap_info *h, long diff)
> {
> if (__mprotect ((char *) h + h->mprotect_size,
> (unsigned long) new_size - h->mprotect_size,
> - mtag_mmap_flags | PROT_READ | PROT_WRITE) != 0)
> + extra_mmap_prot | PROT_READ | PROT_WRITE) != 0)
> return -2;
>
> h->mprotect_size = new_size;
> diff --git a/malloc/malloc-check.c b/malloc/malloc-check.c
> index 49b623df12..ae5025d69a 100644
> --- a/malloc/malloc-check.c
> +++ b/malloc/malloc-check.c
> @@ -217,11 +217,6 @@ free_check (void *mem)
>
> int err = errno;
>
> - /* Quickly check that the freed pointer matches the tag for the memory.
> - This gives a useful double-free detection. */
> - if (__glibc_unlikely (mtag_enabled))
> - *(volatile char *)mem;
> -
> __libc_lock_lock (main_arena.mutex);
> p = mem2chunk_check (mem, NULL);
> if (!p)
> @@ -263,11 +258,6 @@ realloc_check (void *oldmem, size_t bytes)
> return NULL;
> }
>
> - /* Quickly check that the freed pointer matches the tag for the memory.
> - This gives a useful double-free detection. */
> - if (__glibc_unlikely (mtag_enabled))
> - *(volatile char *)oldmem;
> -
> __libc_lock_lock (main_arena.mutex);
> const mchunkptr oldp = mem2chunk_check (oldmem, &magic_p);
> __libc_lock_unlock (main_arena.mutex);
> diff --git a/malloc/malloc.c b/malloc/malloc.c
> index 5313ee68e3..d7224f775c 100644
> --- a/malloc/malloc.c
> +++ b/malloc/malloc.c
> @@ -405,27 +405,17 @@ verify (PTRDIFF_MAX <= SIZE_MAX / 2);
> tagging is not enabled, it simply returns the original pointer.
> */
>
> -#ifdef USE_MTAG
> -static bool mtag_enabled = false;
> -static int mtag_mmap_flags = 0;
> -#else
> -# define mtag_enabled false
> -# define mtag_mmap_flags 0
> -#endif
> +static int extra_mmap_prot = 0;
>
> static __always_inline void *
> tag_region (void *ptr, size_t size)
> {
> - if (__glibc_unlikely (mtag_enabled))
> - return __libc_mtag_tag_region (ptr, size);
> return ptr;
> }
>
> static __always_inline void *
> tag_new_zero_region (void *ptr, size_t size)
> {
> - if (__glibc_unlikely (mtag_enabled))
> - return __libc_mtag_tag_zero_region (__libc_mtag_new_tag (ptr), size);
> return memset (ptr, 0, size);
> }
>
> @@ -436,8 +426,6 @@ tag_new_usable (void *ptr);
> static __always_inline void *
> tag_at (void *ptr)
> {
> - if (__glibc_unlikely (mtag_enabled))
> - return __libc_mtag_address_get_tag (ptr);
> return ptr;
> }
>
> @@ -1258,23 +1246,6 @@ checked_request2size (size_t req) __nonnull (1)
> {
> if (__glibc_unlikely (req > PTRDIFF_MAX))
> return SIZE_MAX;
> -
> - /* When using tagged memory, we cannot share the end of the user
> - block with the header for the next chunk, so ensure that we
> - allocate blocks that are rounded up to the granule size. Take
> - care not to overflow from close to MAX_SIZE_T to a small
> - number. Ideally, this would be part of request2size(), but that
> - must be a macro that produces a compile time constant if passed
> - a constant literal. */
> - if (__glibc_unlikely (mtag_enabled))
> - {
> - /* Ensure this is not evaluated if !mtag_enabled, see gcc PR 99551. */
> - asm ("");
> -
> - req = (req + (__MTAG_GRANULE_SIZE - 1)) &
> - ~(size_t)(__MTAG_GRANULE_SIZE - 1);
> - }
> -
> return request2size (req);
> }
>
> @@ -1377,25 +1348,11 @@ checked_request2size (size_t req) __nonnull (1)
>
> /* This is the size of the real usable data in the chunk. Not valid for
> dumped heap chunks. */
> -#define memsize(p) \
> - (__MTAG_GRANULE_SIZE > SIZE_SZ && __glibc_unlikely (mtag_enabled) ? \
> - chunksize (p) - CHUNK_HDR_SZ : \
> - chunksize (p) - CHUNK_HDR_SZ + SIZE_SZ)
> -
> -/* If memory tagging is enabled the layout changes to accommodate the granule
> - size, this is wasteful for small allocations so not done by default.
> - Both the chunk header and user data has to be granule aligned. */
> -_Static_assert (__MTAG_GRANULE_SIZE <= CHUNK_HDR_SZ,
> - "memory tagging is not supported with large granule.");
> +#define memsize(p) (chunksize (p) - CHUNK_HDR_SZ + SIZE_SZ)
>
> static __always_inline void *
> tag_new_usable (void *ptr)
> {
> - if (__glibc_unlikely (mtag_enabled) && ptr)
> - {
> - mchunkptr cp = mem2chunk(ptr);
> - ptr = __libc_mtag_tag_region (__libc_mtag_new_tag (ptr), memsize (cp));
> - }
> return ptr;
> }
>
> @@ -2228,7 +2185,7 @@ sysmalloc_mmap (INTERNAL_SIZE_T nb, size_t pagesize, int extra_flags)
> size_t size = ALIGN_UP (nb + padding + CHUNK_HDR_SZ, pagesize);
>
> char *mm = (char *) MMAP (NULL, size,
> - mtag_mmap_flags | PROT_READ | PROT_WRITE,
> + extra_mmap_prot | PROT_READ | PROT_WRITE,
> extra_flags);
> if (mm == MAP_FAILED)
> return mm;
> @@ -2269,7 +2226,7 @@ sysmalloc_mmap_fallback (size_t *s, size_t size, size_t minsize,
> size = minsize;
>
> char *mbrk = (char *) (MMAP (NULL, size,
> - mtag_mmap_flags | PROT_READ | PROT_WRITE,
> + extra_mmap_prot | PROT_READ | PROT_WRITE,
> extra_flags));
> if (mbrk == MAP_FAILED)
> return MAP_FAILED;
> @@ -3296,11 +3253,6 @@ __libc_free (void *mem)
> if (mem == NULL) /* free(0) has no effect */
> return;
>
> - /* Quickly check that the freed pointer matches the tag for the memory.
> - This gives a useful double-free detection. */
> - if (__glibc_unlikely (mtag_enabled))
> - *(volatile char *)mem;
> -
> p = mem2chunk (mem);
>
> /* Mark the chunk as belonging to the library again. */
> @@ -3368,11 +3320,6 @@ __libc_realloc (void *oldmem, size_t bytes)
> }
> #endif
>
> - /* Perform a quick check to ensure that the pointer's tag matches the
> - memory's tag. */
> - if (__glibc_unlikely (mtag_enabled))
> - *(volatile char*) oldmem;
> -
> /* chunk corresponding to oldmem */
> const mchunkptr oldp = mem2chunk (oldmem);
>
> @@ -3668,12 +3615,6 @@ __libc_calloc2 (size_t sz)
>
> p = mem2chunk (mem);
>
> - /* If we are using memory tagging, then we need to set the tags
> - regardless of MORECORE_CLEARS, so we zero the whole block while
> - doing so. */
> - if (__glibc_unlikely (mtag_enabled))
> - return tag_new_zero_region (mem, memsize (p));
> -
> csz = chunksize (p);
>
> /* Two optional cases in which clearing not necessary */
> @@ -3720,9 +3661,6 @@ __libc_calloc (size_t n, size_t elem_size)
> if (tcache->entries[tc_idx] != NULL)
> {
> void *mem = tcache_get (tc_idx);
> - if (__glibc_unlikely (mtag_enabled))
> - return tag_new_zero_region (mem, memsize (mem2chunk (mem)));
> -
> return clear_memory ((INTERNAL_SIZE_T *) mem, tidx2usize (tc_idx));
> }
> }
> @@ -3732,9 +3670,6 @@ __libc_calloc (size_t n, size_t elem_size)
> void *mem = tcache_get_large (tc_idx, nb);
> if (mem != NULL)
> {
> - if (__glibc_unlikely (mtag_enabled))
> - return tag_new_zero_region (mem, memsize (mem2chunk (mem)));
> -
> return memset (mem, 0, memsize (mem2chunk (mem)));
> }
> }
> diff --git a/sysdeps/aarch64/__mtag_tag_region.S b/sysdeps/aarch64/__mtag_tag_region.S
> index bad3193bfe..85e330812e 100644
> --- a/sysdeps/aarch64/__mtag_tag_region.S
> +++ b/sysdeps/aarch64/__mtag_tag_region.S
> @@ -18,8 +18,6 @@
>
> #include <sysdep.h>
>
> -#ifdef USE_MTAG
> -
> /* Assumptions:
> *
> * ARMv8-a, AArch64, MTE, LP64 ABI.
> @@ -107,4 +105,3 @@ L(no_zva_loop):
> ret
>
> END (__libc_mtag_tag_region)
> -#endif /* USE_MTAG */
> diff --git a/sysdeps/aarch64/__mtag_tag_zero_region.S b/sysdeps/aarch64/__mtag_tag_zero_region.S
> index 3bc6e7301f..1a84b3e4d4 100644
> --- a/sysdeps/aarch64/__mtag_tag_zero_region.S
> +++ b/sysdeps/aarch64/__mtag_tag_zero_region.S
> @@ -18,8 +18,6 @@
>
> #include <sysdep.h>
>
> -#ifdef USE_MTAG
> -
> /* Assumptions:
> *
> * ARMv8-a, AArch64, MTE, LP64 ABI.
> @@ -107,4 +105,3 @@ L(no_zva_loop):
> ret
>
> END (__libc_mtag_tag_zero_region)
> -#endif /* USE_MTAG */
> diff --git a/sysdeps/aarch64/cpu-features.h b/sysdeps/aarch64/cpu-features.h
> index d6367a4596..f414060066 100644
> --- a/sysdeps/aarch64/cpu-features.h
> +++ b/sysdeps/aarch64/cpu-features.h
> @@ -64,8 +64,7 @@ struct cpu_features
> uint64_t midr_el1;
> unsigned zva_size;
> bool bti;
> - /* Currently, the GLIBC memory tagging tunable only defines 8 bits. */
> - uint8_t mte_state;
> + uint8_t reserved;
> bool sve;
> bool unused;
> bool mops;
> diff --git a/sysdeps/aarch64/libc-mtag.h b/sysdeps/aarch64/libc-mtag.h
> index 1d7368b806..663b866bf8 100644
> --- a/sysdeps/aarch64/libc-mtag.h
> +++ b/sysdeps/aarch64/libc-mtag.h
> @@ -19,10 +19,7 @@
> #ifndef _AARCH64_LIBC_MTAG_H
> #define _AARCH64_LIBC_MTAG_H 1
>
> -#ifndef USE_MTAG
> -/* Generic bindings for systems that do not support memory tagging. */
> -#include_next "libc-mtag.h"
> -#else
> +#if 0
>
> /* Used to ensure additional alignment when objects need to have distinct
> tags. */
> diff --git a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
> index 36bd72bb12..cda1f82948 100644
> --- a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
> +++ b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c
> @@ -20,7 +20,6 @@
> #include <cpu-features.h>
> #include <sys/auxv.h>
> #include <elf/dl-hwcaps.h>
> -#include <sys/prctl.h>
> #include <sys/utsname.h>
> #include <dl-tunables-parse.h>
> #include <dl-symbol-redir-ifunc.h>
> @@ -96,33 +95,6 @@ init_cpu_features (struct cpu_features *cpu_features)
> if (cpu_features->bti)
> GLRO (dl_aarch64_bti) = TUNABLE_GET (glibc, cpu, aarch64_bti, uint64_t, 0);
>
> - /* Setup memory tagging support if the HW and kernel support it, and if
> - the user has requested it. */
> - cpu_features->mte_state = 0;
> -
> -#ifdef USE_MTAG
> - int mte_state = TUNABLE_GET (glibc, mem, tagging, unsigned, 0);
> - cpu_features->mte_state = (GLRO (dl_hwcap2) & HWCAP2_MTE) ? mte_state : 0;
> - /* If we lack the MTE feature, disable the tunable, since it will
> - otherwise cause instructions that won't run on this CPU to be used. */
> - TUNABLE_SET (glibc, mem, tagging, cpu_features->mte_state);
> -
> - if (cpu_features->mte_state & 4)
> - /* Enable choosing system-preferred faulting mode. */
> - __prctl (PR_SET_TAGGED_ADDR_CTRL,
> - (PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC
> - | MTE_ALLOWED_TAGS),
> - 0, 0, 0);
> - else if (cpu_features->mte_state & 2)
> - __prctl (PR_SET_TAGGED_ADDR_CTRL,
> - (PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC | MTE_ALLOWED_TAGS),
> - 0, 0, 0);
> - else if (cpu_features->mte_state)
> - __prctl (PR_SET_TAGGED_ADDR_CTRL,
> - (PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_ASYNC | MTE_ALLOWED_TAGS),
> - 0, 0, 0);
> -#endif
> -
> /* Check if SVE is supported. */
> cpu_features->sve = GLRO (dl_hwcap) & HWCAP_SVE;
>
More information about the Libc-alpha
mailing list