diff options
Diffstat (limited to 'mm/percpu-vm.c')
-rw-r--r-- | mm/percpu-vm.c | 27 |
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; } |