From: Nicholas Piggin <npiggin@gmail.com> Date: 2018-04-05 17:56:44
Any reason we still need to take the tlbie lock on modern
processors?
Nicholas Piggin (2):
KVM: PPC: Book3S HV: trace_tlbie must not be called in realmode
KVM: PPC: Book3S HV: lockless tlbie for HPT hcalls
arch/powerpc/kvm/book3s_hv_rm_mmu.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
--
2.16.3
From: Nicholas Piggin <npiggin@gmail.com> Date: 2018-04-05 17:56:47
This crashes with a "Bad real address for load" attempting to load
from the vmalloc region in realmode (faulting address is in DAR).
Oops: Bad interrupt in KVM entry/exit code, sig: 6 [#1]
LE SMP NR_CPUS=2048 NUMA PowerNV
CPU: 53 PID: 6582 Comm: qemu-system-ppc Not tainted 4.16.0-01530-g43d1859f0994
NIP: c0000000000155ac LR: c0000000000c2430 CTR: c000000000015580
REGS: c000000fff76dd80 TRAP: 0200 Not tainted (4.16.0-01530-g43d1859f0994)
MSR: 9000000000201003 <SF,HV,ME,RI,LE> CR: 48082222 XER: 00000000
CFAR: 0000000102900ef0 DAR: d00017fffd941a28 DSISR: 00000040 SOFTE: 3
NIP [c0000000000155ac] perf_trace_tlbie+0x2c/0x1a0
LR [c0000000000c2430] do_tlbies+0x230/0x2f0
I suspect the reason is the per-cpu data is not in the linear chunk.
This could be restored if that was able to be fixed, but for now,
just remove the tracepoints.
Fixes: 0428491cba ("powerpc/mm: Trace tlbie(l) instructions")
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kvm/book3s_hv_rm_mmu.c | 4 ----
1 file changed, 4 deletions(-)
From: Nicholas Piggin <npiggin@gmail.com> Date: 2018-04-05 17:56:50
tlbies to an LPAR do not have to be serialised since POWER4,
MMU_FTR_LOCKLESS_TLBIE can be used to avoid the spin lock in
do_tlbies.
Testing was done on a POWER9 system in HPT mode, with a -smp 32 guest
in HPT mode. 32 instances of the powerpc fork benchmark from selftests
were run with --fork, and the results measured.
Without this patch, total throughput was about 13.5K/sec, and this is
the top of the host profile:
74.52% [k] do_tlbies
2.95% [k] kvmppc_book3s_hv_page_fault
1.80% [k] calc_checksum
1.80% [k] kvmppc_vcpu_run_hv
1.49% [k] kvmppc_run_core
After this patch, throughput was about 51K/sec, with this profile:
21.28% [k] do_tlbies
5.26% [k] kvmppc_run_core
4.88% [k] kvmppc_book3s_hv_page_fault
3.30% [k] _raw_spin_lock_irqsave
3.25% [k] gup_pgd_range
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kvm/book3s_hv_rm_mmu.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
@@ -439,6 +439,9 @@ static inline int try_lock_tlbie(unsigned int *lock)unsignedinttmp,old;unsignedinttoken=LOCK_TOKEN;+if(mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE))+return1;+asmvolatile("1:lwarx %1,0,%2\n"" cmpwi cr0,%1,0\n"" bne 2f\n"
@@ -452,6 +455,12 @@ static inline int try_lock_tlbie(unsigned int *lock)returnold==0;}+staticinlinevoidunlock_tlbie_after_sync(unsignedint*lock)+{+if(mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE))+return;+}+staticvoiddo_tlbies(structkvm*kvm,unsignedlong*rbvalues,longnpages,intglobal,boolneed_sync){
From: Nicholas Piggin <npiggin@gmail.com> Date: 2018-04-06 05:39:44
On Fri, 6 Apr 2018 03:56:31 +1000
Nicholas Piggin [off-list ref] wrote:
quoted hunk
tlbies to an LPAR do not have to be serialised since POWER4,
MMU_FTR_LOCKLESS_TLBIE can be used to avoid the spin lock in
do_tlbies.
Testing was done on a POWER9 system in HPT mode, with a -smp 32 guest
in HPT mode. 32 instances of the powerpc fork benchmark from selftests
were run with --fork, and the results measured.
Without this patch, total throughput was about 13.5K/sec, and this is
the top of the host profile:
74.52% [k] do_tlbies
2.95% [k] kvmppc_book3s_hv_page_fault
1.80% [k] calc_checksum
1.80% [k] kvmppc_vcpu_run_hv
1.49% [k] kvmppc_run_core
After this patch, throughput was about 51K/sec, with this profile:
21.28% [k] do_tlbies
5.26% [k] kvmppc_run_core
4.88% [k] kvmppc_book3s_hv_page_fault
3.30% [k] _raw_spin_lock_irqsave
3.25% [k] gup_pgd_range
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
arch/powerpc/kvm/book3s_hv_rm_mmu.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
@@ -439,6 +439,9 @@ static inline int try_lock_tlbie(unsigned int *lock)unsignedinttmp,old;unsignedinttoken=LOCK_TOKEN;+if(mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE))+return1;+asmvolatile("1:lwarx %1,0,%2\n"" cmpwi cr0,%1,0\n"" bne 2f\n"
@@ -452,6 +455,12 @@ static inline int try_lock_tlbie(unsigned int *lock)returnold==0;}+staticinlinevoidunlock_tlbie_after_sync(unsignedint*lock)+{+if(mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE))+return;+}+staticvoiddo_tlbies(structkvm*kvm,unsignedlong*rbvalues,longnpages,intglobal,boolneed_sync){
Well that's a silly bug in the !LOCKLESS path, that was supposed
to move to unlock, of course. Will fix it up after some time for
comments.
Thanks,
Nick
@@ -439,6 +439,9 @@ static inline int try_lock_tlbie(unsigned int *lock)unsignedinttmp,old;unsignedinttoken=LOCK_TOKEN;+if(mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE))+return1;+asmvolatile("1:lwarx %1,0,%2\n"" cmpwi cr0,%1,0\n"" bne 2f\n"
@@ -452,6 +455,12 @@ static inline int try_lock_tlbie(unsigned int *lock)returnold==0;}+staticinlinevoidunlock_tlbie_after_sync(unsignedint*lock)+{+if(mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE))+return;+}
So this is a bit hard to follow:
#define MMU_FTRS_DEFAULT_HPTE_ARCH_V2 \
MMU_FTR_HPTE_TABLE | MMU_FTR_PPCAS_ARCH_V2
#define MMU_FTRS_POWER MMU_FTRS_DEFAULT_HPTE_ARCH_V2
#define MMU_FTRS_PPC970 MMU_FTRS_POWER | MMU_FTR_TLBIE_CROP_VA // does NOT
#define MMU_FTRS_POWER5 MMU_FTRS_POWER | MMU_FTR_LOCKLESS_TLBIE
#define MMU_FTRS_POWER6 MMU_FTRS_POWER5 | MMU_FTR_KERNEL_RO | MMU_FTR_68_BIT_VA // includes lockless TLBIE
#define MMU_FTRS_POWER7 MMU_FTRS_POWER6 // includes lockless TLBIE
#define MMU_FTRS_POWER8 MMU_FTRS_POWER6 // includes lockless TLBIE
#define MMU_FTRS_POWER9 MMU_FTRS_POWER6 // includes lockless TLBIE
#define MMU_FTRS_CELL MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | // does NOT
MMU_FTR_CI_LARGE_PAGE
#define MMU_FTRS_PA6T MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \ // does NOT
MMU_FTR_CI_LARGE_PAGE | MMU_FTR_NO_SLBIE_B
So it's only 970, Cell and Pasemi that *don't* have lockless TLBIE.
And KVM HV doesn't doesn't run on any of those.
So we can just not check for the feature in the KVM HV code.
Am I right?
cheers
On Fri, Apr 6, 2018 at 3:56 AM, Nicholas Piggin [off-list ref] wrote:
This crashes with a "Bad real address for load" attempting to load
from the vmalloc region in realmode (faulting address is in DAR).
Oops: Bad interrupt in KVM entry/exit code, sig: 6 [#1]
LE SMP NR_CPUS=2048 NUMA PowerNV
CPU: 53 PID: 6582 Comm: qemu-system-ppc Not tainted 4.16.0-01530-g43d1859f0994
NIP: c0000000000155ac LR: c0000000000c2430 CTR: c000000000015580
REGS: c000000fff76dd80 TRAP: 0200 Not tainted (4.16.0-01530-g43d1859f0994)
MSR: 9000000000201003 <SF,HV,ME,RI,LE> CR: 48082222 XER: 00000000
CFAR: 0000000102900ef0 DAR: d00017fffd941a28 DSISR: 00000040 SOFTE: 3
NIP [c0000000000155ac] perf_trace_tlbie+0x2c/0x1a0
LR [c0000000000c2430] do_tlbies+0x230/0x2f0
I suspect the reason is the per-cpu data is not in the linear chunk.
This could be restored if that was able to be fixed, but for now,
just remove the tracepoints.
Could you share the stack trace as well? I've not observed this in my testing.
May be I don't have as many cpus. I presume your talking about the per cpu
data offsets for per cpu trace data?
Balbir Singh.
On Fri, Apr 6, 2018 at 3:56 AM, Nicholas Piggin [off-list ref] wrote:
quoted
This crashes with a "Bad real address for load" attempting to load
from the vmalloc region in realmode (faulting address is in DAR).
Oops: Bad interrupt in KVM entry/exit code, sig: 6 [#1]
LE SMP NR_CPUS=2048 NUMA PowerNV
CPU: 53 PID: 6582 Comm: qemu-system-ppc Not tainted 4.16.0-01530-g43d1859f0994
NIP: c0000000000155ac LR: c0000000000c2430 CTR: c000000000015580
REGS: c000000fff76dd80 TRAP: 0200 Not tainted (4.16.0-01530-g43d1859f0994)
MSR: 9000000000201003 <SF,HV,ME,RI,LE> CR: 48082222 XER: 00000000
CFAR: 0000000102900ef0 DAR: d00017fffd941a28 DSISR: 00000040 SOFTE: 3
NIP [c0000000000155ac] perf_trace_tlbie+0x2c/0x1a0
LR [c0000000000c2430] do_tlbies+0x230/0x2f0
I suspect the reason is the per-cpu data is not in the linear chunk.
This could be restored if that was able to be fixed, but for now,
just remove the tracepoints.
Could you share the stack trace as well? I've not observed this in my testing.
I can't seem to find it, I can try reproduce tomorrow. It was coming
from h_remove hcall from the guest. It's 176 logical CPUs.
May be I don't have as many cpus. I presume your talking about the per cpu
data offsets for per cpu trace data?
It looked like it was dereferencing virtually mapped per-cpu data, yes.
Probably the perf_events deref.
Thanks,
Nick
On Fri, Apr 6, 2018 at 3:56 AM, Nicholas Piggin [off-list ref] wrote:
quoted
This crashes with a "Bad real address for load" attempting to load
from the vmalloc region in realmode (faulting address is in DAR).
Oops: Bad interrupt in KVM entry/exit code, sig: 6 [#1]
LE SMP NR_CPUS=2048 NUMA PowerNV
CPU: 53 PID: 6582 Comm: qemu-system-ppc Not tainted 4.16.0-01530-g43d1859f0994
NIP: c0000000000155ac LR: c0000000000c2430 CTR: c000000000015580
REGS: c000000fff76dd80 TRAP: 0200 Not tainted (4.16.0-01530-g43d1859f0994)
MSR: 9000000000201003 <SF,HV,ME,RI,LE> CR: 48082222 XER: 00000000
CFAR: 0000000102900ef0 DAR: d00017fffd941a28 DSISR: 00000040 SOFTE: 3
NIP [c0000000000155ac] perf_trace_tlbie+0x2c/0x1a0
LR [c0000000000c2430] do_tlbies+0x230/0x2f0
I suspect the reason is the per-cpu data is not in the linear chunk.
This could be restored if that was able to be fixed, but for now,
just remove the tracepoints.
Could you share the stack trace as well? I've not observed this in my testing.
I can't seem to find it, I can try reproduce tomorrow. It was coming
from h_remove hcall from the guest. It's 176 logical CPUs.
quoted
May be I don't have as many cpus. I presume your talking about the per cpu
data offsets for per cpu trace data?
It looked like it was dereferencing virtually mapped per-cpu data, yes.
Probably the perf_events deref.
On Fri, Apr 6, 2018 at 3:56 AM, Nicholas Piggin [off-list ref] wro=
te:
quoted
quoted
quoted
This crashes with a "Bad real address for load" attempting to load
from the vmalloc region in realmode (faulting address is in DAR).
Oops: Bad interrupt in KVM entry/exit code, sig: 6 [#1]
LE SMP NR_CPUS=3D2048 NUMA PowerNV
CPU: 53 PID: 6582 Comm: qemu-system-ppc Not tainted 4.16.0-01530-g4=
NIP [c0000000000155ac] perf_trace_tlbie+0x2c/0x1a0
LR [c0000000000c2430] do_tlbies+0x230/0x2f0
I suspect the reason is the per-cpu data is not in the linear chunk.
This could be restored if that was able to be fixed, but for now,
just remove the tracepoints. =20
=20
Could you share the stack trace as well? I've not observed this in my t=
esting.
quoted
I can't seem to find it, I can try reproduce tomorrow. It was coming
from h_remove hcall from the guest. It's 176 logical CPUs.
quoted
May be I don't have as many cpus. I presume your talking about the per =
cpu
quoted
quoted
data offsets for per cpu trace data?
It looked like it was dereferencing virtually mapped per-cpu data, yes.
Probably the perf_events deref.
I'm afraid that won't actually help here :(
That series is specific to the function tracer, while this is using=20
static tracepoints.
We could convert trace_tlbie() to a TRACE_EVENT_CONDITION() and guard it=20
within a check for paca->ftrace_enabled, but that would only be useful=20
if the below callsites can ever be hit outside of KVM guest mode.
- Naveen
=
On Fri, Apr 6, 2018 at 3:56 AM, Nicholas Piggin [off-list ref] wrote:
quoted
This crashes with a "Bad real address for load" attempting to load
from the vmalloc region in realmode (faulting address is in DAR).
Oops: Bad interrupt in KVM entry/exit code, sig: 6 [#1]
LE SMP NR_CPUS=2048 NUMA PowerNV
CPU: 53 PID: 6582 Comm: qemu-system-ppc Not tainted 4.16.0-01530-g43d1859f0994
NIP: c0000000000155ac LR: c0000000000c2430 CTR: c000000000015580
REGS: c000000fff76dd80 TRAP: 0200 Not tainted (4.16.0-01530-g43d1859f0994)
MSR: 9000000000201003 <SF,HV,ME,RI,LE> CR: 48082222 XER: 00000000
CFAR: 0000000102900ef0 DAR: d00017fffd941a28 DSISR: 00000040 SOFTE: 3
NIP [c0000000000155ac] perf_trace_tlbie+0x2c/0x1a0
LR [c0000000000c2430] do_tlbies+0x230/0x2f0
I suspect the reason is the per-cpu data is not in the linear chunk.
This could be restored if that was able to be fixed, but for now,
just remove the tracepoints.
Could you share the stack trace as well? I've not observed this in my testing.
I can't seem to find it, I can try reproduce tomorrow. It was coming
from h_remove hcall from the guest. It's 176 logical CPUs.
quoted
May be I don't have as many cpus. I presume your talking about the per cpu
data offsets for per cpu trace data?
It looked like it was dereferencing virtually mapped per-cpu data, yes.
Probably the perf_events deref.
I'm afraid that won't actually help here :(
That series is specific to the function tracer, while this is using
static tracepoints.
We could convert trace_tlbie() to a TRACE_EVENT_CONDITION() and guard it
within a check for paca->ftrace_enabled, but that would only be useful
if the below callsites can ever be hit outside of KVM guest mode.
Right, removing the trace points is the right thing to do here.
Doing tracing in real mode would be a whole effort itself, I'd expect.
Or disabling realmode handling of HPT hcalls if trace points are
active.
Thanks,
Nick
From: Michael Ellerman <hidden> Date: 2018-04-11 14:49:30
On Thu, 2018-04-05 at 17:56:30 UTC, Nicholas Piggin wrote:
This crashes with a "Bad real address for load" attempting to load
from the vmalloc region in realmode (faulting address is in DAR).
Oops: Bad interrupt in KVM entry/exit code, sig: 6 [#1]
LE SMP NR_CPUS=2048 NUMA PowerNV
CPU: 53 PID: 6582 Comm: qemu-system-ppc Not tainted 4.16.0-01530-g43d1859f0994
NIP: c0000000000155ac LR: c0000000000c2430 CTR: c000000000015580
REGS: c000000fff76dd80 TRAP: 0200 Not tainted (4.16.0-01530-g43d1859f0994)
MSR: 9000000000201003 <SF,HV,ME,RI,LE> CR: 48082222 XER: 00000000
CFAR: 0000000102900ef0 DAR: d00017fffd941a28 DSISR: 00000040 SOFTE: 3
NIP [c0000000000155ac] perf_trace_tlbie+0x2c/0x1a0
LR [c0000000000c2430] do_tlbies+0x230/0x2f0
I suspect the reason is the per-cpu data is not in the linear chunk.
This could be restored if that was able to be fixed, but for now,
just remove the tracepoints.
Fixes: 0428491cba ("powerpc/mm: Trace tlbie(l) instructions")
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
@@ -439,6 +439,9 @@ static inline int try_lock_tlbie(unsigned int *lock)unsignedinttmp,old;unsignedinttoken=LOCK_TOKEN;+if(mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE))+return1;+asmvolatile("1:lwarx %1,0,%2\n"" cmpwi cr0,%1,0\n"" bne 2f\n"
@@ -452,6 +455,12 @@ static inline int try_lock_tlbie(unsigned int *lock)returnold==0;}+staticinlinevoidunlock_tlbie_after_sync(unsignedint*lock)+{+if(mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE))+return;+}
So this is a bit hard to follow:
#define MMU_FTRS_DEFAULT_HPTE_ARCH_V2 \
MMU_FTR_HPTE_TABLE | MMU_FTR_PPCAS_ARCH_V2
#define MMU_FTRS_POWER MMU_FTRS_DEFAULT_HPTE_ARCH_V2
#define MMU_FTRS_PPC970 MMU_FTRS_POWER | MMU_FTR_TLBIE_CROP_VA // does NOT
#define MMU_FTRS_POWER5 MMU_FTRS_POWER | MMU_FTR_LOCKLESS_TLBIE
#define MMU_FTRS_POWER6 MMU_FTRS_POWER5 | MMU_FTR_KERNEL_RO | MMU_FTR_68_BIT_VA // includes lockless TLBIE
#define MMU_FTRS_POWER7 MMU_FTRS_POWER6 // includes lockless TLBIE
#define MMU_FTRS_POWER8 MMU_FTRS_POWER6 // includes lockless TLBIE
#define MMU_FTRS_POWER9 MMU_FTRS_POWER6 // includes lockless TLBIE
#define MMU_FTRS_CELL MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | // does NOT
MMU_FTR_CI_LARGE_PAGE
#define MMU_FTRS_PA6T MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \ // does NOT
MMU_FTR_CI_LARGE_PAGE | MMU_FTR_NO_SLBIE_B
So it's only 970, Cell and Pasemi that *don't* have lockless TLBIE.
And KVM HV doesn't doesn't run on any of those.
So we can just not check for the feature in the KVM HV code.
Am I right?
Yes; that code was written when we still supported HV KVM on 970,
but we ripped that out some time ago.
Paul.
@@ -439,6 +439,9 @@ static inline int try_lock_tlbie(unsigned int *lock)unsignedinttmp,old;unsignedinttoken=LOCK_TOKEN;+if(mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE))+return1;+asmvolatile("1:lwarx %1,0,%2\n"" cmpwi cr0,%1,0\n"" bne 2f\n"
@@ -452,6 +455,12 @@ static inline int try_lock_tlbie(unsigned int *lock)returnold==0;}+staticinlinevoidunlock_tlbie_after_sync(unsignedint*lock)+{+if(mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE))+return;+}
So this is a bit hard to follow:
#define MMU_FTRS_DEFAULT_HPTE_ARCH_V2 \
MMU_FTR_HPTE_TABLE | MMU_FTR_PPCAS_ARCH_V2
#define MMU_FTRS_POWER MMU_FTRS_DEFAULT_HPTE_ARCH_V2
#define MMU_FTRS_PPC970 MMU_FTRS_POWER | MMU_FTR_TLBIE_CROP_VA // does NOT
#define MMU_FTRS_POWER5 MMU_FTRS_POWER | MMU_FTR_LOCKLESS_TLBIE
#define MMU_FTRS_POWER6 MMU_FTRS_POWER5 | MMU_FTR_KERNEL_RO | MMU_FTR_68_BIT_VA // includes lockless TLBIE
#define MMU_FTRS_POWER7 MMU_FTRS_POWER6 // includes lockless TLBIE
#define MMU_FTRS_POWER8 MMU_FTRS_POWER6 // includes lockless TLBIE
#define MMU_FTRS_POWER9 MMU_FTRS_POWER6 // includes lockless TLBIE
#define MMU_FTRS_CELL MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | // does NOT
MMU_FTR_CI_LARGE_PAGE
#define MMU_FTRS_PA6T MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \ // does NOT
MMU_FTR_CI_LARGE_PAGE | MMU_FTR_NO_SLBIE_B
So it's only 970, Cell and Pasemi that *don't* have lockless TLBIE.
And KVM HV doesn't doesn't run on any of those.
So we can just not check for the feature in the KVM HV code.
Am I right?
Yes; that code was written when we still supported HV KVM on 970,
but we ripped that out some time ago.
OK good, in commit:
c17b98cf6028 ("KVM: PPC: Book3S HV: Remove code for PPC970 processors") (Dec 2014)
So we should be able to do the patch below.
cheers
From: Paul Mackerras <hidden> Date: 2018-05-17 03:54:00
On Mon, May 14, 2018 at 02:04:10PM +1000, Michael Ellerman wrote:
[snip]
quoted hunk
OK good, in commit:
c17b98cf6028 ("KVM: PPC: Book3S HV: Remove code for PPC970 processors") (Dec 2014)
So we should be able to do the patch below.
cheers