On 2026-09-30 20:51, [email protected] wrote:
> From: Vitaly Prosyak <[email protected]>
>
> The vblank counter callback reads display registers and scanout
> position without holding reset_domain->sem. During GPU recovery,
> display commit work can call the callback while reset owns the
> semaphore for writing. The hardware access then triggers the
> lockdep_assert_held() in amdgpu_device_skip_hw_access() and sets
> TAINT_WARN when lockdep is enabled.
>
> Try to acquire the reset semaphore for reading before accessing the
> hardware, and hold it across the counter and scanout-position reads.
> If reset is already in progress, return DRM's cached software vblank
> count instead. This avoids blocking behind reset and avoids accessing
> display hardware while it is being reset.
>
> The cached count is less accurate than the hardware count, but is
> used only when reset prevents a safe hardware read. This addresses
> the reset-time warning from this vblank path; it does not suppress or
> fix unrelated lockdep warnings.
>
> Cc: Christian König <[email protected]>
> Cc: Alex Deucher <[email protected]>
> Cc: Harry Wentland <[email protected]>
> Cc: Sunpeng Li <[email protected]>
> Signed-off-by: Vitaly Prosyak <[email protected]>
Reviewed-by: Leo Li <[email protected]>
Thanks!
> ---
> drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> index bac072d73e16..f34150d20a2f 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
> @@ -30,6 +30,7 @@
> #include <drm/amdgpu_drm.h>
> #include <drm/drm_drv.h>
> #include <drm/drm_fb_helper.h>
> +#include <drm/drm_vblank.h>
> #include "amdgpu_uvd.h"
> #include "amdgpu_vce.h"
> #include "atom.h"
> @@ -1669,6 +1670,9 @@ u32 amdgpu_get_vblank_counter_kms(struct drm_crtc *crtc)
> DRM_ERROR("Invalid crtc %u\n", pipe);
> return -EINVAL;
> }
> + if (!down_read_trylock(&adev->reset_domain->sem))
> + return drm_crtc_vblank_count(crtc);
> +
>
> /* The hw increments its frame counter at start of vsync, not at start
> * of vblank, as is required by DRM core vblank counter handling.
> @@ -1714,6 +1718,7 @@ u32 amdgpu_get_vblank_counter_kms(struct drm_crtc *crtc)
> DRM_DEBUG_VBL("NULL mode info! Returned count may be wrong.\n");
> }
>
> + up_read(&adev->reset_domain->sem);
> return count;
> }
>