forked from Minki/linux
s390/cpumf: remove counter transaction call backs
The command 'perf stat -e cycles ...' triggers the following function sequence in the CPU Measurement Facility counter device driver: perf_pmu_event_init() __hw_perf_event_init() validate_ctr_auth() validate_ctr_version() During event creation, the counter number is checked in functions validate_ctr_auth() and validate_ctr_version() to verify it is a valid counter and supported by the hardware. If this is not the case, both functions return an error and the event is not created. System call perf_event_open() returns an error in this case. Later on the event is installed in the kernel event subsystem and the driver functions cpumf_pmu_add() and cpumf_pmu_commit_txn() are called to install the counter event by the hardware. Since both events have been verified at event creation, there is no need to re-evaluate the authorization state. This can not change since on * LPARs the authorization change requires a restart of the LPAR (and thus a reboot of the kernel) * DPMs can not take resources away, just add them. Also the sequence of CPU Measurement facility counter device driver calls is cpumf_pmu_start_txn cpumf_pmu_add cpumf_pmu_start cpumf_pmu_commit_txn for every single event. Which means the condition in cpumf_pmu_add() is never met and validate_ctr_auth() is never called. This leaves the counter device driver transaction functions with just one task: start_txn: Verify a transaction is not in flight and call perf_pmu_disable() cancel_txn, commit_txn: Verify a transaction is in flight and call perf_pmu_enable() The same functionality is provided by the default transaction handling functions in kernel/events/core.c. Use those by removing the counter device driver private call back functions. Suggested-by: Sumanth Korikkar <sumanthk@linux.ibm.com> Signed-off-by: Thomas Richter <tmricht@linux.ibm.com> Reviewed-by: Sumanth Korikkar <sumanthk@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
This commit is contained in:
parent
614124bea7
commit
d552a58d70
@ -92,9 +92,8 @@ struct cpu_cf_events {
|
||||
struct cpumf_ctr_info info;
|
||||
atomic_t ctr_set[CPUMF_CTR_SET_MAX];
|
||||
atomic64_t alert;
|
||||
u64 state, tx_state;
|
||||
u64 state;
|
||||
unsigned int flags;
|
||||
unsigned int txn_flags;
|
||||
};
|
||||
DECLARE_PER_CPU(struct cpu_cf_events, cpu_cf_events);
|
||||
|
||||
|
@ -413,15 +413,6 @@ static int cpumf_pmu_add(struct perf_event *event, int flags)
|
||||
{
|
||||
struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events);
|
||||
|
||||
/* Check authorization for the counter set to which this
|
||||
* counter belongs.
|
||||
* For group events transaction, the authorization check is
|
||||
* done in cpumf_pmu_commit_txn().
|
||||
*/
|
||||
if (!(cpuhw->txn_flags & PERF_PMU_TXN_ADD))
|
||||
if (validate_ctr_auth(&event->hw))
|
||||
return -ENOENT;
|
||||
|
||||
ctr_set_enable(&cpuhw->state, event->hw.config_base);
|
||||
event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
|
||||
|
||||
@ -449,78 +440,6 @@ static void cpumf_pmu_del(struct perf_event *event, int flags)
|
||||
ctr_set_disable(&cpuhw->state, event->hw.config_base);
|
||||
}
|
||||
|
||||
/*
|
||||
* Start group events scheduling transaction.
|
||||
* Set flags to perform a single test at commit time.
|
||||
*
|
||||
* We only support PERF_PMU_TXN_ADD transactions. Save the
|
||||
* transaction flags but otherwise ignore non-PERF_PMU_TXN_ADD
|
||||
* transactions.
|
||||
*/
|
||||
static void cpumf_pmu_start_txn(struct pmu *pmu, unsigned int txn_flags)
|
||||
{
|
||||
struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events);
|
||||
|
||||
WARN_ON_ONCE(cpuhw->txn_flags); /* txn already in flight */
|
||||
|
||||
cpuhw->txn_flags = txn_flags;
|
||||
if (txn_flags & ~PERF_PMU_TXN_ADD)
|
||||
return;
|
||||
|
||||
perf_pmu_disable(pmu);
|
||||
cpuhw->tx_state = cpuhw->state;
|
||||
}
|
||||
|
||||
/*
|
||||
* Stop and cancel a group events scheduling tranctions.
|
||||
* Assumes cpumf_pmu_del() is called for each successful added
|
||||
* cpumf_pmu_add() during the transaction.
|
||||
*/
|
||||
static void cpumf_pmu_cancel_txn(struct pmu *pmu)
|
||||
{
|
||||
unsigned int txn_flags;
|
||||
struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events);
|
||||
|
||||
WARN_ON_ONCE(!cpuhw->txn_flags); /* no txn in flight */
|
||||
|
||||
txn_flags = cpuhw->txn_flags;
|
||||
cpuhw->txn_flags = 0;
|
||||
if (txn_flags & ~PERF_PMU_TXN_ADD)
|
||||
return;
|
||||
|
||||
WARN_ON(cpuhw->tx_state != cpuhw->state);
|
||||
|
||||
perf_pmu_enable(pmu);
|
||||
}
|
||||
|
||||
/*
|
||||
* Commit the group events scheduling transaction. On success, the
|
||||
* transaction is closed. On error, the transaction is kept open
|
||||
* until cpumf_pmu_cancel_txn() is called.
|
||||
*/
|
||||
static int cpumf_pmu_commit_txn(struct pmu *pmu)
|
||||
{
|
||||
struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events);
|
||||
u64 state;
|
||||
|
||||
WARN_ON_ONCE(!cpuhw->txn_flags); /* no txn in flight */
|
||||
|
||||
if (cpuhw->txn_flags & ~PERF_PMU_TXN_ADD) {
|
||||
cpuhw->txn_flags = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check if the updated state can be scheduled */
|
||||
state = cpuhw->state & ~((1 << CPUMF_LCCTL_ENABLE_SHIFT) - 1);
|
||||
state >>= CPUMF_LCCTL_ENABLE_SHIFT;
|
||||
if ((state & cpuhw->info.auth_ctl) != state)
|
||||
return -ENOENT;
|
||||
|
||||
cpuhw->txn_flags = 0;
|
||||
perf_pmu_enable(pmu);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Performance monitoring unit for s390x */
|
||||
static struct pmu cpumf_pmu = {
|
||||
.task_ctx_nr = perf_sw_context,
|
||||
@ -533,9 +452,6 @@ static struct pmu cpumf_pmu = {
|
||||
.start = cpumf_pmu_start,
|
||||
.stop = cpumf_pmu_stop,
|
||||
.read = cpumf_pmu_read,
|
||||
.start_txn = cpumf_pmu_start_txn,
|
||||
.commit_txn = cpumf_pmu_commit_txn,
|
||||
.cancel_txn = cpumf_pmu_cancel_txn,
|
||||
};
|
||||
|
||||
static int __init cpumf_pmu_init(void)
|
||||
|
@ -30,7 +30,6 @@ DEFINE_PER_CPU(struct cpu_cf_events, cpu_cf_events) = {
|
||||
.alert = ATOMIC64_INIT(0),
|
||||
.state = 0,
|
||||
.flags = 0,
|
||||
.txn_flags = 0,
|
||||
};
|
||||
/* Indicator whether the CPU-Measurement Counter Facility Support is ready */
|
||||
static bool cpum_cf_initalized;
|
||||
|
Loading…
Reference in New Issue
Block a user