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

Reply via email to