Commit 37dc4737 authored by Lucas Stach's avatar Lucas Stach
Browse files

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: 68dc0b29 ("drm/etnaviv: use 'sync points' for performance monitor requests")
Reviewed-by: default avatarChristian Gmeiner <cgmeiner@igalia.com>
Signed-off-by: default avatarLucas Stach <l.stach@pengutronix.de>
parent 72dc70a0
Loading
Loading
Loading
Loading
+14 −6
Original line number Diff line number Diff line
@@ -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;
	}
}