mm: switch the test_vmalloc module to use __vmalloc_node
[linux-2.6-microblaze.git] / mm / vmalloc.c
index 9a8227a..9311066 100644 (file)
@@ -128,10 +128,24 @@ static void vunmap_p4d_range(pgd_t *pgd, unsigned long addr, unsigned long end)
        } while (p4d++, addr = next, addr != end);
 }
 
-static void vunmap_page_range(unsigned long addr, unsigned long end)
+/**
+ * unmap_kernel_range_noflush - unmap kernel VM area
+ * @addr: start of the VM area to unmap
+ * @size: size of the VM area to unmap
+ *
+ * Unmap PFN_UP(@size) pages at @addr.  The VM area @addr and @size specify
+ * should have been allocated using get_vm_area() and its friends.
+ *
+ * NOTE:
+ * This function does NOT do any cache flushing.  The caller is responsible
+ * for calling flush_cache_vunmap() on to-be-mapped areas before calling this
+ * function and flush_tlb_kernel_range() after.
+ */
+void unmap_kernel_range_noflush(unsigned long addr, unsigned long size)
 {
-       pgd_t *pgd;
+       unsigned long end = addr + size;
        unsigned long next;
+       pgd_t *pgd;
 
        BUG_ON(addr >= end);
        pgd = pgd_offset_k(addr);
@@ -220,18 +234,30 @@ static int vmap_p4d_range(pgd_t *pgd, unsigned long addr,
        return 0;
 }
 
-/*
- * Set up page tables in kva (addr, end). The ptes shall have prot "prot", and
- * will have pfns corresponding to the "pages" array.
+/**
+ * map_kernel_range_noflush - map kernel VM area with the specified pages
+ * @addr: start of the VM area to map
+ * @size: size of the VM area to map
+ * @prot: page protection flags to use
+ * @pages: pages to map
+ *
+ * Map PFN_UP(@size) pages at @addr.  The VM area @addr and @size specify should
+ * have been allocated using get_vm_area() and its friends.
  *
- * Ie. pte at addr+N*PAGE_SIZE shall point to pfn corresponding to pages[N]
+ * NOTE:
+ * This function does NOT do any cache flushing.  The caller is responsible for
+ * calling flush_cache_vmap() on to-be-mapped areas before calling this
+ * function.
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
  */
-static int vmap_page_range_noflush(unsigned long start, unsigned long end,
-                                  pgprot_t prot, struct page **pages)
+int map_kernel_range_noflush(unsigned long addr, unsigned long size,
+                            pgprot_t prot, struct page **pages)
 {
-       pgd_t *pgd;
+       unsigned long end = addr + size;
        unsigned long next;
-       unsigned long addr = start;
+       pgd_t *pgd;
        int err = 0;
        int nr = 0;
 
@@ -244,16 +270,16 @@ static int vmap_page_range_noflush(unsigned long start, unsigned long end,
                        return err;
        } while (pgd++, addr = next, addr != end);
 
-       return nr;
+       return 0;
 }
 
-static int vmap_page_range(unsigned long start, unsigned long end,
-                          pgprot_t prot, struct page **pages)
+int map_kernel_range(unsigned long start, unsigned long size, pgprot_t prot,
+               struct page **pages)
 {
        int ret;
 
-       ret = vmap_page_range_noflush(start, end, prot, pages);
-       flush_cache_vmap(start, end);
+       ret = map_kernel_range_noflush(start, size, prot, pages);
+       flush_cache_vmap(start, start + size);
        return ret;
 }
 
@@ -1222,14 +1248,6 @@ int unregister_vmap_purge_notifier(struct notifier_block *nb)
 }
 EXPORT_SYMBOL_GPL(unregister_vmap_purge_notifier);
 
