diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-10 14:59:50 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-10 14:59:50 -0700 |
commit | f3b26922ecea142a675fa464dbc47d4c4f48dab1 (patch) | |
tree | db41bf58a01fcf5582e267386995e6fc45563549 | |
parent | fda27bed908bb8c1c9bdaceb6b49bc6b21fc5424 (diff) | |
parent | 100d13c3b5b9410f604b86f5e0a34da64b8cf659 (diff) | |
download | linux-f3b26922ecea142a675fa464dbc47d4c4f48dab1.tar.bz2 |
Merge branch 'for-3.4-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu
Pull percpu fixes from Tejun Heo:
"This pull request contains two patches. One is kmemleak annotation
fix which isn't critical. The other is kinda serious.
Depending on NUMA topology, percpu allocator may end up assigning
overlapping regions for the static percpu areas for different CPUs.
While critical, the bug has been there for a very long time and only
few configurations seem to be affected (NUMA configurations w/ no
memory nodes for example) - so, while it's critical, it isn't exactly
urgent."
* 'for-3.4-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu:
kmemleak: Fix the kmemleak tracking of the percpu areas with !SMP
percpu: pcpu_embed_first_chunk() should free unused parts after all allocs are complete
-rw-r--r-- | mm/percpu.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/mm/percpu.c b/mm/percpu.c index f921fdfb5430..bb4be7435ce3 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -1650,6 +1650,16 @@ int __init pcpu_embed_first_chunk(size_t reserved_size, size_t dyn_size, areas[group] = ptr; base = min(ptr, base); + } + + /* + * Copy data and free unused parts. This should happen after all + * allocations are complete; otherwise, we may end up with + * overlapping groups. + */ + for (group = 0; group < ai->nr_groups; group++) { + struct pcpu_group_info *gi = &ai->groups[group]; + void *ptr = areas[group]; for (i = 0; i < gi->nr_units; i++, ptr += ai->unit_size) { if (gi->cpu_map[i] == NR_CPUS) { @@ -1885,6 +1895,8 @@ void __init setup_per_cpu_areas(void) fc = __alloc_bootmem(unit_size, PAGE_SIZE, __pa(MAX_DMA_ADDRESS)); if (!ai || !fc) panic("Failed to allocate memory for percpu areas."); + /* kmemleak tracks the percpu allocations separately */ + kmemleak_free(fc); ai->dyn_size = unit_size; ai->unit_size = unit_size; |