diff options
author | Maarten Lankhorst <maarten.lankhorst@linux.intel.com> | 2023-02-28 11:17:30 +0100 |
---|---|---|
committer | Rodrigo Vivi <rodrigo.vivi@intel.com> | 2023-12-19 18:30:20 -0500 |
commit | 38c04b47cec861cf4007b3e53cbf584e494e2762 (patch) | |
tree | dca5894d0e97888aa1f04c25d3d4ff3a63c2756b /drivers/gpu/drm | |
parent | 044f0cfb19473cd1b60a69c802cac0651066fa21 (diff) |
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 <maarten.lankhorst@linux.intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/xe/xe_device.c | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/xe/xe_device.h | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/xe/xe_device_types.h | 4 |
3 files changed, 13 insertions, 23 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) + bool hold = xe->mem_access.hold_rpm; + int ref = atomic_dec_return(&xe->mem_access.ref); + + if (!ref && hold) xe_pm_runtime_put(xe); - mutex_unlock(&xe->mem_access.lock); - XE_WARN_ON(xe->mem_access.ref < 0); + 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) +static inline bool xe_device_mem_access_ongoing(struct xe_device *xe) { - XE_WARN_ON(!xe->mem_access.ref); + return atomic_read(&xe->mem_access.ref); } -static inline bool xe_device_mem_access_ongoing(struct xe_device *xe) +static inline void xe_device_assert_mem_access(struct xe_device *xe) { - bool ret; - - mutex_lock(&xe->mem_access.lock); - ret = xe->mem_access.ref; - mutex_unlock(&xe->mem_access.lock); - - return ret; + 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; |