mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-22 12:14:01 +08:00
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
This commit is contained in:
parent
83794ee6c1
commit
7f2a09ecf2
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user