Commit 6a5c75ce authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-3.17-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu

Pull percpu fixes from Tejun Heo:
 "One patch to fix a failure path in the alloc path.  The bug is
  dangerous but probably not too likely to actually trigger in the wild
  given that there hasn't been any report yet.

  The other two are low impact fixes"

* 'for-3.17-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu:
  percpu: free percpu allocation info for uniprocessor system
  percpu: perform tlb flush after pcpu_map_pages() failure
  percpu: fix pcpu_alloc_pages() failure path
parents cfa7c641 3189eddb
...@@ -108,7 +108,7 @@ static int pcpu_alloc_pages(struct pcpu_chunk *chunk, ...@@ -108,7 +108,7 @@ static int pcpu_alloc_pages(struct pcpu_chunk *chunk,
int page_start, int page_end) int page_start, int page_end)
{ {
const gfp_t gfp = GFP_KERNEL | __GFP_HIGHMEM | __GFP_COLD; const gfp_t gfp = GFP_KERNEL | __GFP_HIGHMEM | __GFP_COLD;
unsigned int cpu; unsigned int cpu, tcpu;
int i; int i;
for_each_possible_cpu(cpu) { for_each_possible_cpu(cpu) {
...@@ -116,14 +116,23 @@ static int pcpu_alloc_pages(struct pcpu_chunk *chunk, ...@@ -116,14 +116,23 @@ static int pcpu_alloc_pages(struct pcpu_chunk *chunk,
struct page **pagep = &pages[pcpu_page_idx(cpu, i)]; struct page **pagep = &pages[pcpu_page_idx(cpu, i)];
*pagep = alloc_pages_node(cpu_to_node(cpu), gfp, 0); *pagep = alloc_pages_node(cpu_to_node(cpu), gfp, 0);
if (!*pagep) { if (!*pagep)
pcpu_free_pages(chunk, pages, populated, goto err;
page_start, page_end);
return -ENOMEM;
}
} }
} }
return 0; 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;
} }
/** /**
...@@ -263,6 +272,7 @@ static int pcpu_map_pages(struct pcpu_chunk *chunk, ...@@ -263,6 +272,7 @@ static int pcpu_map_pages(struct pcpu_chunk *chunk,
__pcpu_unmap_pages(pcpu_chunk_addr(chunk, tcpu, page_start), __pcpu_unmap_pages(pcpu_chunk_addr(chunk, tcpu, page_start),
page_end - page_start); page_end - page_start);
} }
pcpu_post_unmap_tlb_flush(chunk, page_start, page_end);
return err; return err;
} }
......
...@@ -1932,6 +1932,8 @@ void __init setup_per_cpu_areas(void) ...@@ -1932,6 +1932,8 @@ void __init setup_per_cpu_areas(void)
if (pcpu_setup_first_chunk(ai, fc) < 0) if (pcpu_setup_first_chunk(ai, fc) < 0)
panic("Failed to initialize percpu areas."); panic("Failed to initialize percpu areas.");
pcpu_free_alloc_info(ai);
} }
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment