[PATCH 5.15.y] drm/amd/pm: fix torn gpu metrics reads
Sasha Levin <[email protected]>
| Newsgroups | org.kernel.vger.stable |
|---|---|
| Message-ID | <[email protected]> |
From: Yang Wang <[email protected]> [ Upstream commit 048f4541b71fb19645fb79d6e62e6e4da23a4035 ] amdgpu_dpm_get_gpu_metrics() returns a pointer to the shared metrics cache after dropping adev->pm.mutex. The sysfs path then copies from that pointer. Another reader can refresh the cache in place during the copy and return a snapshot containing data from two generations. Pass caller-provided storage through the DPM interface and copy the metrics while the mutex is held. This keeps the cache pointer private and makes each sysfs read observe one complete sample. Fixes: 25c933b1c4fc ("drm/amd/powerplay: add new sysfs interface for retrieving gpu metrics(V2)") Signed-off-by: Yang Wang <[email protected]> Reviewed-by: Kenneth Feng <[email protected]> Signed-off-by: Alex Deucher <[email protected]> (cherry picked from commit 862333bb48693ecafcae25af0c9d9ec31015ac77) Cc: [email protected] [ applied the fix at the caller `amdgpu_get_gpu_metrics()` in amdgpu_pm.c since the `amdgpu_dpm_get_gpu_metrics()` wrapper is a macro on this tree ] Signed-off-by: Sasha Levin <[email protected]> --- drivers/gpu/drm/amd/pm/amdgpu_pm.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c index 23f3cd9f2e8b0..d8b0c13fc42a3 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c @@ -1804,18 +1804,16 @@ static ssize_t amdgpu_get_gpu_metrics(struct device *dev, return ret; } + mutex_lock(&adev->pm.mutex); if (adev->powerplay.pp_funcs->get_gpu_metrics) size = amdgpu_dpm_get_gpu_metrics(adev, &gpu_metrics); - if (size <= 0) - goto out; - - if (size >= PAGE_SIZE) - size = PAGE_SIZE - 1; - - memcpy(buf, gpu_metrics, size); + if (size > 0) { + size = min_t(ssize_t, size, PAGE_SIZE - 1); + memcpy(buf, gpu_metrics, size); + } + mutex_unlock(&adev->pm.mutex); -out: pm_runtime_mark_last_busy(ddev->dev); pm_runtime_put_autosuspend(ddev->dev); -- 2.53.0