git: 516eb937b274 - stable/14 - LinuxKPI: implement krealloc() for memory being contiguous
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 18 Apr 2025 14:36:55 UTC
The branch stable/14 has been updated by bz: URL: https://cgit.FreeBSD.org/src/commit/?id=516eb937b274c34793f9b640e547eee0dc185b2d commit 516eb937b274c34793f9b640e547eee0dc185b2d Author: Bjoern A. Zeeb <bz@FreeBSD.org> AuthorDate: 2025-03-29 17:05:58 +0000 Commit: Bjoern A. Zeeb <bz@FreeBSD.org> CommitDate: 2025-04-18 14:35:58 +0000 LinuxKPI: implement krealloc() for memory being contiguous Implement krealloc_array() using krealloc(). Implement krealloc() doing the various size checks ourselves and use realloc() or kmalloc() depending on old and new allocation sizes. This way we can ensure that allocated memory stays physically contiguous. Sponsored by: The FreeBSD Foundation Suggested by: jhb (see D46657) Reviewed by: jhb, markj Differential Revision: https://reviews.freebsd.org/D49571 (cherry picked from commit 1c95d401ebe5075ebb38b57638830713a496f107) --- sys/compat/linuxkpi/common/include/linux/slab.h | 31 +++++++++++----------- sys/compat/linuxkpi/common/src/linux_slab.c | 35 +++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 15 deletions(-) diff --git a/sys/compat/linuxkpi/common/include/linux/slab.h b/sys/compat/linuxkpi/common/include/linux/slab.h index ddaabcef0b9c..a692ccb8b944 100644 --- a/sys/compat/linuxkpi/common/include/linux/slab.h +++ b/sys/compat/linuxkpi/common/include/linux/slab.h @@ -94,6 +94,7 @@ extern void *lkpi_kmalloc(size_t size, gfp_t flags); void *lkpi___kmalloc(size_t size, gfp_t flags); void *lkpi___kmalloc_node(size_t size, gfp_t flags, int node); #define __kmalloc(_s, _f) lkpi___kmalloc(_s, _f) +void *lkpi_krealloc(void *, size_t, gfp_t); static inline gfp_t linux_check_m_flags(gfp_t flags) @@ -148,6 +149,21 @@ kcalloc_node(size_t n, size_t size, gfp_t flags, int node) return (kmalloc_array_node(n, size, flags, node)); } +static inline void * +krealloc(void *ptr, size_t size, gfp_t flags) +{ + return (lkpi_krealloc(ptr, size, flags)); +} + +static inline void * +krealloc_array(void *ptr, size_t n, size_t size, gfp_t flags) +{ + if (WOULD_OVERFLOW(n, size)) + return NULL; + + return (krealloc(ptr, n * size, flags)); +} + static inline void * __vmalloc(size_t size, gfp_t flags, int other) { @@ -183,21 +199,6 @@ kvmalloc_array(size_t n, size_t size, gfp_t flags) return (kvmalloc(size * n, flags)); } -static inline void * -krealloc(void *ptr, size_t size, gfp_t flags) -{ - return (realloc(ptr, size, M_KMALLOC, linux_check_m_flags(flags))); -} - -static inline void * -krealloc_array(void *ptr, size_t n, size_t size, gfp_t flags) -{ - if (WOULD_OVERFLOW(n, size)) - return NULL; - - return (realloc(ptr, n * size, M_KMALLOC, linux_check_m_flags(flags))); -} - extern void linux_kfree_async(void *); static inline void diff --git a/sys/compat/linuxkpi/common/src/linux_slab.c b/sys/compat/linuxkpi/common/src/linux_slab.c index 4b0b18178a5c..abcffdb094f5 100644 --- a/sys/compat/linuxkpi/common/src/linux_slab.c +++ b/sys/compat/linuxkpi/common/src/linux_slab.c @@ -234,6 +234,41 @@ lkpi___kmalloc(size_t size, gfp_t flags) 0, -1UL, PAGE_SIZE, 0)); } +void * +lkpi_krealloc(void *ptr, size_t size, gfp_t flags) +{ + void *nptr; + size_t osize; + + /* + * First handle invariants based on function arguments. + */ + if (ptr == NULL) + return (kmalloc(size, flags)); + + osize = ksize(ptr); + if (size <= osize) + return (ptr); + + /* + * We know the new size > original size. realloc(9) does not (and cannot) + * know about our requirements for physically contiguous memory, so we can + * only call it for sizes up to and including PAGE_SIZE, and otherwise have + * to replicate its functionality using kmalloc to get the contigmalloc(9) + * backing. + */ + if (size <= PAGE_SIZE) + return (realloc(ptr, size, M_KMALLOC, linux_check_m_flags(flags))); + + nptr = kmalloc(size, flags); + if (nptr == NULL) + return (NULL); + + memcpy(nptr, ptr, osize); + kfree(ptr); + return (nptr); +} + struct lkpi_kmalloc_ctx { size_t size; gfp_t flags;