Commit cbf6948f authored by Pu Hou's avatar Pu Hou Committed by Martin Schwidefsky

s390/cpumf: enable using AUX buffer

Modify PMU callback to use AUX buffer for diagnostic mode sampling.
Basic-mode sampling still use orignal way.
Signed-off-by: default avatarPu Hou <bjhoupu@linux.vnet.ibm.com>
Reviewed-by: default avatarHendrik Brueckner <brueckner@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent ca5955cd
...@@ -780,6 +780,10 @@ static int __hw_perf_event_init(struct perf_event *event) ...@@ -780,6 +780,10 @@ static int __hw_perf_event_init(struct perf_event *event)
hwc->extra_reg.reg = REG_OVERFLOW; hwc->extra_reg.reg = REG_OVERFLOW;
OVERFLOW_REG(hwc) = 0; OVERFLOW_REG(hwc) = 0;
/* Use AUX buffer. No need to allocate it by ourself */
if (attr->config == PERF_EVENT_CPUM_SF_DIAG)
return 0;
/* Allocate the per-CPU sampling buffer using the CPU information /* Allocate the per-CPU sampling buffer using the CPU information
* from the event. If the event is not pinned to a particular * from the event. If the event is not pinned to a particular
* CPU (event->cpu == -1; or cpuhw == NULL), allocate sampling * CPU (event->cpu == -1; or cpuhw == NULL), allocate sampling
...@@ -876,11 +880,16 @@ static void cpumsf_pmu_enable(struct pmu *pmu) ...@@ -876,11 +880,16 @@ static void cpumsf_pmu_enable(struct pmu *pmu)
*/ */
if (cpuhw->event) { if (cpuhw->event) {
hwc = &cpuhw->event->hw; hwc = &cpuhw->event->hw;
/* Account number of overflow-designated buffer extents */ if (!(SAMPL_DIAG_MODE(hwc))) {
/*
* Account number of overflow-designated
* buffer extents
*/
sfb_account_overflows(cpuhw, hwc); sfb_account_overflows(cpuhw, hwc);
if (sfb_has_pending_allocs(&cpuhw->sfb, hwc)) if (sfb_has_pending_allocs(&cpuhw->sfb, hwc))
extend_sampling_buffer(&cpuhw->sfb, hwc); extend_sampling_buffer(&cpuhw->sfb, hwc);
} }
}
/* (Re)enable the PMU and sampling facility */ /* (Re)enable the PMU and sampling facility */
cpuhw->flags |= PMU_F_ENABLED; cpuhw->flags |= PMU_F_ENABLED;
...@@ -1225,6 +1234,13 @@ static void hw_perf_event_update(struct perf_event *event, int flush_all) ...@@ -1225,6 +1234,13 @@ static void hw_perf_event_update(struct perf_event *event, int flush_all)
unsigned long long event_overflow, sampl_overflow, num_sdb, te_flags; unsigned long long event_overflow, sampl_overflow, num_sdb, te_flags;
int done; int done;
/*
* AUX buffer is used when in diagnostic sampling mode.
* No perf events/samples are created.
*/
if (SAMPL_DIAG_MODE(&event->hw))
return;
if (flush_all && SDB_FULL_BLOCKS(hwc)) if (flush_all && SDB_FULL_BLOCKS(hwc))
flush_all = 0; flush_all = 0;
...@@ -1785,12 +1801,13 @@ static void cpumsf_pmu_stop(struct perf_event *event, int flags) ...@@ -1785,12 +1801,13 @@ static void cpumsf_pmu_stop(struct perf_event *event, int flags)
static int cpumsf_pmu_add(struct perf_event *event, int flags) static int cpumsf_pmu_add(struct perf_event *event, int flags)
{ {
struct cpu_hw_sf *cpuhw = this_cpu_ptr(&cpu_hw_sf); struct cpu_hw_sf *cpuhw = this_cpu_ptr(&cpu_hw_sf);
struct aux_buffer *aux;
int err; int err;
if (cpuhw->flags & PMU_F_IN_USE) if (cpuhw->flags & PMU_F_IN_USE)
return -EAGAIN; return -EAGAIN;
if (!cpuhw->sfb.sdbt) if (!SAMPL_DIAG_MODE(&event->hw) && !cpuhw->sfb.sdbt)
return -EINVAL; return -EINVAL;
err = 0; err = 0;
...@@ -1805,10 +1822,12 @@ static int cpumsf_pmu_add(struct perf_event *event, int flags) ...@@ -1805,10 +1822,12 @@ static int cpumsf_pmu_add(struct perf_event *event, int flags)
*/ */
cpuhw->lsctl.s = 0; cpuhw->lsctl.s = 0;
cpuhw->lsctl.h = 1; cpuhw->lsctl.h = 1;
cpuhw->lsctl.interval = SAMPL_RATE(&event->hw);
if (!SAMPL_DIAG_MODE(&event->hw)) {
cpuhw->lsctl.tear = (unsigned long) cpuhw->sfb.sdbt; cpuhw->lsctl.tear = (unsigned long) cpuhw->sfb.sdbt;
cpuhw->lsctl.dear = *(unsigned long *) cpuhw->sfb.sdbt; cpuhw->lsctl.dear = *(unsigned long *) cpuhw->sfb.sdbt;
cpuhw->lsctl.interval = SAMPL_RATE(&event->hw);
hw_reset_registers(&event->hw, cpuhw->sfb.sdbt); hw_reset_registers(&event->hw, cpuhw->sfb.sdbt);
}
/* Ensure sampling functions are in the disabled state. If disabled, /* Ensure sampling functions are in the disabled state. If disabled,
* switch on sampling enable control. */ * switch on sampling enable control. */
...@@ -1816,9 +1835,18 @@ static int cpumsf_pmu_add(struct perf_event *event, int flags) ...@@ -1816,9 +1835,18 @@ static int cpumsf_pmu_add(struct perf_event *event, int flags)
err = -EAGAIN; err = -EAGAIN;
goto out; goto out;
} }
cpuhw->lsctl.es = 1; if (SAMPL_DIAG_MODE(&event->hw)) {
if (SAMPL_DIAG_MODE(&event->hw)) aux = perf_aux_output_begin(&cpuhw->handle, event);
if (!aux) {
err = -EINVAL;
goto out;
}
err = aux_output_begin(&cpuhw->handle, aux, cpuhw);
if (err)
goto out;
cpuhw->lsctl.ed = 1; cpuhw->lsctl.ed = 1;
}
cpuhw->lsctl.es = 1;
/* Set in_use flag and store event */ /* Set in_use flag and store event */
cpuhw->event = event; cpuhw->event = event;
...@@ -1844,6 +1872,8 @@ static void cpumsf_pmu_del(struct perf_event *event, int flags) ...@@ -1844,6 +1872,8 @@ static void cpumsf_pmu_del(struct perf_event *event, int flags)
cpuhw->flags &= ~PMU_F_IN_USE; cpuhw->flags &= ~PMU_F_IN_USE;
cpuhw->event = NULL; cpuhw->event = NULL;
if (SAMPL_DIAG_MODE(&event->hw))
aux_output_end(&cpuhw->handle);
perf_event_update_userpage(event); perf_event_update_userpage(event);
perf_pmu_enable(event->pmu); perf_pmu_enable(event->pmu);
} }
...@@ -1917,6 +1947,9 @@ static void cpumf_measurement_alert(struct ext_code ext_code, ...@@ -1917,6 +1947,9 @@ static void cpumf_measurement_alert(struct ext_code ext_code,
/* Program alert request */ /* Program alert request */
if (alert & CPU_MF_INT_SF_PRA) { if (alert & CPU_MF_INT_SF_PRA) {
if (cpuhw->flags & PMU_F_IN_USE) if (cpuhw->flags & PMU_F_IN_USE)
if (SAMPL_DIAG_MODE(&cpuhw->event->hw))
hw_collect_aux(cpuhw);
else
hw_perf_event_update(cpuhw->event, 0); hw_perf_event_update(cpuhw->event, 0);
else else
WARN_ON_ONCE(!(cpuhw->flags & PMU_F_IN_USE)); WARN_ON_ONCE(!(cpuhw->flags & PMU_F_IN_USE));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment