Honor OOB max for udelay. Also add a backoff for 'wait'
as it exponentially increases so that doesn't overflow
and also caps to a sane limit so we dont suffer overtly
extended wait times as we progress.
v2: Fix accumnulation of 'wait' so 'slept' is accurate and
accounts for atomic-udelay clamping. (Sashiko)
Fixes: 7dc9b92dcfef ("drm/xe: Remove i915_utils dependency from xe_pcode.")
Signed-off-by: Alan Previn <[email protected]>
---
drivers/gpu/drm/xe/xe_pcode.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_pcode.c b/drivers/gpu/drm/xe/xe_pcode.c
index 266deecbb100..d2ed5edf003e 100644
--- a/drivers/gpu/drm/xe/xe_pcode.c
+++ b/drivers/gpu/drm/xe/xe_pcode.c
@@ -146,6 +146,7 @@ int xe_pcode_read(struct xe_tile *tile, u32 mbox, u32
*val0, u32 *val1)
return err;
}
+#define __XE_PCODE_WAIT_MAX_BACKOFF_100MS (100 * USEC_PER_MSEC)
static int pcode_try_request(struct xe_tile *tile, u32 mbox,
u32 request, u32 reply_mask, u32 reply,
int *status, bool atomic, int timeout_us, bool
locked)
@@ -164,11 +165,14 @@ static int pcode_try_request(struct xe_tile *tile, u32
mbox,
if ((*status == 0) && ((request & reply_mask) == reply))
return 0;
- if (atomic)
- udelay(wait);
- else
+ wait = min_t(int, wait << 1, __XE_PCODE_WAIT_MAX_BACKOFF_100MS);
+ if (atomic) {
+ /* don't overflow udelay */
+ wait = min_t(int, wait, (MAX_UDELAY_MS * 1000);
+ udelay(wait));
+ } else {
usleep_range(wait, wait << 1);
- wait <<= 1;
+ }
}
return -ETIMEDOUT;
base-commit: 2cd78713d917a02987f21b437561a5e1e13ddda2
--
2.43.0