aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-10 14:59:50 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-10 14:59:50 -0700
commitf3b26922ecea142a675fa464dbc47d4c4f48dab1 (patch)
treedb41bf58a01fcf5582e267386995e6fc45563549
parentfda27bed908bb8c1c9bdaceb6b49bc6b21fc5424 (diff)
parent100d13c3b5b9410f604b86f5e0a34da64b8cf659 (diff)
downloadubi2-f3b26922ecea142a675fa464dbc47d4c4f48dab1.tar.gz
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.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/mm/percpu.c b/mm/percpu.c
index f921fdfb543021..bb4be7435ce34b 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;