Commit e9f3af02 authored by Thomas Richter's avatar Thomas Richter Committed by Vasily Gorbik

s390/pai: fix sampling event removal for PMU device driver

In case of a sampling event, the PAI PMU device drivers need a
reference to this event.  Currently to PMU device driver reference
is removed when a sampling event is destroyed. This may lead to
situations where the reference of the PMU device driver is removed
while being used by a different sampling event.
Reset the event reference pointer of the PMU device driver when
a sampling event is deleted and before the next one might be added.

Fixes: 39d62336 ("s390/pai: add support for cryptography counters")
Signed-off-by: default avatarThomas Richter <tmricht@linux.ibm.com>
Acked-by: default avatarSumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
parent c9c26068
...@@ -90,7 +90,6 @@ static void paicrypt_event_destroy(struct perf_event *event) ...@@ -90,7 +90,6 @@ static void paicrypt_event_destroy(struct perf_event *event)
event->cpu); event->cpu);
struct paicrypt_map *cpump = mp->mapptr; struct paicrypt_map *cpump = mp->mapptr;
cpump->event = NULL;
static_branch_dec(&pai_key); static_branch_dec(&pai_key);
mutex_lock(&pai_reserve_mutex); mutex_lock(&pai_reserve_mutex);
debug_sprintf_event(cfm_dbg, 5, "%s event %#llx cpu %d users %d" debug_sprintf_event(cfm_dbg, 5, "%s event %#llx cpu %d users %d"
...@@ -356,10 +355,15 @@ static int paicrypt_add(struct perf_event *event, int flags) ...@@ -356,10 +355,15 @@ static int paicrypt_add(struct perf_event *event, int flags)
static void paicrypt_stop(struct perf_event *event, int flags) static void paicrypt_stop(struct perf_event *event, int flags)
{ {
if (!event->attr.sample_period) /* Counting */ struct paicrypt_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr);
struct paicrypt_map *cpump = mp->mapptr;
if (!event->attr.sample_period) { /* Counting */
paicrypt_read(event); paicrypt_read(event);
else /* Sampling */ } else { /* Sampling */
perf_sched_cb_dec(event->pmu); perf_sched_cb_dec(event->pmu);
cpump->event = NULL;
}
event->hw.state = PERF_HES_STOPPED; event->hw.state = PERF_HES_STOPPED;
} }
......
...@@ -122,7 +122,6 @@ static void paiext_event_destroy(struct perf_event *event) ...@@ -122,7 +122,6 @@ static void paiext_event_destroy(struct perf_event *event)
free_page(PAI_SAVE_AREA(event)); free_page(PAI_SAVE_AREA(event));
mutex_lock(&paiext_reserve_mutex); mutex_lock(&paiext_reserve_mutex);
cpump->event = NULL;
if (refcount_dec_and_test(&cpump->refcnt)) /* Last reference gone */ if (refcount_dec_and_test(&cpump->refcnt)) /* Last reference gone */
paiext_free(mp); paiext_free(mp);
paiext_root_free(); paiext_root_free();
...@@ -362,10 +361,15 @@ static int paiext_add(struct perf_event *event, int flags) ...@@ -362,10 +361,15 @@ static int paiext_add(struct perf_event *event, int flags)
static void paiext_stop(struct perf_event *event, int flags) static void paiext_stop(struct perf_event *event, int flags)
{ {
if (!event->attr.sample_period) /* Counting */ struct paiext_mapptr *mp = this_cpu_ptr(paiext_root.mapptr);
struct paiext_map *cpump = mp->mapptr;
if (!event->attr.sample_period) { /* Counting */
paiext_read(event); paiext_read(event);
else /* Sampling */ } else { /* Sampling */
perf_sched_cb_dec(event->pmu); perf_sched_cb_dec(event->pmu);
cpump->event = NULL;
}
event->hw.state = PERF_HES_STOPPED; event->hw.state = PERF_HES_STOPPED;
} }
......
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