summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLucas Stach <l.stach@pengutronix.de>2024-07-05 22:00:09 +0200
committerLucas Stach <l.stach@pengutronix.de>2024-10-28 16:33:15 +0100
commit37dc4737447a7667f8e9ec790dac251da057eb27 (patch)
tree0556c9f4e5e3aeede4c17a54e8dfcd10822a346e
parent72dc70a062f9faea178d674416d72a2596b69633 (diff)
drm/etnaviv: hold GPU lock across perfmon sampling
The perfmon sampling mutates shared GPU state (e.g. VIVS_HI_CLOCK_CONTROL to select the pipe for the perf counter reads). To avoid clashing with other functions mutating the same state (e.g. etnaviv_gpu_update_clock) the perfmon sampling needs to hold the GPU lock. Fixes: 68dc0b295dcb ("drm/etnaviv: use 'sync points' for performance monitor requests") Reviewed-by: Christian Gmeiner <cgmeiner@igalia.com> Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gpu.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
index 5a8110586d58..b43c6f3416a6 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c
@@ -1322,6 +1322,8 @@ static void sync_point_perfmon_sample_pre(struct etnaviv_gpu *gpu,
{
u32 val;
+ mutex_lock(&gpu->lock);
+
/* disable clock gating */
val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS);
val &= ~VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING;
@@ -1333,6 +1335,8 @@ static void sync_point_perfmon_sample_pre(struct etnaviv_gpu *gpu,
gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, val);
sync_point_perfmon_sample(gpu, event, ETNA_PM_PROCESS_PRE);
+
+ mutex_unlock(&gpu->lock);
}
static void sync_point_perfmon_sample_post(struct etnaviv_gpu *gpu,
@@ -1342,13 +1346,9 @@ static void sync_point_perfmon_sample_post(struct etnaviv_gpu *gpu,
unsigned int i;
u32 val;
- sync_point_perfmon_sample(gpu, event, ETNA_PM_PROCESS_POST);
-
- for (i = 0; i < submit->nr_pmrs; i++) {
- const struct etnaviv_perfmon_request *pmr = submit->pmrs + i;
+ mutex_lock(&gpu->lock);
- *pmr->bo_vma = pmr->sequence;
- }
+ sync_point_perfmon_sample(gpu, event, ETNA_PM_PROCESS_POST);
/* disable debug register */
val = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL);
@@ -1359,6 +1359,14 @@ static void sync_point_perfmon_sample_post(struct etnaviv_gpu *gpu,
val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS);
val |= VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING;
gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, val);
+
+ mutex_unlock(&gpu->lock);
+
+ for (i = 0; i < submit->nr_pmrs; i++) {
+ const struct etnaviv_perfmon_request *pmr = submit->pmrs + i;
+
+ *pmr->bo_vma = pmr->sequence;
+ }
}