aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_drv.h
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2013-03-27 19:03:25 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-03-28 11:41:13 -0400
commit1d5bfac96f1e1856fbdb3f06679691e5b9c2ba8f (patch)
treee0ab711e8c18a05f5e08021e708ff287e20247b0 /drivers/gpu/drm/i915/intel_drv.h
parent6effa33b73fb0129061ecd8ba3158d984475d35d (diff)
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>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_drv.h')
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h13
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 8720a67395f8..18bba6e25e1e 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -33,12 +33,21 @@
33#include <drm/drm_fb_helper.h> 33#include <drm/drm_fb_helper.h>
34#include <drm/drm_dp_helper.h> 34#include <drm/drm_dp_helper.h>
35 35
36/**
37 * _wait_for - magic (register) wait macro
38 *
39 * Does the right thing for modeset paths when run under kdgb or similar atomic
40 * contexts. Note that it's important that we check the condition again after
41 * having timed out, since the timeout could be due to preemption or similar and
42 * we've never had a chance to check the condition before the timeout.
43 */
36#define _wait_for(COND, MS, W) ({ \ 44#define _wait_for(COND, MS, W) ({ \
37 unsigned long timeout__ = jiffies + msecs_to_jiffies(MS); \ 45 unsigned long timeout__ = jiffies + msecs_to_jiffies(MS) + 1; \
38 int ret__ = 0; \ 46 int ret__ = 0; \
39 while (!(COND)) { \ 47 while (!(COND)) { \
40 if (time_after(jiffies, timeout__)) { \ 48 if (time_after(jiffies, timeout__)) { \
41 ret__ = -ETIMEDOUT; \ 49 if (!(COND)) \
50 ret__ = -ETIMEDOUT; \
42 break; \ 51 break; \
43 } \ 52 } \
44 if (W && drm_can_sleep()) { \ 53 if (W && drm_can_sleep()) { \