-/*
- * Clear the pagetable entries of a given vmap_area
- */
-static void unmap_vmap_area(struct vmap_area *va)
-{
-       vunmap_page_range(va->va_start, va->va_end);
-}
-
 /*
  * lazy_max_pages is the maximum amount of virtual address space we gather up
  * before attempting to purge with a TLB flush.
@@ -1391,7 +1409,7 @@ static void free_vmap_area_noflush(struct vmap_area *va)
 static void free_unmap_vmap_area(struct vmap_area *va)
 {
        flush_cache_vunmap(va->va_start, va->va_end);
-       unmap_vmap_area(va);
+       unmap_kernel_range_noflush(va->va_start, va->va_end - va->va_start);
        if (debug_pagealloc_enabled_static())
                flush_tlb_kernel_range(va->va_start, va->va_end);
 
@@ -1665,7 +1683,7 @@ static void *vb_alloc(unsigned long size, gfp_t gfp_mask)
        return vaddr;
 }
 
-static void vb_free(const void *addr, unsigned long size)
+static void vb_free(unsigned long addr, unsigned long size)
 {
        unsigned long offset;
        unsigned long vb_idx;
@@ -1675,24 +1693,22 @@ static void vb_free(const void *addr, unsigned long size)
        BUG_ON(offset_in_page(size));
        BUG_ON(size > PAGE_SIZE*VMAP_MAX_ALLOC);
 
-       flush_cache_vunmap((unsigned long)addr, (unsigned long)addr + size);
+       flush_cache_vunmap(addr, addr + size);
 
        order = get_order(size);
 
-       offset = (unsigned long)addr & (VMAP_BLOCK_SIZE - 1);
-       offset >>= PAGE_SHIFT;
+       offset = (addr & (VMAP_BLOCK_SIZE - 1)) >> PAGE_SHIFT;
 
-       vb_idx = addr_to_vb_idx((unsigned long)addr);
+       vb_idx = addr_to_vb_idx(addr);
        rcu_read_lock();
        vb = radix_tree_lookup(&vmap_block_tree, vb_idx);
        rcu_read_unlock();
        BUG_ON(!vb);
 
-       vunmap_page_range((unsigned long)addr, (unsigned long)addr + size);
+       unmap_kernel_range_noflush(addr, size);
 
        if (debug_pagealloc_enabled_static())
-               flush_tlb_kernel_range((unsigned long)addr,
-                                       (unsigned long)addr + size);
+               flush_tlb_kernel_range(addr, addr + size);
 
        spin_lock(&vb->lock);
 
@@ -1792,7 +1808,7 @@ void vm_unmap_ram(const void *mem, unsigned int count)
 
        if (likely(count <= VMAP_MAX_ALLOC)) {
                debug_check_no_locks_freed(mem, size);
-               vb_free(mem, size);
+               vb_free(addr, size);
                return;
        }
 
@@ -1819,7 +1835,7 @@ EXPORT_SYMBOL(vm_unmap_ram);
  *
  * Returns: a pointer to the address that has been mapped, or %NULL on failure
  */
