[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250731-b4-dont-wake-next-v1-4-e51bdc347fa3@gmail.com>
Date: Thu, 31 Jul 2025 07:36:37 +0200
From: Philipp Zabel <philipp.zabel@...il.com>
To: Alex Deucher <alexander.deucher@....com>,
Christian König <christian.koenig@....com>,
David Airlie <airlied@...il.com>, Simona Vetter <simona@...ll.ch>
Cc: amd-gfx@...ts.freedesktop.org, dri-devel@...ts.freedesktop.org,
linux-kernel@...r.kernel.org, Philipp Zabel <p.zabel@...gutronix.de>,
Philipp Zabel <philipp.zabel@...il.com>
Subject: [PATCH RFC 4/6] drm/amdgpu: don't wake up the GPU for some
AMDGPU_INFO queries
Don't wake the GPU if the AMDGPU_INFO query doesn't need to power up the
GPU.
Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2295
Signed-off-by: Philipp Zabel <philipp.zabel@...il.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 1 +
drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 59 +++++++++++++++++++++++++++------
2 files changed, 49 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 732f398922da5..79d31ac6a7b37 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -2961,6 +2961,7 @@ static const unsigned int no_wake_ioctl_list[] = {
DRM_IOCTL_MODE_LIST_LESSEES,
DRM_IOCTL_MODE_GET_LEASE,
DRM_IOCTL_MODE_REVOKE_LEASE,
+ DRM_IOCTL_AMDGPU_INFO,
};
long amdgpu_drm_ioctl(struct file *filp,
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 190602bacbcdf..fe1347a4075c4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -732,7 +732,17 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
return copy_to_user(out, &count, min(size, 4u)) ? -EFAULT : 0;
}
case AMDGPU_INFO_TIMESTAMP:
+ ret = pm_runtime_get_sync(dev->dev);
+ if (ret < 0) {
+ pm_runtime_put_autosuspend(dev->dev);
+ return ret;
+ }
+
ui64 = amdgpu_gfx_get_gpu_clock_counter(adev);
+
+ pm_runtime_mark_last_busy(dev->dev);
+ pm_runtime_put_autosuspend(dev->dev);
+
return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
case AMDGPU_INFO_FW_VERSION: {
struct drm_amdgpu_info_firmware fw_info;
@@ -873,6 +883,12 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
alloc_size = info->read_mmr_reg.count * sizeof(*regs);
+ ret = pm_runtime_get_sync(dev->dev);
+ if (ret < 0) {
+ pm_runtime_put_autosuspend(dev->dev);
+ goto out;
+ }
+
amdgpu_gfx_off_ctrl(adev, false);
for (i = 0; i < info->read_mmr_reg.count; i++) {
if (amdgpu_asic_read_register(adev, se_num, sh_num,
@@ -882,11 +898,16 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
info->read_mmr_reg.dword_offset + i);
kfree(regs);
amdgpu_gfx_off_ctrl(adev, true);
+ pm_runtime_mark_last_busy(dev->dev);
+ pm_runtime_put_autosuspend(dev->dev);
ret = -EFAULT;
goto out;
}
}
amdgpu_gfx_off_ctrl(adev, true);
+ pm_runtime_mark_last_busy(dev->dev);
+ pm_runtime_put_autosuspend(dev->dev);
+
n = copy_to_user(out, regs, min(size, alloc_size));
kfree(regs);
ret = (n ? -EFAULT : 0);
@@ -912,7 +933,8 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
dev_info->num_shader_arrays_per_engine = adev->gfx.config.max_sh_per_se;
/* return all clocks in KHz */
dev_info->gpu_counter_freq = adev->clock.xclk * 10;
- if (adev->pm.dpm_enabled) {
+ ret = pm_runtime_get_if_active(dev->dev);
+ if (ret == 1 && adev->pm.dpm_enabled) {
dev_info->max_engine_clock = amdgpu_dpm_get_sclk(adev, false) * 10;
dev_info->max_memory_clock = amdgpu_dpm_get_mclk(adev, false) * 10;
dev_info->min_engine_clock = amdgpu_dpm_get_sclk(adev, true) * 10;
@@ -925,6 +947,10 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
dev_info->min_memory_clock =
adev->clock.default_mclk * 10;
}
+ if (ret == 1) {
+ pm_runtime_mark_last_busy(dev->dev);
+ pm_runtime_put_autosuspend(dev->dev);
+ }
dev_info->enabled_rb_pipes_mask = adev->gfx.config.backend_enable_mask;
dev_info->num_rb_pipes = adev->gfx.config.max_backends_per_se *
adev->gfx.config.max_shader_engines;
@@ -1125,13 +1151,19 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
if (!adev->pm.dpm_enabled)
return -ENOENT;
+ ret = pm_runtime_get_sync(dev->dev);
+ if (ret < 0) {
+ pm_runtime_put_autosuspend(dev->dev);
+ return ret;
+ }
+
switch (info->sensor_info.type) {
case AMDGPU_INFO_SENSOR_GFX_SCLK:
/* get sclk in Mhz */
if (amdgpu_dpm_read_sensor(adev,
AMDGPU_PP_SENSOR_GFX_SCLK,
(void *)&ui32, &ui32_size)) {
- return -EINVAL;
+ ret = -EINVAL;
}
ui32 /= 100;
break;
@@ -1140,7 +1172,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
if (amdgpu_dpm_read_sensor(adev,
AMDGPU_PP_SENSOR_GFX_MCLK,
(void *)&ui32, &ui32_size)) {
- return -EINVAL;
+ ret = -EINVAL;
}
ui32 /= 100;
break;
@@ -1149,7 +1181,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
if (amdgpu_dpm_read_sensor(adev,
AMDGPU_PP_SENSOR_GPU_TEMP,
(void *)&ui32, &ui32_size)) {
- return -EINVAL;
+ ret = -EINVAL;
}
break;
case AMDGPU_INFO_SENSOR_GPU_LOAD:
@@ -1157,7 +1189,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
if (amdgpu_dpm_read_sensor(adev,
AMDGPU_PP_SENSOR_GPU_LOAD,
(void *)&ui32, &ui32_size)) {
- return -EINVAL;
+ ret = -EINVAL;
}
break;
case AMDGPU_INFO_SENSOR_GPU_AVG_POWER:
@@ -1169,7 +1201,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
if (amdgpu_dpm_read_sensor(adev,
AMDGPU_PP_SENSOR_GPU_INPUT_POWER,
(void *)&ui32, &ui32_size)) {
- return -EINVAL;
+ ret = -EINVAL;
}
}
ui32 >>= 8;
@@ -1188,7 +1220,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
if (amdgpu_dpm_read_sensor(adev,
AMDGPU_PP_SENSOR_VDDNB,
(void *)&ui32, &ui32_size)) {
- return -EINVAL;
+ ret = -EINVAL;
}
break;
case AMDGPU_INFO_SENSOR_VDDGFX:
@@ -1196,7 +1228,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
if (amdgpu_dpm_read_sensor(adev,
AMDGPU_PP_SENSOR_VDDGFX,
(void *)&ui32, &ui32_size)) {
- return -EINVAL;
+ ret = -EINVAL;
}
break;
case AMDGPU_INFO_SENSOR_STABLE_PSTATE_GFX_SCLK:
@@ -1204,7 +1236,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
if (amdgpu_dpm_read_sensor(adev,
AMDGPU_PP_SENSOR_STABLE_PSTATE_SCLK,
(void *)&ui32, &ui32_size)) {
- return -EINVAL;
+ ret = -EINVAL;
}
ui32 /= 100;
break;
@@ -1213,7 +1245,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
if (amdgpu_dpm_read_sensor(adev,
AMDGPU_PP_SENSOR_STABLE_PSTATE_MCLK,
(void *)&ui32, &ui32_size)) {
- return -EINVAL;
+ ret = -EINVAL;
}
ui32 /= 100;
break;
@@ -1238,8 +1270,13 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
default:
DRM_DEBUG_KMS("Invalid request %d\n",
info->sensor_info.type);
- return -EINVAL;
+ ret = -EINVAL;
+ break;
}
+ pm_runtime_mark_last_busy(dev->dev);
+ pm_runtime_put_autosuspend(dev->dev);
+ if (ret < 0)
+ return ret;
return copy_to_user(out, &ui32, min(size, 4u)) ? -EFAULT : 0;
}
case AMDGPU_INFO_VRAM_LOST_COUNTER:
--
2.50.1
Powered by blists - more mailing lists