diff options
author | Michael Ellerman <mpe@ellerman.id.au> | 2017-10-15 14:43:41 -0400 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2017-11-21 20:24:46 -0500 |
commit | f3f1dfd600ff82b18b7ea73d80eb27f476a6aa97 (patch) | |
tree | 5ece696e86f5b89c26a3517aebb8ff5a8bf7106d | |
parent | 62b49c42107efd973edffc75f4f874c5226cd20a (diff) |
powerpc/perf/imc: Use cpu_to_node() not topology_physical_package_id()
init_imc_pmu() uses topology_physical_package_id() to detect the
node id of the processor it is on to get local memory, but that's
wrong, and can lead to crashes. Fix it to use cpu_to_node().
Fixes: 885dcd709ba9 ("powerpc/perf: Add nest IMC PMU support")
Cc: stable@vger.kernel.org # v4.14+
Reported-By: Rob Lippert <rlippert@google.com>
Tested-By: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r-- | arch/powerpc/perf/imc-pmu.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c index 36344117c680..cf64e16f92c2 100644 --- a/arch/powerpc/perf/imc-pmu.c +++ b/arch/powerpc/perf/imc-pmu.c | |||
@@ -467,7 +467,7 @@ static int nest_imc_event_init(struct perf_event *event) | |||
467 | * Nest HW counter memory resides in a per-chip reserve-memory (HOMER). | 467 | * Nest HW counter memory resides in a per-chip reserve-memory (HOMER). |
468 | * Get the base memory addresss for this cpu. | 468 | * Get the base memory addresss for this cpu. |
469 | */ | 469 | */ |
470 | chip_id = topology_physical_package_id(event->cpu); | 470 | chip_id = cpu_to_chip_id(event->cpu); |
471 | pcni = pmu->mem_info; | 471 | pcni = pmu->mem_info; |
472 | do { | 472 | do { |
473 | if (pcni->id == chip_id) { | 473 | if (pcni->id == chip_id) { |
@@ -524,19 +524,19 @@ static int nest_imc_event_init(struct perf_event *event) | |||
524 | */ | 524 | */ |
525 | static int core_imc_mem_init(int cpu, int size) | 525 | static int core_imc_mem_init(int cpu, int size) |
526 | { | 526 | { |
527 | int phys_id, rc = 0, core_id = (cpu / threads_per_core); | 527 | int nid, rc = 0, core_id = (cpu / threads_per_core); |
528 | struct imc_mem_info *mem_info; | 528 | struct imc_mem_info *mem_info; |
529 | 529 | ||
530 | /* | 530 | /* |
531 | * alloc_pages_node() will allocate memory for core in the | 531 | * alloc_pages_node() will allocate memory for core in the |
532 | * local node only. | 532 | * local node only. |
533 | */ | 533 | */ |
534 | phys_id = topology_physical_package_id(cpu); | 534 | nid = cpu_to_node(cpu); |
535 | mem_info = &core_imc_pmu->mem_info[core_id]; | 535 | mem_info = &core_imc_pmu->mem_info[core_id]; |
536 | mem_info->id = core_id; | 536 | mem_info->id = core_id; |
537 | 537 | ||
538 | /* We need only vbase for core counters */ | 538 | /* We need only vbase for core counters */ |
539 | mem_info->vbase = page_address(alloc_pages_node(phys_id, | 539 | mem_info->vbase = page_address(alloc_pages_node(nid, |
540 | GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE | | 540 | GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE | |
541 | __GFP_NOWARN, get_order(size))); | 541 | __GFP_NOWARN, get_order(size))); |
542 | if (!mem_info->vbase) | 542 | if (!mem_info->vbase) |
@@ -797,14 +797,14 @@ static int core_imc_event_init(struct perf_event *event) | |||
797 | static int thread_imc_mem_alloc(int cpu_id, int size) | 797 | static int thread_imc_mem_alloc(int cpu_id, int size) |
798 | { | 798 | { |
799 | u64 ldbar_value, *local_mem = per_cpu(thread_imc_mem, cpu_id); | 799 | u64 ldbar_value, *local_mem = per_cpu(thread_imc_mem, cpu_id); |
800 | int phys_id = topology_physical_package_id(cpu_id); | 800 | int nid = cpu_to_node(cpu_id); |
801 | 801 | ||
802 | if (!local_mem) { | 802 | if (!local_mem) { |
803 | /* | 803 | /* |
804 | * This case could happen only once at start, since we dont | 804 | * This case could happen only once at start, since we dont |
805 | * free the memory in cpu offline path. | 805 | * free the memory in cpu offline path. |
806 | */ | 806 | */ |
807 | local_mem = page_address(alloc_pages_node(phys_id, | 807 | local_mem = page_address(alloc_pages_node(nid, |
808 | GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE | | 808 | GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE | |
809 | __GFP_NOWARN, get_order(size))); | 809 | __GFP_NOWARN, get_order(size))); |
810 | if (!local_mem) | 810 | if (!local_mem) |