Skip to content

Commit

Permalink
drm/i915: fix up _wait_for macro
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Daniel Vetter committed Mar 28, 2013
1 parent 6effa33 commit 1d5bfac
Showing 1 changed file with 11 additions and 2 deletions.
13 changes: 11 additions & 2 deletions drivers/gpu/drm/i915/intel_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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()) { \
Expand Down

0 comments on commit 1d5bfac

Please sign in to comment.