s390/cpumf: remove counter transaction call backs
authorThomas Richter <tmricht@linux.ibm.com>
Wed, 28 Apr 2021 11:30:56 +0000 (13:30 +0200)
committerVasily Gorbik <gor@linux.ibm.com>
Mon, 7 Jun 2021 15:06:58 +0000 (17:06 +0200)
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>
arch/s390/include/asm/cpu_mcf.h
arch/s390/kernel/perf_cpum_cf.c
arch/s390/kernel/perf_cpum_cf_common.c

index 3e4cbcb..4dcefdd 100644 (file)
@@ -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);
 
index 31a605b..91ee0f3 100644 (file)
@@ -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)
index 6d53215..2300fba 100644 (file)
@@ -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;