-void *vm_map_ram(struct page **pages, unsigned int count, int node, pgprot_t prot)
+void *vm_map_ram(struct page **pages, unsigned int count, int node)
 {
        unsigned long size = (unsigned long)count << PAGE_SHIFT;
        unsigned long addr;
@@ -1843,7 +1859,7 @@ void *vm_map_ram(struct page **pages, unsigned int count, int node, pgprot_t pro
 
        kasan_unpoison_vmalloc(mem, size);
 
-       if (vmap_page_range(addr, addr + size, prot, pages) < 0) {
+       if (map_kernel_range(addr, size, PAGE_KERNEL, pages) < 0) {
                vm_unmap_ram(mem, count);
                return NULL;
        }
@@ -1987,51 +2003,6 @@ void __init vmalloc_init(void)
        vmap_initialized = true;
 }
 
-/**
- * map_kernel_range_noflush - map kernel VM area with the specified pages
- * @addr: start of the VM area to map
- * @size: size of the VM area to map
- * @prot: page protection flags to use
- * @pages: pages to map
- *
- * Map PFN_UP(@size) pages at @addr.  The VM area @addr and @size
- * specify should have been allocated using get_vm_area() and its
- * friends.
- *
- * NOTE:
- * This function does NOT do any cache flushing.  The caller is
- * responsible for calling flush_cache_vmap() on to-be-mapped areas
- * before calling this function.
- *
- * RETURNS:
- * The number of pages mapped on success, -errno on failure.
- */
-int map_kernel_range_noflush(unsigned long addr, unsigned long size,
-                            pgprot_t prot, struct page **pages)
-{
-       return vmap_page_range_noflush(addr, addr + size, prot, pages);
-}
-
-/**
- * unmap_kernel_range_noflush - unmap kernel VM area
- * @addr: start of the VM area to unmap
- * @size: size of the VM area to unmap
- *
- * Unmap PFN_UP(@size) pages at @addr.  The VM area @addr and @size
- * specify should have been allocated using get_vm_area() and its
- * friends.
- *
- * NOTE:
- * This function does NOT do any cache flushing.  The caller is
- * responsible for calling flush_cache_vunmap() on to-be-mapped areas
- * before calling this function and flush_tlb_kernel_range() after.
- */
-void unmap_kernel_range_noflush(unsigned long addr, unsigned long size)
-{
-       vunmap_page_range(addr, addr + size);
-}
-EXPORT_SYMBOL_GPL(unmap_kernel_range_noflush);
-
 /**
  * unmap_kernel_range - unmap kernel VM area and flush cache and TLB
  * @addr: start of the VM area to unmap
@@ -2045,22 +2016,9 @@ void unmap_kernel_range(unsigned long addr, unsigned long size)
        unsigned long end = addr + size;
 
        flush_cache_vunmap(addr, end);
-       vunmap_page_range(addr, end);
+       unmap_kernel_range_noflush(addr, size);
        flush_tlb_kernel_range(addr, end);
 }
-EXPORT_SYMBOL_GPL(unmap_kernel_range);
-
-int map_vm_area(struct vm_struct *area, pgprot_t prot, struct page **pages)
-{
-       unsigned long addr = (unsigned long)area->addr;
-       unsigned long end = addr + get_vm_area_size(area);
-       int err;
-
-       err = vmap_page_range(addr, end, prot, pages);
-
-       return err > 0 ? 0 : err;
-}
-EXPORT_SYMBOL_GPL(map_vm_area);
 
 static inline void setup_vmalloc_vm_locked(struct vm_struct *vm,
        struct vmap_area *va, unsigned long flags, const void *caller)
@@ -2128,14 +2086,6 @@ static struct vm_struct *__get_vm_area_node(unsigned long size,
        return area;
 }
 
-struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
-                               unsigned long start, unsigned long end)
-{
-       return __get_vm_area_node(size, 1, flags, start, end, NUMA_NO_NODE,
-                                 GFP_KERNEL, __builtin_return_address(0));
-}
-EXPORT_SYMBOL_GPL(__get_vm_area);
-
 struct vm_struct *__get_vm_area_caller(unsigned long size, unsigned long flags,
                                       unsigned long start, unsigned long end,
                                       const void *caller)
@@ -2441,7 +2391,8 @@ void *vmap(struct page **pages, unsigned int count,
        if (!area)
                return NULL;
 
-       if (map_vm_area(area, prot, pages)) {
+       if (map_kernel_range((unsigned long)area->addr, size, pgprot_nx(prot),
+                       pages) < 0) {
                vunmap(area->addr);
                return NULL;
        }
@@ -2450,9 +2401,6 @@ void *vmap(struct page **pages, unsigned int count,
 }
 EXPORT_SYMBOL(vmap);
 
-static void *__vmalloc_node(unsigned long size, unsigned long align,
-                           gfp_t gfp_mask, pgprot_t prot,
-                           int node, const void *caller);
 static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
                                 pgprot_t prot, int node)
 {
@@ -2470,7 +2418,7 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
        /* Please note that the recursion is strictly bounded. */
        if (array_size > PAGE_SIZE) {
                pages = __vmalloc_node(array_size, 1, nested_gfp|highmem_mask,
-                               PAGE_KERNEL, node, area->caller);
+                               node, area->caller);
        } else {
                pages = kmalloc_node(array_size, nested_gfp, node);
        }
@@ -2504,8 +2452,10 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
        }
        atomic_long_add(area->nr_pages, &nr_vmalloc_pages);
 
-       if (map_vm_area(area, prot, pages))
+       if (map_kernel_range((unsigned long)area->addr, get_vm_area_size(area),
+                       prot, pages) < 0)
                goto fail;
+
        return area->addr;
 
 fail:
@@ -2573,27 +2523,16 @@ fail:
        return NULL;
 }
 
-/*
- * This is only for performance analysis of vmalloc and stress purpose.
- * It is required by vmalloc test module, therefore do not use it other
- * than that.
- */
-#ifdef CONFIG_TEST_VMALLOC_MODULE
-EXPORT_SYMBOL_GPL(__vmalloc_node_range);
-#endif
-
 /**
  * __vmalloc_node - allocate virtually contiguous memory
  * @size:          allocation size
  * @align:         desired alignment
  * @gfp_mask:      flags for the page level allocator
- * @prot:          protection mask for the allocated pages
  * @node:          node to use for allocation or NUMA_NO_NODE
  * @caller:        caller's return address
  *
- * Allocate enough pages to cover @size from the page level
- * allocator with @gfp_mask flags.  Map them into contiguous
- * kernel virtual space, using a pagetable protection of @prot.
+ * Allocate enough pages to cover @size from the page level allocator with
+ * @gfp_mask flags.  Map them into contiguous kernel virtual space.
  *
  * Reclaim modifiers in @gfp_mask - __GFP_NORETRY, __GFP_RETRY_MAYFAIL
  * and __GFP_NOFAIL are not supported
@@ -2603,35 +2542,28 @@ EXPORT_SYMBOL_GPL(__vmalloc_node_range);
  *
  * Return: pointer to the allocated memory or %NULL on error
  */
