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;
>  }
>  

Reply via email to