* [PATCH 2/4] powerpc/perf: Add an accessor for regs->result
2013-04-10 8:32 [PATCH 1/4] powerpc/perf: Convert mmcra_sipr/sihv() to regs_sipr/sihv() Michael Ellerman
@ 2013-04-10 8:32 ` Michael Ellerman
2013-04-10 8:32 ` [PATCH 3/4] powerpc/perf: Add regs_no_sipr() Michael Ellerman
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Michael Ellerman @ 2013-04-10 8:32 UTC (permalink / raw)
To: linuxppc-dev; +Cc: sukadev, Paul Mackerras
From: Michael Ellerman <michaele@au1.ibm.com>
Add an accessor for regs->result so we can use it to store more flags in
future.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
arch/powerpc/perf/core-book3s.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index cb1618d..770f359 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -132,6 +132,11 @@ static bool regs_sipr(struct pt_regs *regs)
return !!(regs->dsisr & sipr);
}
+static bool regs_use_siar(struct pt_regs *regs)
+{
+ return !!(regs->result & 1);
+}
+
static inline u32 perf_flags_from_msr(struct pt_regs *regs)
{
if (regs->msr & MSR_PR)
@@ -143,7 +148,7 @@ static inline u32 perf_flags_from_msr(struct pt_regs *regs)
static inline u32 perf_get_misc_flags(struct pt_regs *regs)
{
- unsigned long use_siar = regs->result;
+ bool use_siar = regs_use_siar(regs);
if (!use_siar)
return perf_flags_from_msr(regs);
@@ -1413,7 +1418,7 @@ unsigned long perf_misc_flags(struct pt_regs *regs)
*/
unsigned long perf_instruction_pointer(struct pt_regs *regs)
{
- unsigned long use_siar = regs->result;
+ bool use_siar = regs_use_siar(regs);
if (use_siar && siar_valid(regs))
return mfspr(SPRN_SIAR) + perf_ip_adjust(regs);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/4] powerpc/perf: Add regs_no_sipr()
2013-04-10 8:32 [PATCH 1/4] powerpc/perf: Convert mmcra_sipr/sihv() to regs_sipr/sihv() Michael Ellerman
2013-04-10 8:32 ` [PATCH 2/4] powerpc/perf: Add an accessor for regs->result Michael Ellerman
@ 2013-04-10 8:32 ` Michael Ellerman
2013-04-10 8:32 ` [PATCH 4/4] powerpc/perf: Add support for SIER Michael Ellerman
2013-04-25 17:11 ` [PATCH 1/4] powerpc/perf: Convert mmcra_sipr/sihv() to regs_sipr/sihv() Sukadev Bhattiprolu
3 siblings, 0 replies; 6+ messages in thread
From: Michael Ellerman @ 2013-04-10 8:32 UTC (permalink / raw)
To: linuxppc-dev; +Cc: sukadev, Paul Mackerras
From: Michael Ellerman <michaele@au1.ibm.com>
On power8 the presence or absence of SIPR depends on settings at runtime,
so convert to using a dynamic flag for NO_SIPR. Existing backends that
set NO_SIPR unconditionally set the dynamic flag obviously.
Signed-off-by: Michael Ellerman <michaele@au1.ibm.com>
---
arch/powerpc/perf/core-book3s.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index 770f359..4255b12 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -137,6 +137,11 @@ static bool regs_use_siar(struct pt_regs *regs)
return !!(regs->result & 1);
}
+static bool regs_no_sipr(struct pt_regs *regs)
+{
+ return !!(regs->result & 2);
+}
+
static inline u32 perf_flags_from_msr(struct pt_regs *regs)
{
if (regs->msr & MSR_PR)
@@ -159,7 +164,7 @@ static inline u32 perf_get_misc_flags(struct pt_regs *regs)
* SIAR which should give slightly more reliable
* results
*/
- if (ppmu->flags & PPMU_NO_SIPR) {
+ if (regs_no_sipr(regs)) {
unsigned long siar = mfspr(SPRN_SIAR);
if (siar >= PAGE_OFFSET)
return PERF_RECORD_MISC_KERNEL;
@@ -189,6 +194,10 @@ static inline void perf_read_regs(struct pt_regs *regs)
int use_siar;
regs->dsisr = mmcra;
+ regs->result = 0;
+
+ if (ppmu->flags & PPMU_NO_SIPR)
+ regs->result |= 2;
/*
* If this isn't a PMU exception (eg a software event) the SIAR is
@@ -213,12 +222,12 @@ static inline void perf_read_regs(struct pt_regs *regs)
use_siar = 1;
else if ((ppmu->flags & PPMU_NO_CONT_SAMPLING))
use_siar = 0;
- else if (!(ppmu->flags & PPMU_NO_SIPR) && regs_sipr(regs))
+ else if (!regs_no_sipr(regs) && regs_sipr(regs))
use_siar = 0;
else
use_siar = 1;
- regs->result = use_siar;
+ regs->result |= use_siar;
}
/*
--
1.7.10.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 4/4] powerpc/perf: Add support for SIER
2013-04-10 8:32 [PATCH 1/4] powerpc/perf: Convert mmcra_sipr/sihv() to regs_sipr/sihv() Michael Ellerman
2013-04-10 8:32 ` [PATCH 2/4] powerpc/perf: Add an accessor for regs->result Michael Ellerman
2013-04-10 8:32 ` [PATCH 3/4] powerpc/perf: Add regs_no_sipr() Michael Ellerman
@ 2013-04-10 8:32 ` Michael Ellerman
2013-04-25 18:24 ` Sukadev Bhattiprolu
2013-04-25 17:11 ` [PATCH 1/4] powerpc/perf: Convert mmcra_sipr/sihv() to regs_sipr/sihv() Sukadev Bhattiprolu
3 siblings, 1 reply; 6+ messages in thread
From: Michael Ellerman @ 2013-04-10 8:32 UTC (permalink / raw)
To: linuxppc-dev; +Cc: sukadev, Paul Mackerras
From: Michael Ellerman <michaele@au1.ibm.com>
On power8 we have a new SIER (Sampled Instruction Event Register), which
captures information about instructions when we have random sampling
enabled.
Add support for loading the SIER into pt_regs, overloading regs->dar.
Also set the new NO_SIPR flag in regs->result if we don't have SIPR.
Update regs_sihv/sipr() to look for SIPR/SIHV in SIER.
Signed-off-by: Michael Ellerman <michaele@au1.ibm.com>
---
arch/powerpc/include/asm/perf_event_server.h | 1 +
arch/powerpc/perf/core-book3s.c | 19 +++++++++++++++++++
2 files changed, 20 insertions(+)
diff --git a/arch/powerpc/include/asm/perf_event_server.h b/arch/powerpc/include/asm/perf_event_server.h
index e287aef..a1a1ad8 100644
--- a/arch/powerpc/include/asm/perf_event_server.h
+++ b/arch/powerpc/include/asm/perf_event_server.h
@@ -53,6 +53,7 @@ struct power_pmu {
#define PPMU_NO_CONT_SAMPLING 0x00000008 /* no continuous sampling */
#define PPMU_SIAR_VALID 0x00000010 /* Processor has SIAR Valid bit */
#define PPMU_HAS_SSLOT 0x00000020 /* Has sampled slot in MMCRA */
+#define PPMU_HAS_SIER 0x00000040 /* Has SIER */
/*
* Values for flags to get_alternatives()
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index 4255b12..a4bbd4d 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -116,6 +116,9 @@ static bool regs_sihv(struct pt_regs *regs)
{
unsigned long sihv = MMCRA_SIHV;
+ if (ppmu->flags & PPMU_HAS_SIER)
+ return !!(regs->dar & SIER_SIHV);
+
if (ppmu->flags & PPMU_ALT_SIPR)
sihv = POWER6_MMCRA_SIHV;
@@ -126,6 +129,9 @@ static bool regs_sipr(struct pt_regs *regs)
{
unsigned long sipr = MMCRA_SIPR;
+ if (ppmu->flags & PPMU_HAS_SIER)
+ return !!(regs->dar & SIER_SIPR);
+
if (ppmu->flags & PPMU_ALT_SIPR)
sipr = POWER6_MMCRA_SIPR;
@@ -184,6 +190,7 @@ static inline u32 perf_get_misc_flags(struct pt_regs *regs)
/*
* Overload regs->dsisr to store MMCRA so we only need to read it once
* on each interrupt.
+ * Overload regs->dar to store SIER if we have it.
* Overload regs->result to specify whether we should use the MSR (result
* is zero) or the SIAR (result is non zero).
*/
@@ -200,6 +207,18 @@ static inline void perf_read_regs(struct pt_regs *regs)
regs->result |= 2;
/*
+ * On power8 if we're in random sampling mode, the SIER is updated.
+ * If we're in continuous sampling mode, we don't have SIPR.
+ */
+ if (ppmu->flags & PPMU_HAS_SIER) {
+ if (marked)
+ regs->dar = mfspr(SPRN_SIER);
+ else
+ regs->result |= 2;
+ }
+
+
+ /*
* If this isn't a PMU exception (eg a software event) the SIAR is
* not valid. Use pt_regs.
*
--
1.7.10.4
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 4/4] powerpc/perf: Add support for SIER
2013-04-10 8:32 ` [PATCH 4/4] powerpc/perf: Add support for SIER Michael Ellerman
@ 2013-04-25 18:24 ` Sukadev Bhattiprolu
0 siblings, 0 replies; 6+ messages in thread
From: Sukadev Bhattiprolu @ 2013-04-25 18:24 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, Paul Mackerras
Michael Ellerman [michael@ellerman.id.au] wrote:
| From: Michael Ellerman <michaele@au1.ibm.com>
|
| On power8 we have a new SIER (Sampled Instruction Event Register), which
| captures information about instructions when we have random sampling
| enabled.
|
| Add support for loading the SIER into pt_regs, overloading regs->dar.
| Also set the new NO_SIPR flag in regs->result if we don't have SIPR.
|
| Update regs_sihv/sipr() to look for SIPR/SIHV in SIER.
|
| Signed-off-by: Michael Ellerman <michaele@au1.ibm.com>
| ---
| arch/powerpc/include/asm/perf_event_server.h | 1 +
| arch/powerpc/perf/core-book3s.c | 19 +++++++++++++++++++
| 2 files changed, 20 insertions(+)
|
| diff --git a/arch/powerpc/include/asm/perf_event_server.h b/arch/powerpc/include/asm/perf_event_server.h
| index e287aef..a1a1ad8 100644
| --- a/arch/powerpc/include/asm/perf_event_server.h
| +++ b/arch/powerpc/include/asm/perf_event_server.h
| @@ -53,6 +53,7 @@ struct power_pmu {
| #define PPMU_NO_CONT_SAMPLING 0x00000008 /* no continuous sampling */
| #define PPMU_SIAR_VALID 0x00000010 /* Processor has SIAR Valid bit */
| #define PPMU_HAS_SSLOT 0x00000020 /* Has sampled slot in MMCRA */
| +#define PPMU_HAS_SIER 0x00000040 /* Has SIER */
|
| /*
| * Values for flags to get_alternatives()
| diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
| index 4255b12..a4bbd4d 100644
| --- a/arch/powerpc/perf/core-book3s.c
| +++ b/arch/powerpc/perf/core-book3s.c
| @@ -116,6 +116,9 @@ static bool regs_sihv(struct pt_regs *regs)
| {
| unsigned long sihv = MMCRA_SIHV;
|
| + if (ppmu->flags & PPMU_HAS_SIER)
| + return !!(regs->dar & SIER_SIHV);
| +
Were SIER_SIHV and SIER_SIPR defined in an earlier patch set ?
| if (ppmu->flags & PPMU_ALT_SIPR)
| sihv = POWER6_MMCRA_SIHV;
|
| @@ -126,6 +129,9 @@ static bool regs_sipr(struct pt_regs *regs)
| {
| unsigned long sipr = MMCRA_SIPR;
|
| + if (ppmu->flags & PPMU_HAS_SIER)
| + return !!(regs->dar & SIER_SIPR);
| +
| if (ppmu->flags & PPMU_ALT_SIPR)
| sipr = POWER6_MMCRA_SIPR;
|
| @@ -184,6 +190,7 @@ static inline u32 perf_get_misc_flags(struct pt_regs *regs)
| /*
| * Overload regs->dsisr to store MMCRA so we only need to read it once
| * on each interrupt.
| + * Overload regs->dar to store SIER if we have it.
| * Overload regs->result to specify whether we should use the MSR (result
| * is zero) or the SIAR (result is non zero).
| */
| @@ -200,6 +207,18 @@ static inline void perf_read_regs(struct pt_regs *regs)
| regs->result |= 2;
|
| /*
| + * On power8 if we're in random sampling mode, the SIER is updated.
| + * If we're in continuous sampling mode, we don't have SIPR.
| + */
| + if (ppmu->flags & PPMU_HAS_SIER) {
| + if (marked)
| + regs->dar = mfspr(SPRN_SIER);
| + else
| + regs->result |= 2;
Can we use a helper, regs_set_no_sipr() to set this - since we set and
test in more than one place ?
Other than these nits, the patchset looks good.
Sukadev
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/4] powerpc/perf: Convert mmcra_sipr/sihv() to regs_sipr/sihv()
2013-04-10 8:32 [PATCH 1/4] powerpc/perf: Convert mmcra_sipr/sihv() to regs_sipr/sihv() Michael Ellerman
` (2 preceding siblings ...)
2013-04-10 8:32 ` [PATCH 4/4] powerpc/perf: Add support for SIER Michael Ellerman
@ 2013-04-25 17:11 ` Sukadev Bhattiprolu
3 siblings, 0 replies; 6+ messages in thread
From: Sukadev Bhattiprolu @ 2013-04-25 17:11 UTC (permalink / raw)
To: Michael Ellerman; +Cc: linuxppc-dev, Paul Mackerras
Michael Ellerman [michael@ellerman.id.au] wrote:
| From: Michael Ellerman <michaele@au1.ibm.com>
|
| On power8 the SIPR and SIHV are not in MMCRA, so convert the routines
| to take regs and change the names accordingly.
|
| Signed-off-by: Michael Ellerman <michaele@au1.ibm.com>
| ---
| arch/powerpc/perf/core-book3s.c | 20 +++++++++++---------
| 1 file changed, 11 insertions(+), 9 deletions(-)
|
| diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
| index fcfafa0..cb1618d 100644
| --- a/arch/powerpc/perf/core-book3s.c
| +++ b/arch/powerpc/perf/core-book3s.c
| @@ -112,24 +112,24 @@ static inline void perf_get_data_addr(struct pt_regs *regs, u64 *addrp)
| *addrp = mfspr(SPRN_SDAR);
| }
|
| -static bool mmcra_sihv(unsigned long mmcra)
| +static bool regs_sihv(struct pt_regs *regs)
| {
| unsigned long sihv = MMCRA_SIHV;
|
| if (ppmu->flags & PPMU_ALT_SIPR)
| sihv = POWER6_MMCRA_SIHV;
|
| - return !!(mmcra & sihv);
| + return !!(regs->dsisr & sihv);
| }
|
| -static bool mmcra_sipr(unsigned long mmcra)
| +static bool regs_sipr(struct pt_regs *regs)
| {
| unsigned long sipr = MMCRA_SIPR;
|
Would it make sense to add this here:
if (ppmu->flags & PPMU_NO_SIPR)
return 0;
so ....
| if (ppmu->flags & PPMU_ALT_SIPR)
| sipr = POWER6_MMCRA_SIPR;
|
| - return !!(mmcra & sipr);
| + return !!(regs->dsisr & sipr);
| }
|
| static inline u32 perf_flags_from_msr(struct pt_regs *regs)
| @@ -143,7 +143,6 @@ static inline u32 perf_flags_from_msr(struct pt_regs *regs)
|
| static inline u32 perf_get_misc_flags(struct pt_regs *regs)
| {
| - unsigned long mmcra = regs->dsisr;
| unsigned long use_siar = regs->result;
|
| if (!use_siar)
| @@ -163,10 +162,12 @@ static inline u32 perf_get_misc_flags(struct pt_regs *regs)
| }
|
| /* PR has priority over HV, so order below is important */
| - if (mmcra_sipr(mmcra))
| + if (regs_sipr(regs))
| return PERF_RECORD_MISC_USER;
| - if (mmcra_sihv(mmcra) && (freeze_events_kernel != MMCR0_FCHV))
| +
| + if (regs_sihv(regs) && (freeze_events_kernel != MMCR0_FCHV))
| return PERF_RECORD_MISC_HYPERVISOR;
| +
| return PERF_RECORD_MISC_KERNEL;
| }
|
| @@ -182,6 +183,8 @@ static inline void perf_read_regs(struct pt_regs *regs)
| int marked = mmcra & MMCRA_SAMPLE_ENABLE;
| int use_siar;
|
| + regs->dsisr = mmcra;
| +
| /*
| * If this isn't a PMU exception (eg a software event) the SIAR is
| * not valid. Use pt_regs.
| @@ -205,12 +208,11 @@ static inline void perf_read_regs(struct pt_regs *regs)
| use_siar = 1;
| else if ((ppmu->flags & PPMU_NO_CONT_SAMPLING))
| use_siar = 0;
| - else if (!(ppmu->flags & PPMU_NO_SIPR) && mmcra_sipr(mmcra))
| + else if (!(ppmu->flags & PPMU_NO_SIPR) && regs_sipr(regs))
... this becomes
else if (regs_sipr(regs))
mmcra_sipr() is used currently in two places and both places check
the NO_SIPR flag.
The reason is that this line gets modified in PATCH 3/4 to:
else if (!regs_no_sipr(regs) && regs_sipr(regs))
which is kind of hard to read. if (!not_X && X)
Sukadev
^ permalink raw reply [flat|nested] 6+ messages in thread