drm/i915: fix up _wait_for macro
As Thomas Gleixner spotted, it's rather horrible racy: - We can miss almost a full tick, so need to compensate by 1 jiffy. - We need to re-check the condition when having timed-out, since a the last check could have been before the timeout expired. E.g. when we've been preempted or a long irq happened. Cc: Thomas Gleixner <tglx@linutronix.de> Reported-by: Jack Winter <jbh@alchemy.lu> Cc: Jack Winter <jbh@alchemy.lu> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
6effa33b73
commit
1d5bfac96f
|
@ -33,12 +33,21 @@
|
|||
#include <drm/drm_fb_helper.h>
|
||||
#include <drm/drm_dp_helper.h>
|
||||
|
||||
/**
|
||||
* _wait_for - magic (register) 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.
|
||||
*/
|
||||
#define _wait_for(COND, MS, W) ({ \
|
||||
unsigned long timeout__ = jiffies + msecs_to_jiffies(MS); \
|
||||
unsigned long timeout__ = jiffies + msecs_to_jiffies(MS) + 1; \
|
||||
int ret__ = 0; \
|
||||
while (!(COND)) { \
|
||||
if (time_after(jiffies, timeout__)) { \
|
||||
ret__ = -ETIMEDOUT; \
|
||||
if (!(COND)) \
|
||||
ret__ = -ETIMEDOUT; \
|
||||
break; \
|
||||
} \
|
||||
if (W && drm_can_sleep()) { \
|
||||
|
|
Loading…
Reference in New Issue