diff options
Diffstat (limited to 'mm/util.c')
| -rw-r--r-- | mm/util.c | 55 | 
1 files changed, 45 insertions, 10 deletions
diff --git a/mm/util.c b/mm/util.c index 8f18683825bc..9341ca77bd88 100644 --- a/mm/util.c +++ b/mm/util.c @@ -1,7 +1,9 @@ +#include <linux/mm.h>  #include <linux/slab.h>  #include <linux/string.h>  #include <linux/module.h>  #include <linux/err.h> +#include <linux/sched.h>  #include <asm/uaccess.h>  /** @@ -68,25 +70,22 @@ void *kmemdup(const void *src, size_t len, gfp_t gfp)  EXPORT_SYMBOL(kmemdup);  /** - * krealloc - reallocate memory. The contents will remain unchanged. + * __krealloc - like krealloc() but don't free @p.   * @p: object to reallocate memory for.   * @new_size: how many bytes of memory are required.   * @flags: the type of memory to allocate.   * - * The contents of the object pointed to are preserved up to the - * lesser of the new and old sizes.  If @p is %NULL, krealloc() - * behaves exactly like kmalloc().  If @size is 0 and @p is not a - * %NULL pointer, the object pointed to is freed. + * This function is like krealloc() except it never frees the originally + * allocated buffer. Use this if you don't want to free the buffer immediately + * like, for example, with RCU.   */ -void *krealloc(const void *p, size_t new_size, gfp_t flags) +void *__krealloc(const void *p, size_t new_size, gfp_t flags)  {  	void *ret;  	size_t ks = 0; -	if (unlikely(!new_size)) { -		kfree(p); +	if (unlikely(!new_size))  		return ZERO_SIZE_PTR; -	}  	if (p)  		ks = ksize(p); @@ -95,10 +94,37 @@ void *krealloc(const void *p, size_t new_size, gfp_t flags)  		return (void *)p;  	ret = kmalloc_track_caller(new_size, flags); -	if (ret && p) { +	if (ret && p)  		memcpy(ret, p, ks); + +	return ret; +} +EXPORT_SYMBOL(__krealloc); + +/** + * krealloc - reallocate memory. The contents will remain unchanged. + * @p: object to reallocate memory for. + * @new_size: how many bytes of memory are required. + * @flags: the type of memory to allocate. + * + * The contents of the object pointed to are preserved up to the + * lesser of the new and old sizes.  If @p is %NULL, krealloc() + * behaves exactly like kmalloc().  If @size is 0 and @p is not a + * %NULL pointer, the object pointed to is freed. + */ +void *krealloc(const void *p, size_t new_size, gfp_t flags) +{ +	void *ret; + +	if (unlikely(!new_size)) {  		kfree(p); +		return ZERO_SIZE_PTR;  	} + +	ret = __krealloc(p, new_size, flags); +	if (ret && p != ret) +		kfree(p); +  	return ret;  }  EXPORT_SYMBOL(krealloc); @@ -136,3 +162,12 @@ char *strndup_user(const char __user *s, long n)  	return p;  }  EXPORT_SYMBOL(strndup_user); + +#ifndef HAVE_ARCH_PICK_MMAP_LAYOUT +void arch_pick_mmap_layout(struct mm_struct *mm) +{ +	mm->mmap_base = TASK_UNMAPPED_BASE; +	mm->get_unmapped_area = arch_get_unmapped_area; +	mm->unmap_area = arch_unmap_area; +} +#endif  |