-static void *__vmalloc_node(unsigned long size, unsigned long align,
-                           gfp_t gfp_mask, pgprot_t prot,
-                           int node, const void *caller)
+void *__vmalloc_node(unsigned long size, unsigned long align,
+                           gfp_t gfp_mask, int node, const void *caller)
 {
        return __vmalloc_node_range(size, align, VMALLOC_START, VMALLOC_END,
-                               gfp_mask, prot, 0, node, caller);
+                               gfp_mask, PAGE_KERNEL, 0, node, caller);
 }
+/*
+ * This is only for performance analysis of vmalloc and stress purpose.
+ * It is required by vmalloc test module, therefore do not use it other
+ * than that.
+ */
+#ifdef CONFIG_TEST_VMALLOC_MODULE
+EXPORT_SYMBOL_GPL(__vmalloc_node);
+#endif
 
-void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot)
+void *__vmalloc(unsigned long size, gfp_t gfp_mask)
 {
-       return __vmalloc_node(size, 1, gfp_mask, prot, NUMA_NO_NODE,
+       return __vmalloc_node(size, 1, gfp_mask, NUMA_NO_NODE,
                                __builtin_return_address(0));
 }
 EXPORT_SYMBOL(__vmalloc);
 
-static inline void *__vmalloc_node_flags(unsigned long size,
-                                       int node, gfp_t flags)
-{
-       return __vmalloc_node(size, 1, flags, PAGE_KERNEL,
-                                       node, __builtin_return_address(0));
-}
-
-
-void *__vmalloc_node_flags_caller(unsigned long size, int node, gfp_t flags,
-                                 void *caller)
-{
-       return __vmalloc_node(size, 1, flags, PAGE_KERNEL, node, caller);
-}
-
 /**
  * vmalloc - allocate virtually contiguous memory
  * @size:    allocation size
@@ -2646,8 +2578,8 @@ void *__vmalloc_node_flags_caller(unsigned long size, int node, gfp_t flags,
  */
 void *vmalloc(unsigned long size)
 {
-       return __vmalloc_node_flags(size, NUMA_NO_NODE,
-                                   GFP_KERNEL);
+       return __vmalloc_node(size, 1, GFP_KERNEL, NUMA_NO_NODE,
+                               __builtin_return_address(0));
 }
 EXPORT_SYMBOL(vmalloc);
 
@@ -2666,8 +2598,8 @@ EXPORT_SYMBOL(vmalloc);
  */
 void *vzalloc(unsigned long size)
 {
-       return __vmalloc_node_flags(size, NUMA_NO_NODE,
-                               GFP_KERNEL | __GFP_ZERO);
+       return __vmalloc_node(size, 1, GFP_KERNEL | __GFP_ZERO, NUMA_NO_NODE,
+                               __builtin_return_address(0));
 }
 EXPORT_SYMBOL(vzalloc);
 
@@ -2704,8 +2636,8 @@ EXPORT_SYMBOL(vmalloc_user);
  */
 void *vmalloc_node(unsigned long size, int node)
 {
-       return __vmalloc_node(size, 1, GFP_KERNEL, PAGE_KERNEL,
-                                       node, __builtin_return_address(0));
+       return __vmalloc_node(size, 1, GFP_KERNEL, node,
+                       __builtin_return_address(0));
 }
 EXPORT_SYMBOL(vmalloc_node);
 
@@ -2718,15 +2650,12 @@ EXPORT_SYMBOL(vmalloc_node);
  * allocator and map them into contiguous kernel virtual space.
  * The memory allocated is set to zero.
  *
- * For tight control over page level allocator and protection flags
- * use __vmalloc_node() instead.
- *
  * Return: pointer to the allocated memory or %NULL on error
  */
 void *vzalloc_node(unsigned long size, int node)
 {
-       return __vmalloc_node_flags(size, node,
-                        GFP_KERNEL | __GFP_ZERO);
+       return __vmalloc_node(size, 1, GFP_KERNEL | __GFP_ZERO, node,
+                               __builtin_return_address(0));
 }
 EXPORT_SYMBOL(vzalloc_node);
 
@@ -2793,8 +2722,8 @@ void *vmalloc_exec(unsigned long size)
  */
 void *vmalloc_32(unsigned long size)
 {
-       return __vmalloc_node(size, 1, GFP_VMALLOC32, PAGE_KERNEL,
-                             NUMA_NO_NODE, __builtin_return_address(0));
+       return __vmalloc_node(size, 1, GFP_VMALLOC32, NUMA_NO_NODE,
+                       __builtin_return_address(0));
 }
 EXPORT_SYMBOL(vmalloc_32);