summaryrefslogtreecommitdiff
path: root/arch/powerpc/platforms/pseries/lparcfg.c
diff options
context:
space:
mode:
authorNicholas Piggin <npiggin@gmail.com>2018-05-04 20:19:30 +0300
committerMichael Ellerman <mpe@ellerman.id.au>2018-06-03 13:40:27 +0300
commit3d3a6021ddcbe9c31520e4e7b65e5ce5dc58274d (patch)
tree10d300ac9f4f3b8354b9e35075d3d5a776739e7e /arch/powerpc/platforms/pseries/lparcfg.c
parent36d632ea831fd2fa3cb62599a465825f59076f64 (diff)
downloadlinux-3d3a6021ddcbe9c31520e4e7b65e5ce5dc58274d.tar.xz
powerpc/pseries: lparcfg calculate PURR on demand
For SPLPAR, lparcfg provides a sum of PURR registers for all CPUs. Currently this is done by reading PURR in context switch and timer interrupt, and storing that into a per-CPU variable. These are summed to provide the value. This does not work with all timer schemes (e.g., NO_HZ_FULL), and it is sub-optimal for performance because it reads the PURR register on every context switch, although that's been difficult to distinguish from noise in the contxt_switch microbenchmark. This patch implements the sum by calling a function on each CPU, to read and add PURR values of each CPU. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/platforms/pseries/lparcfg.c')
-rw-r--r--arch/powerpc/platforms/pseries/lparcfg.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/arch/powerpc/platforms/pseries/lparcfg.c b/arch/powerpc/platforms/pseries/lparcfg.c
index c508c938dc71..7c872dc01bdb 100644
--- a/arch/powerpc/platforms/pseries/lparcfg.c
+++ b/arch/powerpc/platforms/pseries/lparcfg.c
@@ -52,18 +52,20 @@
* Track sum of all purrs across all processors. This is used to further
* calculate usage values by different applications
*/
+static void cpu_get_purr(void *arg)
+{
+ atomic64_t *sum = arg;
+
+ atomic64_add(mfspr(SPRN_PURR), sum);
+}
+
static unsigned long get_purr(void)
{
- unsigned long sum_purr = 0;
- int cpu;
+ atomic64_t purr = ATOMIC64_INIT(0);
- for_each_possible_cpu(cpu) {
- struct cpu_usage *cu;
+ on_each_cpu(cpu_get_purr, &purr, 1);
- cu = &per_cpu(cpu_usage_array, cpu);
- sum_purr += cu->current_tb;
- }
- return sum_purr;
+ return atomic64_read(&purr);
}
/*