mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-04-19 04:37:30 +07:00
powerpc/perf: Move BHRB code into CONFIG_PPC64 region
The new Branch History Rolling buffer (BHRB) code is only useful on 64bit processors, so move it into the #ifdef CONFIG_PPC64 region. This avoids code bloat on 32bit systems. Signed-off-by: Michael Neuling <mikey@neuling.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
This commit is contained in:
parent
a1797b2fd2
commit
d52f2dc40b
@ -100,6 +100,10 @@ static inline int siar_valid(struct pt_regs *regs)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void power_pmu_bhrb_enable(struct perf_event *event) {}
|
||||||
|
static inline void power_pmu_bhrb_disable(struct perf_event *event) {}
|
||||||
|
void power_pmu_flush_branch_stack(void) {}
|
||||||
|
static inline void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw) {}
|
||||||
#endif /* CONFIG_PPC32 */
|
#endif /* CONFIG_PPC32 */
|
||||||
|
|
||||||
static bool regs_use_siar(struct pt_regs *regs)
|
static bool regs_use_siar(struct pt_regs *regs)
|
||||||
@ -308,6 +312,129 @@ static inline int siar_valid(struct pt_regs *regs)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Reset all possible BHRB entries */
|
||||||
|
static void power_pmu_bhrb_reset(void)
|
||||||
|
{
|
||||||
|
asm volatile(PPC_CLRBHRB);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void power_pmu_bhrb_enable(struct perf_event *event)
|
||||||
|
{
|
||||||
|
struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
|
||||||
|
|
||||||
|
if (!ppmu->bhrb_nr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Clear BHRB if we changed task context to avoid data leaks */
|
||||||
|
if (event->ctx->task && cpuhw->bhrb_context != event->ctx) {
|
||||||
|
power_pmu_bhrb_reset();
|
||||||
|
cpuhw->bhrb_context = event->ctx;
|
||||||
|
}
|
||||||
|
cpuhw->bhrb_users++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void power_pmu_bhrb_disable(struct perf_event *event)
|
||||||
|
{
|
||||||
|
struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
|
||||||
|
|
||||||
|
if (!ppmu->bhrb_nr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cpuhw->bhrb_users--;
|
||||||
|
WARN_ON_ONCE(cpuhw->bhrb_users < 0);
|
||||||
|
|
||||||
|
if (!cpuhw->disabled && !cpuhw->bhrb_users) {
|
||||||
|
/* BHRB cannot be turned off when other
|
||||||
|
* events are active on the PMU.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* avoid stale pointer */
|
||||||
|
cpuhw->bhrb_context = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called from ctxsw to prevent one process's branch entries to
|
||||||
|
* mingle with the other process's entries during context switch.
|
||||||
|
*/
|
||||||
|
void power_pmu_flush_branch_stack(void)
|
||||||
|
{
|
||||||
|
if (ppmu->bhrb_nr)
|
||||||
|
power_pmu_bhrb_reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Processing BHRB entries */
|
||||||
|
static void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw)
|
||||||
|
{
|
||||||
|
u64 val;
|
||||||
|
u64 addr;
|
||||||
|
int r_index, u_index, target, pred;
|
||||||
|
|
||||||
|
r_index = 0;
|
||||||
|
u_index = 0;
|
||||||
|
while (r_index < ppmu->bhrb_nr) {
|
||||||
|
/* Assembly read function */
|
||||||
|
val = read_bhrb(r_index);
|
||||||
|
|
||||||
|
/* Terminal marker: End of valid BHRB entries */
|
||||||
|
if (val == 0) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
/* BHRB field break up */
|
||||||
|
addr = val & BHRB_EA;
|
||||||
|
pred = val & BHRB_PREDICTION;
|
||||||
|
target = val & BHRB_TARGET;
|
||||||
|
|
||||||
|
/* Probable Missed entry: Not applicable for POWER8 */
|
||||||
|
if ((addr == 0) && (target == 0) && (pred == 1)) {
|
||||||
|
r_index++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Real Missed entry: Power8 based missed entry */
|
||||||
|
if ((addr == 0) && (target == 1) && (pred == 1)) {
|
||||||
|
r_index++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reserved condition: Not a valid entry */
|
||||||
|
if ((addr == 0) && (target == 1) && (pred == 0)) {
|
||||||
|
r_index++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is a target address */
|
||||||
|
if (val & BHRB_TARGET) {
|
||||||
|
/* First address cannot be a target address */
|
||||||
|
if (r_index == 0) {
|
||||||
|
r_index++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update target address for the previous entry */
|
||||||
|
cpuhw->bhrb_entries[u_index - 1].to = addr;
|
||||||
|
cpuhw->bhrb_entries[u_index - 1].mispred = pred;
|
||||||
|
cpuhw->bhrb_entries[u_index - 1].predicted = ~pred;
|
||||||
|
|
||||||
|
/* Dont increment u_index */
|
||||||
|
r_index++;
|
||||||
|
} else {
|
||||||
|
/* Update address, flags for current entry */
|
||||||
|
cpuhw->bhrb_entries[u_index].from = addr;
|
||||||
|
cpuhw->bhrb_entries[u_index].mispred = pred;
|
||||||
|
cpuhw->bhrb_entries[u_index].predicted = ~pred;
|
||||||
|
|
||||||
|
/* Successfully popullated one entry */
|
||||||
|
u_index++;
|
||||||
|
r_index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cpuhw->bhrb_stack.nr = u_index;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_PPC64 */
|
#endif /* CONFIG_PPC64 */
|
||||||
|
|
||||||
static void perf_event_interrupt(struct pt_regs *regs);
|
static void perf_event_interrupt(struct pt_regs *regs);
|
||||||
@ -904,47 +1031,6 @@ static int collect_events(struct perf_event *group, int max_count,
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reset all possible BHRB entries */
|
|
||||||
static void power_pmu_bhrb_reset(void)
|
|
||||||
{
|
|
||||||
asm volatile(PPC_CLRBHRB);
|
|
||||||
}
|
|
||||||
|
|
||||||
void power_pmu_bhrb_enable(struct perf_event *event)
|
|
||||||
{
|
|
||||||
struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
|
|
||||||
|
|
||||||
if (!ppmu->bhrb_nr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Clear BHRB if we changed task context to avoid data leaks */
|
|
||||||
if (event->ctx->task && cpuhw->bhrb_context != event->ctx) {
|
|
||||||
power_pmu_bhrb_reset();
|
|
||||||
cpuhw->bhrb_context = event->ctx;
|
|
||||||
}
|
|
||||||
cpuhw->bhrb_users++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void power_pmu_bhrb_disable(struct perf_event *event)
|
|
||||||
{
|
|
||||||
struct cpu_hw_events *cpuhw = &__get_cpu_var(cpu_hw_events);
|
|
||||||
|
|
||||||
if (!ppmu->bhrb_nr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
cpuhw->bhrb_users--;
|
|
||||||
WARN_ON_ONCE(cpuhw->bhrb_users < 0);
|
|
||||||
|
|
||||||
if (!cpuhw->disabled && !cpuhw->bhrb_users) {
|
|
||||||
/* BHRB cannot be turned off when other
|
|
||||||
* events are active on the PMU.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* avoid stale pointer */
|
|
||||||
cpuhw->bhrb_context = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add a event to the PMU.
|
* Add a event to the PMU.
|
||||||
* If all events are not already frozen, then we disable and
|
* If all events are not already frozen, then we disable and
|
||||||
@ -1180,15 +1266,6 @@ int power_pmu_commit_txn(struct pmu *pmu)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called from ctxsw to prevent one process's branch entries to
|
|
||||||
* mingle with the other process's entries during context switch.
|
|
||||||
*/
|
|
||||||
void power_pmu_flush_branch_stack(void)
|
|
||||||
{
|
|
||||||
if (ppmu->bhrb_nr)
|
|
||||||
power_pmu_bhrb_reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return 1 if we might be able to put event on a limited PMC,
|
* Return 1 if we might be able to put event on a limited PMC,
|
||||||
* or 0 if not.
|
* or 0 if not.
|
||||||
@ -1458,77 +1535,6 @@ struct pmu power_pmu = {
|
|||||||
.flush_branch_stack = power_pmu_flush_branch_stack,
|
.flush_branch_stack = power_pmu_flush_branch_stack,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Processing BHRB entries */
|
|
||||||
void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw)
|
|
||||||
{
|
|
||||||
u64 val;
|
|
||||||
u64 addr;
|
|
||||||
int r_index, u_index, target, pred;
|
|
||||||
|
|
||||||
r_index = 0;
|
|
||||||
u_index = 0;
|
|
||||||
while (r_index < ppmu->bhrb_nr) {
|
|
||||||
/* Assembly read function */
|
|
||||||
val = read_bhrb(r_index);
|
|
||||||
|
|
||||||
/* Terminal marker: End of valid BHRB entries */
|
|
||||||
if (val == 0) {
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
/* BHRB field break up */
|
|
||||||
addr = val & BHRB_EA;
|
|
||||||
pred = val & BHRB_PREDICTION;
|
|
||||||
target = val & BHRB_TARGET;
|
|
||||||
|
|
||||||
/* Probable Missed entry: Not applicable for POWER8 */
|
|
||||||
if ((addr == 0) && (target == 0) && (pred == 1)) {
|
|
||||||
r_index++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Real Missed entry: Power8 based missed entry */
|
|
||||||
if ((addr == 0) && (target == 1) && (pred == 1)) {
|
|
||||||
r_index++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reserved condition: Not a valid entry */
|
|
||||||
if ((addr == 0) && (target == 1) && (pred == 0)) {
|
|
||||||
r_index++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Is a target address */
|
|
||||||
if (val & BHRB_TARGET) {
|
|
||||||
/* First address cannot be a target address */
|
|
||||||
if (r_index == 0) {
|
|
||||||
r_index++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update target address for the previous entry */
|
|
||||||
cpuhw->bhrb_entries[u_index - 1].to = addr;
|
|
||||||
cpuhw->bhrb_entries[u_index - 1].mispred = pred;
|
|
||||||
cpuhw->bhrb_entries[u_index - 1].predicted = ~pred;
|
|
||||||
|
|
||||||
/* Dont increment u_index */
|
|
||||||
r_index++;
|
|
||||||
} else {
|
|
||||||
/* Update address, flags for current entry */
|
|
||||||
cpuhw->bhrb_entries[u_index].from = addr;
|
|
||||||
cpuhw->bhrb_entries[u_index].mispred = pred;
|
|
||||||
cpuhw->bhrb_entries[u_index].predicted = ~pred;
|
|
||||||
|
|
||||||
/* Successfully popullated one entry */
|
|
||||||
u_index++;
|
|
||||||
r_index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cpuhw->bhrb_stack.nr = u_index;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A counter has overflowed; update its count and record
|
* A counter has overflowed; update its count and record
|
||||||
* things if requested. Note that interrupts are hard-disabled
|
* things if requested. Note that interrupts are hard-disabled
|
||||||
|
Loading…
Reference in New Issue
Block a user