These ioctls don't need to GPU, so don't resume it. Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@xxxxxxx> --- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 45 +++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index a9831b243bfc..d21d5af7f187 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -2855,7 +2855,9 @@ long amdgpu_drm_ioctl(struct file *filp, { struct drm_file *file_priv = filp->private_data; struct drm_device *dev; + bool is_driver_ioctl; bool needs_device; + unsigned int nr; long ret; dev = file_priv->minor->dev; @@ -2863,9 +2865,46 @@ long amdgpu_drm_ioctl(struct file *filp, /* Some ioctl can opt-out of powermanagement handling * if they don't require the device to be resumed. */ - switch (cmd) { - default: - needs_device = true; + nr = DRM_IOCTL_NR(cmd); + + is_driver_ioctl = nr >= DRM_COMMAND_BASE && nr < DRM_COMMAND_END; + + if (is_driver_ioctl) { + switch (nr - DRM_COMMAND_BASE) { + /* These 4 only operate on kernel data structure. */ + case DRM_AMDGPU_VM: + case DRM_AMDGPU_SCHED: + case DRM_AMDGPU_BO_LIST: + case DRM_AMDGPU_FENCE_TO_HANDLE: + /* All the waits don't need to resume up the device. If there are + * jobs in progress, the device can't be in suspended state. And if + * there's nothing no in-flight jobs, then the waits are no-op. + */ + case DRM_AMDGPU_GEM_WAIT_IDLE: + case DRM_AMDGPU_WAIT_CS: + case DRM_AMDGPU_WAIT_FENCES: + needs_device = false; + break; + default: + needs_device = true; + } + } else { + /* Most drm core ioctls don't need the device, but to avoid missing one + * that requires it, implement the "can skip pm" logic as an allow list. + */ + switch (nr) { + case DRM_IOCTL_NR(DRM_IOCTL_VERSION): + case DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC): + case DRM_IOCTL_NR(DRM_IOCTL_GET_CAP): + case DRM_IOCTL_NR(DRM_IOCTL_SYNCOBJ_CREATE): + /* Same logic as DRM_AMDGPU_WAIT_* */ + case DRM_IOCTL_NR(DRM_IOCTL_SYNCOBJ_WAIT): + case DRM_IOCTL_NR(DRM_IOCTL_SYNCOBJ_DESTROY): + needs_device = false; + break; + default: + needs_device = true; + } } if (needs_device) { -- 2.40.1