summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/vc4
diff options
context:
space:
mode:
authorJames Hughes <james.hughes@raspberrypi.com>2020-02-17 15:31:45 +0000
committerEric Anholt <eric@anholt.net>2020-03-04 22:15:27 -0800
commit7f2a09ecf2e8d86e22598dfb879db48e72c5a40e (patch)
tree312662a816ec48e039e1a22f9602ccf430cff42a /drivers/gpu/drm/vc4
parent83794ee6c13b41c7db86ccfcaa20dc360b08fdb6 (diff)
drm/vc4: Replace wait_for macros to remove use of msleep
The wait_for macro's for Broadcom VC4 driver used msleep, which is inappropriate due to its inaccuracy at low values (minimum wait time is about 30ms on the Raspberry Pi). This sleep was triggering in v3d_clean_caches(), causing us to only be able to dispatch ~33 compute jobs per second. This patch replaces the macro with the one from the Intel i915 version which uses usleep_range to provide more accurate waits. v2: Split from the v3d patch in case this tickles modesetting bugs (by anholt) Signed-off-by: James Hughes <james.hughes@raspberrypi.com> Signed-off-by: Eric Anholt <eric@anholt.net> Link: https://patchwork.freedesktop.org/patch/msgid/20200217153145.13780-1-james.hughes@raspberrypi.com
Diffstat (limited to 'drivers/gpu/drm/vc4')
-rw-r--r--drivers/gpu/drm/vc4/vc4_drv.h43
1 files changed, 26 insertions, 17 deletions
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index f90c0d08e740..26d1d5886352 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -677,32 +677,41 @@ struct vc4_validated_shader_info {
};
/**
- * _wait_for - magic (register) wait macro
+ * __wait_for - magic wait macro
*
- * Does the right thing for modeset paths when run under kdgb or similar atomic
- * contexts. Note that it's important that we check the condition again after
- * having timed out, since the timeout could be due to preemption or similar and
- * we've never had a chance to check the condition before the timeout.
+ * Macro to help avoid open coding check/wait/timeout patterns. Note that it's
+ * important that we check the condition again after having timed out, since the
+ * timeout could be due to preemption or similar and we've never had a chance to
+ * check the condition before the timeout.
*/
-#define _wait_for(COND, MS, W) ({ \
- unsigned long timeout__ = jiffies + msecs_to_jiffies(MS) + 1; \
- int ret__ = 0; \
- while (!(COND)) { \
- if (time_after(jiffies, timeout__)) { \
- if (!(COND)) \
- ret__ = -ETIMEDOUT; \
+#define __wait_for(OP, COND, US, Wmin, Wmax) ({ \
+ const ktime_t end__ = ktime_add_ns(ktime_get_raw(), 1000ll * (US)); \
+ long wait__ = (Wmin); /* recommended min for usleep is 10 us */ \
+ int ret__; \
+ might_sleep(); \
+ for (;;) { \
+ const bool expired__ = ktime_after(ktime_get_raw(), end__); \
+ OP; \
+ /* Guarantee COND check prior to timeout */ \
+ barrier(); \
+ if (COND) { \
+ ret__ = 0; \
break; \
} \
- if (W && drm_can_sleep()) { \
- msleep(W); \
- } else { \
- cpu_relax(); \
+ if (expired__) { \
+ ret__ = -ETIMEDOUT; \
+ break; \
} \
+ usleep_range(wait__, wait__ * 2); \
+ if (wait__ < (Wmax)) \
+ wait__ <<= 1; \
} \
ret__; \
})
-#define wait_for(COND, MS) _wait_for(COND, MS, 1)
+#define _wait_for(COND, US, Wmin, Wmax) __wait_for(, (COND), (US), (Wmin), \
+ (Wmax))
+#define wait_for(COND, MS) _wait_for((COND), (MS) * 1000, 10, 1000)
/* vc4_bo.c */
struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size);