From 38c04b47cec861cf4007b3e53cbf584e494e2762 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Tue, 28 Feb 2023 11:17:30 +0100 Subject: [PATCH] drm/xe: Use atomic instead of mutex for xe_device_mem_access_ongoing xe_guc_ct_fast_path() is called from an irq context, and cannot lock the mutex used by xe_device_mem_access_ongoing(). Fortunately it is easy to fix, and the atomic guarantees are good enough to ensure xe->mem_access.hold_rpm is set before last ref is dropped. As far as I can tell, the runtime ref in device access should be killable, but don't dare to do it yet. Signed-off-by: Maarten Lankhorst Reviewed-by: Matthew Brost Acked-by: Rodrigo Vivi Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/xe/xe_device.c | 20 +++++++++----------- drivers/gpu/drm/xe/xe_device.h | 16 +++++----------- drivers/gpu/drm/xe/xe_device_types.h | 4 +--- 3 files changed, 15 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c index 49ce11fc1174..ffacf80c8942 100644 --- a/drivers/gpu/drm/xe/xe_device.c +++ b/drivers/gpu/drm/xe/xe_device.c @@ -206,8 +206,6 @@ struct xe_device *xe_device_create(struct pci_dev *pdev, if (err) goto err_put; - drmm_mutex_init(&xe->drm, &xe->mem_access.lock); - return xe; err_put: @@ -354,25 +352,25 @@ u32 xe_device_ccs_bytes(struct xe_device *xe, u64 size) void xe_device_mem_access_get(struct xe_device *xe) { bool resumed = xe_pm_runtime_resume_if_suspended(xe); + int ref = atomic_inc_return(&xe->mem_access.ref); - mutex_lock(&xe->mem_access.lock); - if (xe->mem_access.ref++ == 0) + if (ref == 1) xe->mem_access.hold_rpm = xe_pm_runtime_get_if_active(xe); - mutex_unlock(&xe->mem_access.lock); /* The usage counter increased if device was immediately resumed */ if (resumed) xe_pm_runtime_put(xe); - XE_WARN_ON(xe->mem_access.ref == S32_MAX); + XE_WARN_ON(ref == S32_MAX); } void xe_device_mem_access_put(struct xe_device *xe) { - mutex_lock(&xe->mem_access.lock); - if (--xe->mem_access.ref == 0 && xe->mem_access.hold_rpm) - xe_pm_runtime_put(xe); - mutex_unlock(&xe->mem_access.lock); + bool hold = xe->mem_access.hold_rpm; + int ref = atomic_dec_return(&xe->mem_access.ref); - XE_WARN_ON(xe->mem_access.ref < 0); + if (!ref && hold) + xe_pm_runtime_put(xe); + + XE_WARN_ON(ref < 0); } diff --git a/drivers/gpu/drm/xe/xe_device.h b/drivers/gpu/drm/xe/xe_device.h index 25c5087f5aad..d277f8985f7b 100644 --- a/drivers/gpu/drm/xe/xe_device.h +++ b/drivers/gpu/drm/xe/xe_device.h @@ -90,20 +90,14 @@ static inline struct xe_force_wake * gt_to_fw(struct xe_gt *gt) void xe_device_mem_access_get(struct xe_device *xe); void xe_device_mem_access_put(struct xe_device *xe); -static inline void xe_device_assert_mem_access(struct xe_device *xe) -{ - XE_WARN_ON(!xe->mem_access.ref); -} - static inline bool xe_device_mem_access_ongoing(struct xe_device *xe) { - bool ret; + return atomic_read(&xe->mem_access.ref); +} - mutex_lock(&xe->mem_access.lock); - ret = xe->mem_access.ref; - mutex_unlock(&xe->mem_access.lock); - - return ret; +static inline void xe_device_assert_mem_access(struct xe_device *xe) +{ + XE_WARN_ON(!xe_device_mem_access_ongoing(xe)); } static inline bool xe_device_in_fault_mode(struct xe_device *xe) diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h index 377a8979bc06..3917b9152eb9 100644 --- a/drivers/gpu/drm/xe/xe_device_types.h +++ b/drivers/gpu/drm/xe/xe_device_types.h @@ -184,10 +184,8 @@ struct xe_device { * triggering additional actions when they occur. */ struct { - /** @lock: protect the ref count */ - struct mutex lock; /** @ref: ref count of memory accesses */ - s32 ref; + atomic_t ref; /** @hold_rpm: need to put rpm ref back at the end */ bool hold_rpm; } mem_access;