[PATCH] drm/xe: Fix potential deadlock in __fini_dbm

Piotr Piórkowski piotr.piorkowski at intel.com
Fri Jan 12 09:16:43 UTC 2024


Michal Wajdeczko <michal.wajdeczko at intel.com> wrote on czw [2024-sty-11 19:56:03 +0100]:
> If Doorbell Manager is in unclean state during fini phase, for
> debug purposes we try to print it's state, but we missed the fact
> that we are already holding a lock so the xe_guc_db_mgr_print()
> will deadlock since it also attempts to grab the same lock.
> 
> Fixes: 990fe6e6ed3c ("drm/xe: Introduce GuC Doorbells Manager")
> Signed-off-by: Michal Wajdeczko <michal.wajdeczko at intel.com>
> Cc: Piotr Piórkowski <piotr.piorkowski at intel.com>
Reviewed-by: Piotr Piórkowski <piotr.piorkowski at intel.com>
> ---
>  drivers/gpu/drm/xe/xe_guc_db_mgr.c | 27 ++++++++++++++++-----------
>  1 file changed, 16 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/xe/xe_guc_db_mgr.c b/drivers/gpu/drm/xe/xe_guc_db_mgr.c
> index c1c04575d82d..8d9a0287df6b 100644
> --- a/drivers/gpu/drm/xe/xe_guc_db_mgr.c
> +++ b/drivers/gpu/drm/xe/xe_guc_db_mgr.c
> @@ -46,6 +46,8 @@ static struct xe_device *dbm_to_xe(struct xe_guc_db_mgr *dbm)
>  #define dbm_assert(_dbm, _cond)		xe_gt_assert(dbm_to_gt(_dbm), _cond)
>  #define dbm_mutex(_dbm)			(&dbm_to_guc(_dbm)->submission_state.lock)
>  
> +static void dbm_print_locked(struct xe_guc_db_mgr *dbm, struct drm_printer *p, int indent);
> +
>  static void __fini_dbm(struct drm_device *drm, void *arg)
>  {
>  	struct xe_guc_db_mgr *dbm = arg;
> @@ -59,7 +61,7 @@ static void __fini_dbm(struct drm_device *drm, void *arg)
>  
>  		xe_gt_err(dbm_to_gt(dbm), "GuC doorbells manager unclean (%u/%u)\n",
>  			  weight, dbm->count);
> -		xe_guc_db_mgr_print(dbm, &p, 1);
> +		dbm_print_locked(dbm, &p, 1);
>  	}
>  
>  	bitmap_free(dbm->bitmap);
> @@ -219,14 +221,7 @@ void xe_guc_db_mgr_release_range(struct xe_guc_db_mgr *dbm,
>  	mutex_unlock(dbm_mutex(dbm));
>  }
>  
> -/**
> - * xe_guc_db_mgr_print() - Print status of GuC Doorbells Manager.
> - * @dbm: the &xe_guc_db_mgr to print
> - * @p: the &drm_printer to print to
> - * @indent: tab indentation level
> - */
> -void xe_guc_db_mgr_print(struct xe_guc_db_mgr *dbm,
> -			 struct drm_printer *p, int indent)
> +static void dbm_print_locked(struct xe_guc_db_mgr *dbm, struct drm_printer *p, int indent)
>  {
>  	unsigned int rs, re;
>  	unsigned int total;
> @@ -235,8 +230,6 @@ void xe_guc_db_mgr_print(struct xe_guc_db_mgr *dbm,
>  	if (!dbm->bitmap)
>  		return;
>  
> -	mutex_lock(dbm_mutex(dbm));
> -
>  	total = 0;
>  	for_each_clear_bitrange(rs, re, dbm->bitmap, dbm->count) {
>  		drm_printf_indent(p, indent, "available range: %u..%u (%u)\n",
> @@ -252,7 +245,19 @@ void xe_guc_db_mgr_print(struct xe_guc_db_mgr *dbm,
>  		total += re - rs;
>  	}
>  	drm_printf_indent(p, indent, "reserved total: %u\n", total);
> +}
>  
> +/**
> + * xe_guc_db_mgr_print() - Print status of GuC Doorbells Manager.
> + * @dbm: the &xe_guc_db_mgr to print
> + * @p: the &drm_printer to print to
> + * @indent: tab indentation level
> + */
> +void xe_guc_db_mgr_print(struct xe_guc_db_mgr *dbm,
> +			 struct drm_printer *p, int indent)
> +{
> +	mutex_lock(dbm_mutex(dbm));
> +	dbm_print_locked(dbm, p, indent);
>  	mutex_unlock(dbm_mutex(dbm));
>  }
>  
> 
> base-commit: 39d854dbde14bef5cabe3cf3a49de8894cd99ba7
> -- 
> 2.25.1
> 

-- 


More information about the Intel-xe mailing list