aboutsummaryrefslogtreecommitdiffstats
path: root/mm/percpu-vm.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/percpu-vm.c')
-rw-r--r--mm/percpu-vm.c27
1 files changed, 9 insertions, 18 deletions
diff --git a/mm/percpu-vm.c b/mm/percpu-vm.c
index 0539f6a..bfad724 100644
--- a/mm/percpu-vm.c
+++ b/mm/percpu-vm.c
@@ -50,13 +50,14 @@ static struct page **pcpu_get_pages_and_bitmap(struct pcpu_chunk *chunk,
if (!pages || !bitmap) {
if (may_alloc && !pages)
- pages = pcpu_mem_zalloc(pages_size);
+ pages = pcpu_mem_alloc(pages_size);
if (may_alloc && !bitmap)
- bitmap = pcpu_mem_zalloc(bitmap_size);
+ bitmap = pcpu_mem_alloc(bitmap_size);
if (!pages || !bitmap)
return NULL;
}
+ memset(pages, 0, pages_size);
bitmap_copy(bitmap, chunk->populated, pcpu_unit_pages);
*bitmapp = bitmap;
@@ -108,7 +109,7 @@ static int pcpu_alloc_pages(struct pcpu_chunk *chunk,
int page_start, int page_end)
{
const gfp_t gfp = GFP_KERNEL | __GFP_HIGHMEM | __GFP_COLD;
- unsigned int cpu, tcpu;
+ unsigned int cpu;
int i;
for_each_possible_cpu(cpu) {
@@ -116,23 +117,14 @@ static int pcpu_alloc_pages(struct pcpu_chunk *chunk,
struct page **pagep = &pages[pcpu_page_idx(cpu, i)];
*pagep = alloc_pages_node(cpu_to_node(cpu), gfp, 0);
- if (!*pagep)
- goto err;
+ if (!*pagep) {
+ pcpu_free_pages(chunk, pages, populated,
+ page_start, page_end);
+ return -ENOMEM;
+ }
}
}
return 0;
-
-err:
- while (--i >= page_start)
- __free_page(pages[pcpu_page_idx(cpu, i)]);
-
- for_each_possible_cpu(tcpu) {
- if (tcpu == cpu)
- break;
- for (i = page_start; i < page_end; i++)
- __free_page(pages[pcpu_page_idx(tcpu, i)]);
- }
- return -ENOMEM;
}
/**
@@ -273,7 +265,6 @@ err:
__pcpu_unmap_pages(pcpu_chunk_addr(chunk, tcpu, page_start),
page_end - page_start);
}
- pcpu_post_unmap_tlb_flush(chunk, page_start, page_end);
return err;
}