diff options
| author | Paolo Bonzini <pbonzini@redhat.com> | 2022-03-08 04:47:22 -0500 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2024-02-23 08:41:55 +0100 |
| commit | 95670878a612adaac74e97fc6f6a1d0aa8601de9 (patch) | |
| tree | 2462dc79690de3796a6b8ccc7b00ee2a26fc188b | |
| parent | 02f629bb460d01c81d3acb8d7e383dde65acbb0c (diff) | |
| download | linux-95670878a612adaac74e97fc6f6a1d0aa8601de9.tar.gz linux-95670878a612adaac74e97fc6f6a1d0aa8601de9.tar.bz2 linux-95670878a612adaac74e97fc6f6a1d0aa8601de9.zip | |
mm: vmalloc: introduce array allocation functions
commit a8749a35c39903120ec421ef2525acc8e0daa55c upstream.
Linux has dozens of occurrences of vmalloc(array_size()) and
vzalloc(array_size()). Allow to simplify the code by providing
vmalloc_array and vcalloc, as well as the underscored variants that let
the caller specify the GFP flags.
Acked-by: Michal Hocko <mhocko@suse.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Alexander Ofitserov <oficerovas@altlinux.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
| -rw-r--r-- | include/linux/vmalloc.h | 5 | ||||
| -rw-r--r-- | mm/util.c | 50 |
2 files changed, 55 insertions, 0 deletions
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index 76dad53a410a..0fd47f2f39eb 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -112,6 +112,11 @@ extern void *__vmalloc_node_range(unsigned long size, unsigned long align, void *__vmalloc_node(unsigned long size, unsigned long align, gfp_t gfp_mask, int node, const void *caller); +extern void *__vmalloc_array(size_t n, size_t size, gfp_t flags); +extern void *vmalloc_array(size_t n, size_t size); +extern void *__vcalloc(size_t n, size_t size, gfp_t flags); +extern void *vcalloc(size_t n, size_t size); + extern void vfree(const void *addr); extern void vfree_atomic(const void *addr); diff --git a/mm/util.c b/mm/util.c index 25bfda774f6f..7fd3c2bb3e4f 100644 --- a/mm/util.c +++ b/mm/util.c @@ -686,6 +686,56 @@ static inline void *__page_rmapping(struct page *page) return (void *)mapping; } +/** + * __vmalloc_array - allocate memory for a virtually contiguous array. + * @n: number of elements. + * @size: element size. + * @flags: the type of memory to allocate (see kmalloc). + */ +void *__vmalloc_array(size_t n, size_t size, gfp_t flags) +{ + size_t bytes; + + if (unlikely(check_mul_overflow(n, size, &bytes))) + return NULL; + return __vmalloc(bytes, flags); +} +EXPORT_SYMBOL(__vmalloc_array); + +/** + * vmalloc_array - allocate memory for a virtually contiguous array. + * @n: number of elements. + * @size: element size. + */ +void *vmalloc_array(size_t n, size_t size) +{ + return __vmalloc_array(n, size, GFP_KERNEL); +} +EXPORT_SYMBOL(vmalloc_array); + +/** + * __vcalloc - allocate and zero memory for a virtually contiguous array. + * @n: number of elements. + * @size: element size. + * @flags: the type of memory to allocate (see kmalloc). + */ +void *__vcalloc(size_t n, size_t size, gfp_t flags) +{ + return __vmalloc_array(n, size, flags | __GFP_ZERO); +} +EXPORT_SYMBOL(__vcalloc); + +/** + * vcalloc - allocate and zero memory for a virtually contiguous array. + * @n: number of elements. + * @size: element size. + */ +void *vcalloc(size_t n, size_t size) +{ + return __vmalloc_array(n, size, GFP_KERNEL | __GFP_ZERO); +} +EXPORT_SYMBOL(vcalloc); + /* Neutral page->mapping pointer to address_space or anon_vma or other */ void *page_rmapping(struct page *page) { |
