39 lines · c
1// SPDX-License-Identifier: GPL-2.02 3#include <linux/log2.h>4#include <linux/slab.h>5#include <linux/vmalloc.h>6#include "darray.h"7 8int __bch2_darray_resize_noprof(darray_char *d, size_t element_size, size_t new_size, gfp_t gfp)9{10 if (new_size > d->size) {11 new_size = roundup_pow_of_two(new_size);12 13 /*14 * This is a workaround: kvmalloc() doesn't support > INT_MAX15 * allocations, but vmalloc() does.16 * The limit needs to be lifted from kvmalloc, and when it does17 * we'll go back to just using that.18 */19 size_t bytes;20 if (unlikely(check_mul_overflow(new_size, element_size, &bytes)))21 return -ENOMEM;22 23 void *data = likely(bytes < INT_MAX)24 ? kvmalloc_noprof(bytes, gfp)25 : vmalloc_noprof(bytes);26 if (!data)27 return -ENOMEM;28 29 if (d->size)30 memcpy(data, d->data, d->size * element_size);31 if (d->data != d->preallocated)32 kvfree(d->data);33 d->data = data;34 d->size = new_size;35 }36 37 return 0;38}39