summaryrefslogtreecommitdiff
path: root/arch/s390/kernel/perf_pai_crypto.c
diff options
context:
space:
mode:
authorThomas Richter <tmricht@linux.ibm.com>2024-02-29 15:13:48 +0100
committerAlexander Gordeev <agordeev@linux.ibm.com>2024-06-07 16:49:06 +0200
commitfb412c6241dccc530416917efe8e9fea5fa1fda2 (patch)
treef519b41cae7f0ee526f9d8099fe41271f6b444f8 /arch/s390/kernel/perf_pai_crypto.c
parent1433b36e3ab67772a37db624fc1f8e66d443690d (diff)
s390/pai_crypto: Enable concurrent system-wide counting/sampling event
The PMU for PAI crypto counters enforces the following restriction: - No system wide counting while system wide sampling is active. This restriction is removed. One or more system wide counting events can now be active at the same time while at most one system wide sampling event is active. Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com> Signed-off-by: Thomas Richter <tmricht@linux.ibm.com> Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
Diffstat (limited to 'arch/s390/kernel/perf_pai_crypto.c')
-rw-r--r--arch/s390/kernel/perf_pai_crypto.c19
1 files changed, 9 insertions, 10 deletions
diff --git a/arch/s390/kernel/perf_pai_crypto.c b/arch/s390/kernel/perf_pai_crypto.c
index 4ad472d130a3..d3a64f041819 100644
--- a/arch/s390/kernel/perf_pai_crypto.c
+++ b/arch/s390/kernel/perf_pai_crypto.c
@@ -97,6 +97,8 @@ static void paicrypt_event_destroy(struct perf_event *event)
event->attr.config, event->cpu,
cpump->active_events, cpump->mode,
refcount_read(&cpump->refcnt));
+ if (event->attr.sample_period)
+ cpump->mode &= ~PAI_MODE_SAMPLING;
free_page(PAI_SAVE_AREA(event));
if (refcount_dec_and_test(&cpump->refcnt)) {
debug_sprintf_event(cfm_dbg, 4, "%s page %#lx save %p\n",
@@ -160,9 +162,7 @@ static u64 paicrypt_getall(struct perf_event *event)
* sampling for crypto events
*
* Only one instance of event pai_crypto/CRYPTO_ALL/ for sampling is
- * allowed and when this event is running, no counting event is allowed.
- * Several counting events are allowed in parallel, but no sampling event
- * is allowed while one (or more) counting events are running.
+ * allowed. Several counting events are allowed in parallel.
*
* This function is called in process context and it is save to block.
* When the event initialization functions fails, no other call back will
@@ -196,12 +196,12 @@ static struct paicrypt_map *paicrypt_busy(struct perf_event *event)
}
if (a->sample_period) { /* Sampling requested */
- if (cpump->mode != PAI_MODE_NONE)
- rc = -EBUSY; /* ... sampling/counting active */
- } else { /* Counting requested */
- if (cpump->mode == PAI_MODE_SAMPLING)
+ if (cpump->mode & PAI_MODE_SAMPLING)
rc = -EBUSY; /* ... and sampling active */
+ else
+ cpump->mode |= PAI_MODE_SAMPLING;
}
+
/*
* This error case triggers when there is a conflict:
* Either sampling requested and counting already active, or visa
@@ -235,7 +235,6 @@ static struct paicrypt_map *paicrypt_busy(struct perf_event *event)
/* Set mode and reference count */
rc = 0;
refcount_set(&cpump->refcnt, 1);
- cpump->mode = a->sample_period ? PAI_MODE_SAMPLING : PAI_MODE_COUNTING;
mp->mapptr = cpump;
debug_sprintf_event(cfm_dbg, 5, "%s sample_period %#llx users %d"
" mode %d refcnt %u page %#lx save %p rc %d\n",
@@ -249,7 +248,6 @@ free_paicrypt_map:
mp->mapptr = NULL;
free_root:
paicrypt_root_free();
-
unlock:
mutex_unlock(&pai_reserve_mutex);
return rc ? ERR_PTR(rc) : cpump;
@@ -332,6 +330,7 @@ static void paicrypt_start(struct perf_event *event, int flags)
local64_set(&event->hw.prev_count, sum);
} else { /* Sampling */
cpump->event = event;
+ memcpy((void *)PAI_SAVE_AREA(event), cpump->page, PAGE_SIZE);
perf_sched_cb_inc(event->pmu);
}
}
@@ -480,7 +479,7 @@ static int paicrypt_have_sample(void)
static void paicrypt_sched_task(struct perf_event_pmu_context *pmu_ctx, bool sched_in)
{
/* We started with a clean page on event installation. So read out
- * results on schedule_out and if page was dirty, clear values.
+ * results on schedule_out and if page was dirty, save old values.
*/
if (!sched_in)
paicrypt_have_sample();