diff options
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/kernel/perf_pai_crypto.c | 19 |
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(); |