staging: xillybus: Fixes related to "rc" variable
[firefly-linux-kernel-4.4.55.git] / mm / vmalloc.c
index bf233b283319cea03fcf76f2d81dce5b9933d536..2b0aa5486092dca2745c2ec201cda44db033550c 100644 (file)
@@ -1268,20 +1268,17 @@ void unmap_kernel_range(unsigned long addr, unsigned long size)
        vunmap_page_range(addr, end);
        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)
+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);
-       if (err > 0) {
-               *pages += err;
-               err = 0;
-       }
+       err = vmap_page_range(addr, end, prot, pages);
 
-       return err;
+       return err > 0 ? 0 : err;
 }
 EXPORT_SYMBOL_GPL(map_vm_area);
 
@@ -1496,7 +1493,7 @@ void vfree(const void *addr)
        if (!addr)
                return;
        if (unlikely(in_interrupt())) {
-               struct vfree_deferred *p = &__get_cpu_var(vfree_deferred);
+               struct vfree_deferred *p = this_cpu_ptr(&vfree_deferred);
                if (llist_add((struct llist_node *)addr, &p->list))
                        schedule_work(&p->wq);
        } else
@@ -1547,7 +1544,7 @@ void *vmap(struct page **pages, unsigned int count,
        if (!area)
                return NULL;
 
-       if (map_vm_area(area, prot, &pages)) {
+       if (map_vm_area(area, prot, pages)) {
                vunmap(area->addr);
                return NULL;
        }
@@ -1565,7 +1562,8 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
        const int order = 0;
        struct page **pages;
        unsigned int nr_pages, array_size, i;
-       gfp_t nested_gfp = (gfp_mask & GFP_RECLAIM_MASK) | __GFP_ZERO;
+       const gfp_t nested_gfp = (gfp_mask & GFP_RECLAIM_MASK) | __GFP_ZERO;
+       const gfp_t alloc_mask = gfp_mask | __GFP_NOWARN;
 
        nr_pages = get_vm_area_size(area) >> PAGE_SHIFT;
        array_size = (nr_pages * sizeof(struct page *));
@@ -1588,12 +1586,11 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
 
        for (i = 0; i < area->nr_pages; i++) {
                struct page *page;
-               gfp_t tmp_mask = gfp_mask | __GFP_NOWARN;
 
                if (node == NUMA_NO_NODE)
-                       page = alloc_page(tmp_mask);
+                       page = alloc_page(alloc_mask);
                else
-                       page = alloc_pages_node(node, tmp_mask, order);
+                       page = alloc_pages_node(node, alloc_mask, order);
 
                if (unlikely(!page)) {
                        /* Successfully allocated i pages, free them in __vunmap() */
@@ -1601,9 +1598,11 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
                        goto fail;
                }
                area->pages[i] = page;
+               if (gfp_mask & __GFP_WAIT)
+                       cond_resched();
        }
 
-       if (map_vm_area(area, prot, &pages))
+       if (map_vm_area(area, prot, pages))
                goto fail;
        return area->addr;
 
@@ -2619,19 +2618,19 @@ static int s_show(struct seq_file *m, void *p)
                seq_printf(m, " phys=%llx", (unsigned long long)v->phys_addr);
 
        if (v->flags & VM_IOREMAP)
-               seq_printf(m, " ioremap");
+               seq_puts(m, " ioremap");
 
        if (v->flags & VM_ALLOC)
-               seq_printf(m, " vmalloc");
+               seq_puts(m, " vmalloc");
 
        if (v->flags & VM_MAP)
-               seq_printf(m, " vmap");
+               seq_puts(m, " vmap");
 
        if (v->flags & VM_USERMAP)
-               seq_printf(m, " user");
+               seq_puts(m, " user");
 
        if (v->flags & VM_VPAGES)
-               seq_printf(m, " vpages");
+               seq_puts(m, " vpages");
 
        show_numa_info(m, v);
        seq_putc(m, '\n');
@@ -2689,14 +2688,14 @@ void get_vmalloc_info(struct vmalloc_info *vmi)
 
        prev_end = VMALLOC_START;
 
-       spin_lock(&vmap_area_lock);
+       rcu_read_lock();
 
        if (list_empty(&vmap_area_list)) {
                vmi->largest_chunk = VMALLOC_TOTAL;
                goto out;
        }
 
-       list_for_each_entry(va, &vmap_area_list, list) {
+       list_for_each_entry_rcu(va, &vmap_area_list, list) {
                unsigned long addr = va->va_start;
 
                /*
@@ -2723,7 +2722,7 @@ void get_vmalloc_info(struct vmalloc_info *vmi)
                vmi->largest_chunk = VMALLOC_END - prev_end;
 
 out:
-       spin_unlock(&vmap_area_lock);
+       rcu_read_unlock();
 }
 #endif