X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=mm%2Futil.c;h=cb00b748ce47886446975d96466c2154f4d52fa3;hb=3bda12589646caa22b2ed4ef7cf82d17ea59d7a6;hp=bf340d80686884bf765dc696a73f7fd840842e8f;hpb=b981d8b3f5e008ff10d993be633ad00564fc22cd;p=linux-2.6 diff --git a/mm/util.c b/mm/util.c index bf340d8068..cb00b748ce 100644 --- a/mm/util.c +++ b/mm/util.c @@ -1,7 +1,9 @@ +#include #include #include #include #include +#include #include /** @@ -67,6 +69,38 @@ void *kmemdup(const void *src, size_t len, gfp_t gfp) } EXPORT_SYMBOL(kmemdup); +/** + * __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. + * + * 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 *ret; + size_t ks = 0; + + if (unlikely(!new_size)) + return ZERO_SIZE_PTR; + + if (p) + ks = ksize(p); + + if (ks >= new_size) + return (void *)p; + + ret = kmalloc_track_caller(new_size, flags); + 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. @@ -81,22 +115,16 @@ EXPORT_SYMBOL(kmemdup); void *krealloc(const void *p, size_t new_size, gfp_t flags) { void *ret; - size_t ks; if (unlikely(!new_size)) { kfree(p); return ZERO_SIZE_PTR; } - ks = ksize(p); - if (ks >= new_size) - return (void *)p; - - ret = kmalloc_track_caller(new_size, flags); - if (ret) { - memcpy(ret, p, min(new_size, ks)); + ret = __krealloc(p, new_size, flags); + if (ret && p != ret) kfree(p); - } + return ret; } EXPORT_SYMBOL(krealloc); @@ -134,3 +162,27 @@ 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 + +int __attribute__((weak)) get_user_pages_fast(unsigned long start, + int nr_pages, int write, struct page **pages) +{ + struct mm_struct *mm = current->mm; + int ret; + + down_read(&mm->mmap_sem); + ret = get_user_pages(current, mm, start, nr_pages, + write, 0, pages, NULL); + up_read(&mm->mmap_sem); + + return ret; +} +EXPORT_SYMBOL_GPL(get_user_pages_fast);