Date: Mon, 29 Jun 2026 20:33:30 +0000 From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 559f45638dfa - main - rtld: add spinlock around the crt malloc calls Message-ID: <6a42d69a.302c4.56f9007@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=559f45638dfa50195c591bb0f7f3d3d8f3bb8dc0 commit 559f45638dfa50195c591bb0f7f3d3d8f3bb8dc0 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2026-06-27 18:50:29 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2026-06-29 20:33:12 +0000 rtld: add spinlock around the crt malloc calls Right now, the rtld malloc is called under the write-locked rtld bind lock. A future change adds places where only read-locked rtld bind lock is held, and then the spinlock protects the malloc structures from the parallel updates. Reviewed by: kevans Tested by: Marek Zarychta <zarychtam@plan-b.pwste.edu.pl> Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D57908 --- libexec/rtld-elf/rtld.c | 25 ---------------- libexec/rtld-elf/xmalloc.c | 72 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 71 insertions(+), 26 deletions(-) diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 2a05afe66902..938e4b0b8a6b 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -6878,31 +6878,6 @@ getenv(const char *name) strlen(name)))); } -/* malloc */ -void * -malloc(size_t nbytes) -{ - return (__crt_malloc(nbytes)); -} - -void * -calloc(size_t num, size_t size) -{ - return (__crt_calloc(num, size)); -} - -void -free(void *cp) -{ - __crt_free(cp); -} - -void * -realloc(void *cp, size_t nbytes) -{ - return (__crt_realloc(cp, nbytes)); -} - extern int _rtld_version__FreeBSD_version __exported; int _rtld_version__FreeBSD_version = __FreeBSD_version; diff --git a/libexec/rtld-elf/xmalloc.c b/libexec/rtld-elf/xmalloc.c index 5f7c1b5ba10a..4c67939fc27f 100644 --- a/libexec/rtld-elf/xmalloc.c +++ b/libexec/rtld-elf/xmalloc.c @@ -26,6 +26,8 @@ */ #include <sys/param.h> +#include <machine/cpu.h> +#include <machine/cpufunc.h> #include <stddef.h> #include <stdlib.h> #include <string.h> @@ -35,12 +37,36 @@ #include "rtld_malloc.h" #include "rtld_libc.h" +static int rtld_malloc_spinlock; + +/* + * Almost always the rtld malloc is called under the write-locked rtld + * bind lock. Due to this, xlock() would need a single CAS to take + * the spinlock. But some places only own read-locked rtld bind lock, + * and then the spinlock protects the malloc structures from the + * parallel updates. + */ +static void +xlock(void) +{ + while (atomic_cmpset_acq_int(&rtld_malloc_spinlock, 0, 1) == 0) + cpu_spinwait(); +} + +static void +xunlock(void) +{ + atomic_store_rel_int(&rtld_malloc_spinlock, 0); +} + void * xcalloc(size_t number, size_t size) { void *p; + xlock(); p = __crt_calloc(number, size); + xunlock(); if (p == NULL) { rtld_fdputstr(STDERR_FILENO, "Out of memory\n"); _exit(1); @@ -51,10 +77,11 @@ xcalloc(size_t number, size_t size) void * xmalloc(size_t size) { - void *p; + xlock(); p = __crt_malloc(size); + xunlock(); if (p == NULL) { rtld_fdputstr(STDERR_FILENO, "Out of memory\n"); _exit(1); @@ -83,10 +110,53 @@ xmalloc_aligned(size_t size, size_t align, size_t offset) if (align < sizeof(void *)) align = sizeof(void *); + xlock(); res = __crt_aligned_alloc_offset(align, size, offset); + xunlock(); if (res == NULL) { rtld_fdputstr(STDERR_FILENO, "Out of memory\n"); _exit(1); } return (res); } + +void * +malloc(size_t size) +{ + void *p; + + xlock(); + p = __crt_malloc(size); + xunlock(); + return (p); +} + +void * +calloc(size_t num, size_t size) +{ + void *p; + + xlock(); + p = __crt_calloc(num, size); + xunlock(); + return (p); +} + +void +free(void *cp) +{ + xlock(); + __crt_free(cp); + xunlock(); +} + +void * +realloc(void *cp, size_t nbytes) +{ + void *p; + + xlock(); + p = __crt_realloc(cp, nbytes); + xunlock(); + return (p); +}home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a42d69a.302c4.56f9007>
