Commit b4911ea2 authored by Mel Gorman's avatar Mel Gorman Committed by Linus Torvalds

mm: initialise per_cpu_nodestats for all online pgdats at boot

Paul Mackerras and Reza Arbab reported that machines with memoryless
nodes fail when vmstats are refreshed.  Paul reported an oops as follows

  Unable to handle kernel paging request for data at address 0xff7a10000
  Faulting instruction address: 0xc000000000270cd0
  Oops: Kernel access of bad area, sig: 11 [#1]
  SMP NR_CPUS=2048 NUMA PowerNV
  Modules linked in:
  CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.7.0-kvm+ #118
  task: c000000ff0680010 task.stack: c000000ff0704000
  NIP: c000000000270cd0 LR: c000000000270ce8 CTR: 0000000000000000
  REGS: c000000ff0707900 TRAP: 0300   Not tainted  (4.7.0-kvm+)
  MSR: 9000000102009033 <SF,HV,VEC,EE,ME,IR,DR,RI,LE,TM[E]>  CR: 846b6824  XER: 20000000
  CFAR: c000000000008768 DAR: 0000000ff7a10000 DSISR: 42000000 SOFTE: 1
  NIP refresh_zone_stat_thresholds+0x80/0x240
  LR refresh_zone_stat_thresholds+0x98/0x240
  Call Trace:
    refresh_zone_stat_thresholds+0xb8/0x240 (unreliable)

Both supplied potential fixes but one potentially misses checks and
another had redundant initialisations.  This version initialises
per_cpu_nodestats on a per-pgdat basis instead of on a per-zone basis.

Link: http://lkml.kernel.org/r/20160804092404.GI2799@techsingularity.netSigned-off-by: default avatarMel Gorman <mgorman@techsingularity.net>
Reported-by: default avatarPaul Mackerras <paulus@ozlabs.org>
Reported-by: default avatarReza Arbab <arbab@linux.vnet.ibm.com>
Tested-by: default avatarReza Arbab <arbab@linux.vnet.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 412d0008
...@@ -5257,11 +5257,6 @@ static void __meminit setup_zone_pageset(struct zone *zone) ...@@ -5257,11 +5257,6 @@ static void __meminit setup_zone_pageset(struct zone *zone)
zone->pageset = alloc_percpu(struct per_cpu_pageset); zone->pageset = alloc_percpu(struct per_cpu_pageset);
for_each_possible_cpu(cpu) for_each_possible_cpu(cpu)
zone_pageset_init(zone, cpu); zone_pageset_init(zone, cpu);
if (!zone->zone_pgdat->per_cpu_nodestats) {
zone->zone_pgdat->per_cpu_nodestats =
alloc_percpu(struct per_cpu_nodestat);
}
} }
/* /*
...@@ -5270,10 +5265,15 @@ static void __meminit setup_zone_pageset(struct zone *zone) ...@@ -5270,10 +5265,15 @@ static void __meminit setup_zone_pageset(struct zone *zone)
*/ */
void __init setup_per_cpu_pageset(void) void __init setup_per_cpu_pageset(void)
{ {
struct pglist_data *pgdat;
struct zone *zone; struct zone *zone;
for_each_populated_zone(zone) for_each_populated_zone(zone)
setup_zone_pageset(zone); setup_zone_pageset(zone);
for_each_online_pgdat(pgdat)
pgdat->per_cpu_nodestats =
alloc_percpu(struct per_cpu_nodestat);
} }
static noinline __ref static noinline __ref
......
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