ARM: test for PMU feature on v7.
Subsystems (4)
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 1/1 ARM: test for PMU feature on v7.
The v7 ARM (B4.1.82) specifies that bits 27-24 of the ID_DFR0 reg show what performance monitoring (if any) is available. We should test this before assuming (useful for inside virtualized environments, for example).
arch/arm/kernel/perf_event_v7.c +14 -0
@@ -1108,6 +1108,12 @@ static struct arm_pmu armv7pmu = { .max_period = (1LLU << 32) - 1, }; +static bool armv7_pmu_avail (void ) +{ +/* 0 means unknown (maybe v1), 1 means v2, 2 means v2, 15 means none */ +return ((read_cpuid_ext (CPUID_EXT_DFR0 ) >>24 ) &0xF ) !=0xF ; +} +static u32 __init armv7_read_num_pmnc_events (void ) {u32 nb_cnt;
@@ -1121,6 +1127,8 @@ static u32 __init armv7_read_num_pmnc_events(void)static struct arm_pmu *__init armv7_a8_pmu_init (void ) { +if (!armv7_pmu_avail ()) +return NULL ; armv7pmu.id =ARM_PERF_PMU_ID_CA8 ; armv7pmu.name ="ARMv7 Cortex-A8" ; armv7pmu.map_event = armv7_a8_map_event;
@@ -1130,6 +1138,8 @@ static struct arm_pmu *__init armv7_a8_pmu_init(void)static struct arm_pmu *__init armv7_a9_pmu_init (void ) { +if (!armv7_pmu_avail ()) +return NULL ; armv7pmu.id =ARM_PERF_PMU_ID_CA9 ; armv7pmu.name ="ARMv7 Cortex-A9" ; armv7pmu.map_event = armv7_a9_map_event;
@@ -1139,6 +1149,8 @@ static struct arm_pmu *__init armv7_a9_pmu_init(void)static struct arm_pmu *__init armv7_a5_pmu_init (void ) { +if (!armv7_pmu_avail ()) +return NULL ; armv7pmu.id =ARM_PERF_PMU_ID_CA5 ; armv7pmu.name ="ARMv7 Cortex-A5" ; armv7pmu.map_event = armv7_a5_map_event;
@@ -1148,6 +1160,8 @@ static struct arm_pmu *__init armv7_a5_pmu_init(void)static struct arm_pmu *__init armv7_a15_pmu_init (void ) { +if (!armv7_pmu_avail ()) +return NULL ; armv7pmu.id =ARM_PERF_PMU_ID_CA15 ; armv7pmu.name ="ARMv7 Cortex-A15" ; armv7pmu.map_event = armv7_a15_map_event;
PATCH 1/1 ARM: test for PMU feature on v7 (v2 with typo fix)
The v7 ARM (B4.1.82) specifies that bits 27-24 of the ID_DFR0 reg show what performance monitoring (if any) is available. We should test this before assuming (useful for inside virtualized environments, for example).
arch/arm/kernel/perf_event_v7.c +14 -0
@@ -1108,6 +1108,12 @@ static struct arm_pmu armv7pmu = { .max_period = (1LLU << 32) - 1, }; +static bool armv7_pmu_avail (void ) +{ +/* 0 means unknown (maybe v1), 1 means v1, 2 means v2, 15 means none */ +return ((read_cpuid_ext (CPUID_EXT_DFR0 ) >>24 ) &0xF ) !=0xF ; +} +static u32 __init armv7_read_num_pmnc_events (void ) {u32 nb_cnt;
@@ -1121,6 +1127,8 @@ static u32 __init armv7_read_num_pmnc_events(void)static struct arm_pmu *__init armv7_a8_pmu_init (void ) { +if (!armv7_pmu_avail ()) +return NULL ; armv7pmu.id =ARM_PERF_PMU_ID_CA8 ; armv7pmu.name ="ARMv7 Cortex-A8" ; armv7pmu.map_event = armv7_a8_map_event;
@@ -1130,6 +1138,8 @@ static struct arm_pmu *__init armv7_a8_pmu_init(void)static struct arm_pmu *__init armv7_a9_pmu_init (void ) { +if (!armv7_pmu_avail ()) +return NULL ; armv7pmu.id =ARM_PERF_PMU_ID_CA9 ; armv7pmu.name ="ARMv7 Cortex-A9" ; armv7pmu.map_event = armv7_a9_map_event;
@@ -1139,6 +1149,8 @@ static struct arm_pmu *__init armv7_a9_pmu_init(void)static struct arm_pmu *__init armv7_a5_pmu_init (void ) { +if (!armv7_pmu_avail ()) +return NULL ; armv7pmu.id =ARM_PERF_PMU_ID_CA5 ; armv7pmu.name ="ARMv7 Cortex-A5" ; armv7pmu.map_event = armv7_a5_map_event;
@@ -1148,6 +1160,8 @@ static struct arm_pmu *__init armv7_a5_pmu_init(void)static struct arm_pmu *__init armv7_a15_pmu_init (void ) { +if (!armv7_pmu_avail ()) +return NULL ; armv7pmu.id =ARM_PERF_PMU_ID_CA15 ; armv7pmu.name ="ARMv7 Cortex-A15" ; armv7pmu.map_event = armv7_a15_map_event;
PATCH 1/1 ARM: test for PMU feature on v7 (v2 with typo fix)
Hi Rusty,
Quoted 3 lines · Rusty Russell
The v7 ARM (B4.1.82) specifies that bits 27-24 of the
ID_DFR0reg show what performance monitoring (if any) is available. We should test this before assuming (useful for inside virtualized environments, for example).
Ok, I can see why you don't want to emulate a PMU but I don't agree with the patch :)
Quoted 18 lines
arch/arm/kernel/perf_event_v7.c +6
-0@@ -1108,6 +1108,12 @@ static struct arm_pmu armv7pmu = { .max_period = (1LLU << 32) - 1, }; +static bool armv7_pmu_avail (void ) +{ +/* 0 means unknown (maybe v1), 1 means v1, 2 means v2, 15 means none */ +return ((read_cpuid_ext (CPUID_EXT_DFR0 ) >>24 ) &0xF ) !=0xF ; +} +static u32 __init armv7_read_num_pmnc_events (void ) {u32 nb_cnt;
arch/arm/kernel/perf_event_v7.c static u32 __init armv7_read_num_pmnc_events(void) · line 1131
Quoted 5 lines
arch/arm/kernel/perf_event_v7.c +2
-0@@ -1121,6 +1127,8 @@ static u32 __init armv7_read_num_pmnc_events(void)static struct arm_pmu *__init armv7_a8_pmu_init (void ) { +if (!armv7_pmu_avail ()) +return NULL ;
This code is only executed if we know for sure that we are running on a Cortex-A8. Cortex-A8 implementations have a PMU, so I don't like having the probe here in case we are running on a virtualised CPU that doesn't quite match the hardware.
Would you be able to advertise 0 event counters instead and treat the PMU largely as RAZ/WI? The only tricky bit I can see is the cycle counter, which is mandated by the presence of a PMU, however this could also just RAZ initially.
arch/arm/kernel/perf_event_v7.c static struct arm_pmu *__init armv7_a8_pmu_init(void) · line 1142
Quoted 9 lines
arch/arm/kernel/perf_event_v7.c +2
-0armv7pmu.id =ARM_PERF_PMU_ID_CA8 ; armv7pmu.name ="ARMv7 Cortex-A8" ; armv7pmu.map_event = armv7_a8_map_event;@@ -1130,6 +1138,8 @@ static struct arm_pmu *__init armv7_a8_pmu_init(void)static struct arm_pmu *__init armv7_a9_pmu_init (void ) { +if (!armv7_pmu_avail ()) +return NULL ;
Similarly for A5, A9, A7 and A15...
Cheers,
Will
PATCH 1/1 ARM: test for PMU feature on v7 (v2 with typo fix)
Quoted 9 lines · Will Deacon
Hi Rusty,
Quoted 3 lines · Rusty Russell
The v7 ARM (B4.1.82) specifies that bits 27-24 of the
ID_DFR0reg show what performance monitoring (if any) is available. We should test this before assuming (useful for inside virtualized environments, for example).Ok, I can see why you don't want to emulate a PMU but I don't agree with the patch :)
...
Quoted 9 lines
Review
Quoted 4 lines
static struct
arm_pmu*__initarmv7_a8_pmu_init(void){(quoted diff) +2
-0+ if (!armv7_pmu_avail()) + return NULL;This code is only executed if we know for sure that we are running on a Cortex-A8. Cortex-A8 implementations have a PMU, so I don't like having the probe here in case we are running on a virtualised CPU that doesn't quite match the hardware.
OK, I see that argument, but I don't like it. eg. the Cortex A-15 is defined to have a PMUv2 with 6 counters, and below you're arguing we should implement zero of them.
I had assumed that as we trend towards a common cross-platform kernel, we should be relying on feature registers where available, not the model.
Quoted 4 lines
Would you be able to advertise 0 event counters instead and treat the PMU largely as RAZ/WI? The only tricky bit I can see is the cycle counter, which is mandated by the presence of a PMU, however this could also just RAZ initially.
Yes, that's the effect of the current emulation hack. Far better not to lie to the guest, however, than get weird results from profiling.
Cheers,
Rusty.
Signature · 1 line
How could I marry someone with more hair than me? http://baldalex.org
PATCH 1/1 ARM: test for PMU feature on v7 (v2 with typo fix)
[removed some dead email addresses from CC]
Quoted 13 lines · Rusty Russell
Quoted 1 line · Will Deacon
On Fri, Mar 23, 2012 at 12:34:57AM +0000, Rusty Russell wrote:
...
Quoted 9 lines
Review
Quoted 4 lines
static struct
arm_pmu*__initarmv7_a8_pmu_init(void){(quoted diff) +2
-0+ if (!armv7_pmu_avail()) + return NULL;This code is only executed if we know for sure that we are running on a Cortex-A8. Cortex-A8 implementations have a PMU, so I don't like having the probe here in case we are running on a virtualised CPU that doesn't quite match the hardware.
Quoted 3 lines
OK, I see that argument, but I don't like it. eg. the Cortex A-15 is defined to have a PMUv2 with 6 counters, and below you're arguing we should implement zero of them.
Well, I think you should actually implement all 6 of them if that's the target which you're emulating. However, there are bigger peripherals to fry than the PMU so if you want to get something working quickly then a dummy PMU makes sense as a stopgap.
Quoted 3 lines
I had assumed that as we trend towards a common cross-platform kernel, we should be relying on feature registers where available, not the model.
The PMU is very tightly coupled with the CPU and it is necessary to know exactly which CPU you have so that you can map microarchitectural events to their identifiers. This is not discoverable in the architecture [PMUv2 provides some support for discovering the status of architected events, but that is still not enough and is only present on A7 and A15 so far] so that's why we probe the CPU instead.
Now, if everything was device-tree based then we could simply use a different binding for each CPU but since we support perf on non-DT platforms, probing the CPU type is the best solution. I would like to avoid the probing code if we are initialised from DT, but I've not got round to it yet (this would be useful for big.LITTLE).
Quoted 7 lines
Quoted 4 lines
Would you be able to advertise 0 event counters instead and treat the PMU largely as RAZ/WI? The only tricky bit I can see is the cycle counter, which is mandated by the presence of a PMU, however this could also just RAZ initially.
Yes, that's the effect of the current emulation hack. Far better not to lie to the guest, however, than get weird results from profiling.
I'd rather lie to the guest than modify it just to avoid emulating the device correctly. Even then, the profiling results wouldn't be especially weird -- everything would be 0, which is a lot better than random numbers.
Will
PATCH 1/1 ARM: test for PMU feature on v7 (v2 with typo fix)
Quoted 9 lines · Will Deacon
[removed some dead email addresses from CC]
Quoted 6 lines · Rusty Russell
Quoted 4 lines · Will Deacon
This code is only executed if we know for sure that we are running on a Cortex-A8. Cortex-A8 implementations have a PMU, so I don't like having the probe here in case we are running on a virtualised CPU that doesn't quite match the hardware.
Quoted 6 lines
Quoted 3 lines
OK, I see that argument, but I don't like it. ?eg. the Cortex A-15 is defined to have a PMUv2 with 6 counters, and below you're arguing we should implement zero of them.
Well, I think you should actually implement all 6 of them if that's the target which you're emulating.
The trouble with this line of thought is that it leads to the requirement to support nested virtualization and virtualization of TrustZone, neither of which are actually particularly useful or simple to do. At some point we're going to end up saying that the "A15" we expose to the guest is not an exact match to the real hardware, that it's missing certain features (and hopefully that the lack of those features is advertised via the feature registers). So the question is where you draw the line...
-- PMM
PATCH 1/1 ARM: test for PMU feature on v7 (v2 with typo fix)
Quoted 10 lines · Peter Maydell
Quoted 8 lines · Will Deacon
Quoted 4 lines · Rusty Russell
OK, I see that argument, but I don't like it. ?eg. the Cortex A-15 is defined to have a PMUv2 with 6 counters, and below you're arguing we should implement zero of them.
Well, I think you should actually implement all 6 of them if that's the target which you're emulating.
Quoted 7 lines
The trouble with this line of thought is that it leads to the requirement to support nested virtualization and virtualization of TrustZone, neither of which are actually particularly useful or simple to do. At some point we're going to end up saying that the "A15" we expose to the guest is not an exact match to the real hardware, that it's missing certain features (and hopefully that the lack of those features is advertised via the feature registers). So the question is where you draw the line...
I'd be inclined to say that, at least for kvm, you should draw the line at the point where the guest doesn't need modifications to run in the virtual environment. That is, everything used by Linux is emulated enough for the kernel to run happily. Clearly you can improve on that in the areas which are considered to be most critical.
Aside: given that guests have to run non-secure, how would you emulate a secure platform without emulating the corresponding TrustZone API? Or is that one of the reasons why you're currently targetting Versatile Express?
Will
PATCH 1/1 ARM: test for PMU feature on v7 (v2 with typo fix)
In reply to Will DeaconQuoted 1 line · Will Deacon
[removed some dead email addresses from CC]
Thanks!
Quoted 11 lines · Rusty Russell
Quoted 3 lines
I had assumed that as we trend towards a common cross-platform kernel, we should be relying on feature registers where available, not the model.
The PMU is very tightly coupled with the CPU and it is necessary to know exactly which CPU you have so that you can map microarchitectural events to their identifiers. This is not discoverable in the architecture [PMUv2 provides some support for discovering the status of architected events, but that is still not enough and is only present on A7 and A15 so far] so that's why we probe the CPU instead.
OK.
Quoted 5 lines
Now, if everything was device-tree based then we could simply use a different binding for each CPU but since we support perf on non-DT platforms, probing the CPU type is the best solution. I would like to avoid the probing code if we are initialised from DT, but I've not got round to it yet (this would be useful for big.LITTLE).
I'll be interested to see how you encode the mapping of microarchitectural events to their identifiers here.
Quoted 5 lines
Quoted 5 lines
Quoted 4 lines
Would you be able to advertise 0 event counters instead and treat the PMU largely as RAZ/WI? The only tricky bit I can see is the cycle counter, which is mandated by the presence of a PMU, however this could also just RAZ initially.
Quoted 7 lines
Quoted 2 lines
Yes, that's the effect of the current emulation hack. Far better not to lie to the guest, however, than get weird results from profiling.
I'd rather lie to the guest than modify it just to avoid emulating the device correctly. Even then, the profiling results wouldn't be especially weird -- everything would be 0, which is a lot better than random numbers.
Sure, but nowhere as neat an experience as having "no hardware support available" printed, and nicely defined failure mode :(
When I get back in May, I'll look at how hard it will to be implement this properly, if noone else does.
Thanks,
Rusty.
Signature · 1 line
How could I marry someone with more hair than me? http://baldalex.org
PATCH 1/1 ARM: test for PMU feature on v7 (v2 with typo fix)
In reply to Will DeaconQuoted 5 lines · Will Deacon
Now, if everything was device-tree based then we could simply use a different binding for each CPU but since we support perf on non-DT platforms, probing the CPU type is the best solution. I would like to avoid the probing code if we are initialised from DT, but I've not got round to it yet (this would be useful for big.LITTLE).
Still... my opinion is that we should try to autodetect as much as possible and avoid overstuffing the DT with content that can otherwise be run-time probed. OK to use DT to override the probe for corner cases, but IMHO the probe should be the default method of initialization. The rational is that we want to spread knowledge about part of the system and have it confined into respective drivers and subsystems for easier maintenance. If the guy who has to maintain the dts has to know all the details for everything then that won't scale and the risk for discrepancies is increased.
Nicolas
PATCH 1/1 ARM: test for PMU feature on v7 (v2 with typo fix)
Hi Nicolas,
Quoted 8 lines · Nicolas Pitre
Quoted 5 lines · Will Deacon
Now, if everything was device-tree based then we could simply use a different binding for each CPU but since we support perf on non-DT platforms, probing the CPU type is the best solution. I would like to avoid the probing code if we are initialised from DT, but I've not got round to it yet (this would be useful for big.LITTLE).
Quoted 9 lines
Still... my opinion is that we should try to autodetect as much as possible and avoid overstuffing the DT with content that can otherwise be run-time probed. OK to use DT to override the probe for corner cases, but IMHO the probe should be the default method of initialization. The rational is that we want to spread knowledge about part of the system and have it confined into respective drivers and subsystems for easier maintenance. If the guy who has to maintain the dts has to know all the details for everything then that won't scale and the risk for discrepancies is increased.
I agree that probing is preferable where possible but, since the PMUs are banked, we cannot reliably probe them on big.LITTLE platforms. I guess if there were some infrastructure for probing on the remote cluster, I could use that, but it seems like DT would be easier.
Will
PATCH 1/1 ARM: test for PMU feature on v7 (v2 with typo fix)
Quoted 21 lines · Will Deacon
Hi Nicolas,
Quoted 8 lines · Nicolas Pitre
Quoted 5 lines · Will Deacon
Now, if everything was device-tree based then we could simply use a different binding for each CPU but since we support perf on non-DT platforms, probing the CPU type is the best solution. I would like to avoid the probing code if we are initialised from DT, but I've not got round to it yet (this would be useful for big.LITTLE).
Quoted 9 lines
Still... my opinion is that we should try to autodetect as much as possible and avoid overstuffing the DT with content that can otherwise be run-time probed. OK to use DT to override the probe for corner cases, but IMHO the probe should be the default method of initialization. The rational is that we want to spread knowledge about part of the system and have it confined into respective drivers and subsystems for easier maintenance. If the guy who has to maintain the dts has to know all the details for everything then that won't scale and the risk for discrepancies is increased.
Quoted 2 lines
I agree that probing is preferable where possible but, since the PMUs are banked, we cannot reliably probe them on big.LITTLE platforms.
Are they tied to each cluster power domains? If so you'll have to preserve/restore their state when clusters are suspended even if the interface tries to present a consistent view to users. The probe can be done there, and differences in capabilities adjusted dynamically.
Nicolas
PATCH 1/1 ARM: KVM: Emulate ID_DFR0 to say we don't support anything.
In reply to Rusty RussellThe guest should be checking this before trying to use performance monitors, for example.
arch/arm/kvm/emulate.c +12 -0
@@ -238,6 +238,15 @@ static bool read_l2ctlr(struct kvm_vcpu *vcpu,return true; } +static bool read_id_dfr0 (struct kvm_vcpu *vcpu, +const struct coproc_params *p, +unsigned long arg) +{ +/* We support no performance monitors (27-24 = b1111) and no debug */ + *vcpu_reg (vcpu, p->Rt1) =0x0F000000 ; +return true; +} +static bool access_cp15_reg (struct kvm_vcpu *vcpu,const struct coproc_params *p,unsigned long cp15_reg)
@@ -277,6 +286,9 @@ struct coproc_emulate {#define RW .is_w = DFstatic const struct coproc_emulate coproc_emulate[] = { +/* ID_DFR0 (guest asks what PMU/debug we support) */ + {CRn (0 ),CRm (1 ),Op1 (0 ),Op2 (2 ), is32,READ , read_id_dfr0}, +/* * L2CTLR access: *
Re: [Android-virt] [PATCH] ARM: KVM: Emulate ID_DFR0 to say we don't support anything.
Quoted 4 lines · Rusty Russell
The guest should be checking this before trying to use performance monitors, for example.
Signed-off-by Rusty Russell <[email protected]>
Does this code get used currently? I thought we hadn't enabled trapping for feature register reads because of that use of one of the MMFR registers in a hot path for page allocation...
-- PMM
Re: [Android-virt] [PATCH] ARM: KVM: Emulate ID_DFR0 to say we don't support anything.
Quoted 9 lines · Peter Maydell
Quoted 4 lines · Rusty Russell
The guest should be checking this before trying to use performance monitors, for example.
Signed-off-by Rusty Russell <[email protected]>Does this code get used currently? I thought we hadn't enabled trapping for feature register reads because of that use of one of the MMFR registers in a hot path for page allocation...
True (I mis-labelled the patches, they should have been RFC, since this is tied to the host-side probing patch).
So maybe not today, but we're going to end up doing this eventually. Everyone expects their virtual machines to work fine with the next model of ARM CPUs, which means we need to hide more and more host features over time.
Cheers,
Rusty.
Signature · 1 line
How could I marry someone with more hair than me? http://baldalex.org