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.za...@gmail.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

Reply via email to