* [PATCH v4] drm/i915: Wait for PSR exit before checking for vblank evasion
@ 2018-06-22 9:01 Tarun Vyas
2018-06-22 9:26 ` ✗ Fi.CI.BAT: failure for " Patchwork
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Tarun Vyas @ 2018-06-22 9:01 UTC (permalink / raw)
To: intel-gfx; +Cc: dhinakaran.pandiyan, rodrigo.vivi
The PIPEDSL freezes on PSR entry and if PSR hasn't fully exited, then
the pipe_update_start call schedules itself out to check back later.
On ChromeOS-4.4 kernel, which is fairly up-to-date w.r.t drm/i915 but
lags w.r.t core kernel code, hot plugging an external display triggers
tons of "potential atomic update errors" in the dmesg, on *pipe A*. A
closer analysis reveals that we try to read the scanline 3 times and
eventually timeout, b/c PSR hasn't exited fully leading to a PIPEDSL
stuck @ 1599. This issue is not seen on upstream kernels, b/c for *some*
reason we loop inside intel_pipe_update start for ~2+ msec which in this
case is more than enough to exit PSR fully, hence an *unstuck* PIPEDSL
counter, hence no error. On the other hand, the ChromeOS kernel spends
~1.1 msec looping inside intel_pipe_update_start and hence errors out
b/c the source is still in PSR.
Regardless, we should wait for PSR exit (if PSR is disabled, we incur
a ~1-2 usec penalty) before reading the PIPEDSL, b/c if we haven't
fully exited PSR, then checking for vblank evasion isn't actually
applicable.
v4: Comment explaining psr_wait after enabling VBL interrupts (DK)
Signed-off-by: Tarun Vyas <tarun.vyas@intel.com>
---
drivers/gpu/drm/i915/intel_sprite.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 344c0e709b19..3a4ad6fed246 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -107,14 +107,22 @@ void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state)
VBLANK_EVASION_TIME_US);
max = vblank_start - 1;
- local_irq_disable();
-
if (min <= 0 || max <= 0)
return;
if (WARN_ON(drm_crtc_vblank_get(&crtc->base)))
return;
+ /*
+ * Wait for psr to idle out after enabling the VBL interrupts
+ * VBL interrupts will start the PSR exit and prevent a PSR
+ * re-entry as well.
+ */
+ if (intel_psr_wait_for_idle(dev_priv))
+ DRM_ERROR("PSR idle timed out, atomic update may fail\n");
+
+ local_irq_disable();
+
crtc->debug.min_vbl = min;
crtc->debug.max_vbl = max;
trace_i915_pipe_update_start(crtc);
--
2.13.5
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 4+ messages in thread* ✗ Fi.CI.BAT: failure for drm/i915: Wait for PSR exit before checking for vblank evasion
2018-06-22 9:01 [PATCH v4] drm/i915: Wait for PSR exit before checking for vblank evasion Tarun Vyas
@ 2018-06-22 9:26 ` Patchwork
2018-06-22 10:35 ` [PATCH v4] " kbuild test robot
2018-06-22 10:37 ` kbuild test robot
2 siblings, 0 replies; 4+ messages in thread
From: Patchwork @ 2018-06-22 9:26 UTC (permalink / raw)
To: Tarun Vyas; +Cc: intel-gfx
== Series Details ==
Series: drm/i915: Wait for PSR exit before checking for vblank evasion
URL : https://patchwork.freedesktop.org/series/45235/
State : failure
== Summary ==
CALL scripts/checksyscalls.sh
DESCEND objtool
CHK include/generated/compile.h
CC [M] drivers/gpu/drm/i915/intel_sprite.o
drivers/gpu/drm/i915/intel_sprite.c: In function ‘intel_pipe_update_start’:
drivers/gpu/drm/i915/intel_sprite.c:121:6: error: implicit declaration of function ‘intel_psr_wait_for_idle’; did you mean ‘i915_gem_wait_for_idle’? [-Werror=implicit-function-declaration]
if (intel_psr_wait_for_idle(dev_priv))
^~~~~~~~~~~~~~~~~~~~~~~
i915_gem_wait_for_idle
cc1: all warnings being treated as errors
scripts/Makefile.build:317: recipe for target 'drivers/gpu/drm/i915/intel_sprite.o' failed
make[4]: *** [drivers/gpu/drm/i915/intel_sprite.o] Error 1
scripts/Makefile.build:558: recipe for target 'drivers/gpu/drm/i915' failed
make[3]: *** [drivers/gpu/drm/i915] Error 2
scripts/Makefile.build:558: recipe for target 'drivers/gpu/drm' failed
make[2]: *** [drivers/gpu/drm] Error 2
scripts/Makefile.build:558: recipe for target 'drivers/gpu' failed
make[1]: *** [drivers/gpu] Error 2
Makefile:1034: recipe for target 'drivers' failed
make: *** [drivers] Error 2
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH v4] drm/i915: Wait for PSR exit before checking for vblank evasion
2018-06-22 9:01 [PATCH v4] drm/i915: Wait for PSR exit before checking for vblank evasion Tarun Vyas
2018-06-22 9:26 ` ✗ Fi.CI.BAT: failure for " Patchwork
@ 2018-06-22 10:35 ` kbuild test robot
2018-06-22 10:37 ` kbuild test robot
2 siblings, 0 replies; 4+ messages in thread
From: kbuild test robot @ 2018-06-22 10:35 UTC (permalink / raw)
To: Tarun Vyas; +Cc: intel-gfx, rodrigo.vivi, kbuild-all, dhinakaran.pandiyan
[-- Attachment #1: Type: text/plain, Size: 5619 bytes --]
Hi Tarun,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on drm-intel/for-linux-next]
[also build test ERROR on v4.18-rc1 next-20180622]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Tarun-Vyas/drm-i915-Wait-for-PSR-exit-before-checking-for-vblank-evasion/20180622-175933
base: git://anongit.freedesktop.org/drm-intel for-linux-next
config: x86_64-randconfig-x011-201824 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All errors (new ones prefixed by >>):
drivers/gpu//drm/i915/intel_sprite.c: In function 'intel_pipe_update_start':
>> drivers/gpu//drm/i915/intel_sprite.c:121:6: error: implicit declaration of function 'intel_psr_wait_for_idle'; did you mean 'i915_gem_wait_for_idle'? [-Werror=implicit-function-declaration]
if (intel_psr_wait_for_idle(dev_priv))
^~~~~~~~~~~~~~~~~~~~~~~
i915_gem_wait_for_idle
cc1: some warnings being treated as errors
vim +121 drivers/gpu//drm/i915/intel_sprite.c
76
77 /**
78 * intel_pipe_update_start() - start update of a set of display registers
79 * @new_crtc_state: the new crtc state
80 *
81 * Mark the start of an update to pipe registers that should be updated
82 * atomically regarding vblank. If the next vblank will happens within
83 * the next 100 us, this function waits until the vblank passes.
84 *
85 * After a successful call to this function, interrupts will be disabled
86 * until a subsequent call to intel_pipe_update_end(). That is done to
87 * avoid random delays.
88 */
89 void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state)
90 {
91 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
92 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
93 const struct drm_display_mode *adjusted_mode = &new_crtc_state->base.adjusted_mode;
94 long timeout = msecs_to_jiffies_timeout(1);
95 int scanline, min, max, vblank_start;
96 wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base);
97 bool need_vlv_dsi_wa = (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
98 intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI);
99 DEFINE_WAIT(wait);
100
101 vblank_start = adjusted_mode->crtc_vblank_start;
102 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
103 vblank_start = DIV_ROUND_UP(vblank_start, 2);
104
105 /* FIXME needs to be calibrated sensibly */
106 min = vblank_start - intel_usecs_to_scanlines(adjusted_mode,
107 VBLANK_EVASION_TIME_US);
108 max = vblank_start - 1;
109
110 if (min <= 0 || max <= 0)
111 return;
112
113 if (WARN_ON(drm_crtc_vblank_get(&crtc->base)))
114 return;
115
116 /*
117 * Wait for psr to idle out after enabling the VBL interrupts
118 * VBL interrupts will start the PSR exit and prevent a PSR
119 * re-entry as well.
120 */
> 121 if (intel_psr_wait_for_idle(dev_priv))
122 DRM_ERROR("PSR idle timed out, atomic update may fail\n");
123
124 local_irq_disable();
125
126 crtc->debug.min_vbl = min;
127 crtc->debug.max_vbl = max;
128 trace_i915_pipe_update_start(crtc);
129
130 for (;;) {
131 /*
132 * prepare_to_wait() has a memory barrier, which guarantees
133 * other CPUs can see the task state update by the time we
134 * read the scanline.
135 */
136 prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE);
137
138 scanline = intel_get_crtc_scanline(crtc);
139 if (scanline < min || scanline > max)
140 break;
141
142 if (!timeout) {
143 DRM_ERROR("Potential atomic update failure on pipe %c\n",
144 pipe_name(crtc->pipe));
145 break;
146 }
147
148 local_irq_enable();
149
150 timeout = schedule_timeout(timeout);
151
152 local_irq_disable();
153 }
154
155 finish_wait(wq, &wait);
156
157 drm_crtc_vblank_put(&crtc->base);
158
159 /*
160 * On VLV/CHV DSI the scanline counter would appear to
161 * increment approx. 1/3 of a scanline before start of vblank.
162 * The registers still get latched at start of vblank however.
163 * This means we must not write any registers on the first
164 * line of vblank (since not the whole line is actually in
165 * vblank). And unfortunately we can't use the interrupt to
166 * wait here since it will fire too soon. We could use the
167 * frame start interrupt instead since it will fire after the
168 * critical scanline, but that would require more changes
169 * in the interrupt code. So for now we'll just do the nasty
170 * thing and poll for the bad scanline to pass us by.
171 *
172 * FIXME figure out if BXT+ DSI suffers from this as well
173 */
174 while (need_vlv_dsi_wa && scanline == vblank_start)
175 scanline = intel_get_crtc_scanline(crtc);
176
177 crtc->debug.scanline_start = scanline;
178 crtc->debug.start_vbl_time = ktime_get();
179 crtc->debug.start_vbl_count = intel_crtc_get_vblank_counter(crtc);
180
181 trace_i915_pipe_update_vblank_evaded(crtc);
182 }
183
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 34875 bytes --]
[-- Attachment #3: Type: text/plain, Size: 160 bytes --]
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH v4] drm/i915: Wait for PSR exit before checking for vblank evasion
2018-06-22 9:01 [PATCH v4] drm/i915: Wait for PSR exit before checking for vblank evasion Tarun Vyas
2018-06-22 9:26 ` ✗ Fi.CI.BAT: failure for " Patchwork
2018-06-22 10:35 ` [PATCH v4] " kbuild test robot
@ 2018-06-22 10:37 ` kbuild test robot
2 siblings, 0 replies; 4+ messages in thread
From: kbuild test robot @ 2018-06-22 10:37 UTC (permalink / raw)
To: Tarun Vyas; +Cc: intel-gfx, rodrigo.vivi, kbuild-all, dhinakaran.pandiyan
[-- Attachment #1: Type: text/plain, Size: 7476 bytes --]
Hi Tarun,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on drm-intel/for-linux-next]
[also build test WARNING on v4.18-rc1 next-20180622]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Tarun-Vyas/drm-i915-Wait-for-PSR-exit-before-checking-for-vblank-evasion/20180622-175933
base: git://anongit.freedesktop.org/drm-intel for-linux-next
config: x86_64-randconfig-x009-201824 (attached as .config)
compiler: gcc-7 (Debian 7.3.0-16) 7.3.0
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
All warnings (new ones prefixed by >>):
In file included from include/linux/kernel.h:10:0,
from include/linux/list.h:9,
from include/linux/agp_backend.h:33,
from include/drm/drmP.h:35,
from drivers/gpu//drm/i915/intel_sprite.c:32:
drivers/gpu//drm/i915/intel_sprite.c: In function 'intel_pipe_update_start':
drivers/gpu//drm/i915/intel_sprite.c:121:6: error: implicit declaration of function 'intel_psr_wait_for_idle'; did you mean 'i915_gem_wait_for_idle'? [-Werror=implicit-function-declaration]
if (intel_psr_wait_for_idle(dev_priv))
^
include/linux/compiler.h:58:30: note: in definition of macro '__trace_if'
if (__builtin_constant_p(!!(cond)) ? !!(cond) : \
^~~~
>> drivers/gpu//drm/i915/intel_sprite.c:121:2: note: in expansion of macro 'if'
if (intel_psr_wait_for_idle(dev_priv))
^~
cc1: some warnings being treated as errors
vim +/if +121 drivers/gpu//drm/i915/intel_sprite.c
> 32 #include <drm/drmP.h>
33 #include <drm/drm_atomic_helper.h>
34 #include <drm/drm_crtc.h>
35 #include <drm/drm_fourcc.h>
36 #include <drm/drm_rect.h>
37 #include <drm/drm_atomic.h>
38 #include <drm/drm_plane_helper.h>
39 #include "intel_drv.h"
40 #include "intel_frontbuffer.h"
41 #include <drm/i915_drm.h>
42 #include "i915_drv.h"
43
44 bool intel_format_is_yuv(u32 format)
45 {
46 switch (format) {
47 case DRM_FORMAT_YUYV:
48 case DRM_FORMAT_UYVY:
49 case DRM_FORMAT_VYUY:
50 case DRM_FORMAT_YVYU:
51 case DRM_FORMAT_NV12:
52 return true;
53 default:
54 return false;
55 }
56 }
57
58 int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
59 int usecs)
60 {
61 /* paranoia */
62 if (!adjusted_mode->crtc_htotal)
63 return 1;
64
65 return DIV_ROUND_UP(usecs * adjusted_mode->crtc_clock,
66 1000 * adjusted_mode->crtc_htotal);
67 }
68
69 /* FIXME: We should instead only take spinlocks once for the entire update
70 * instead of once per mmio. */
71 #if IS_ENABLED(CONFIG_PROVE_LOCKING)
72 #define VBLANK_EVASION_TIME_US 250
73 #else
74 #define VBLANK_EVASION_TIME_US 100
75 #endif
76
77 /**
78 * intel_pipe_update_start() - start update of a set of display registers
79 * @new_crtc_state: the new crtc state
80 *
81 * Mark the start of an update to pipe registers that should be updated
82 * atomically regarding vblank. If the next vblank will happens within
83 * the next 100 us, this function waits until the vblank passes.
84 *
85 * After a successful call to this function, interrupts will be disabled
86 * until a subsequent call to intel_pipe_update_end(). That is done to
87 * avoid random delays.
88 */
89 void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state)
90 {
91 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
92 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
93 const struct drm_display_mode *adjusted_mode = &new_crtc_state->base.adjusted_mode;
94 long timeout = msecs_to_jiffies_timeout(1);
95 int scanline, min, max, vblank_start;
96 wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base);
97 bool need_vlv_dsi_wa = (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
98 intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI);
99 DEFINE_WAIT(wait);
100
101 vblank_start = adjusted_mode->crtc_vblank_start;
102 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
103 vblank_start = DIV_ROUND_UP(vblank_start, 2);
104
105 /* FIXME needs to be calibrated sensibly */
106 min = vblank_start - intel_usecs_to_scanlines(adjusted_mode,
107 VBLANK_EVASION_TIME_US);
108 max = vblank_start - 1;
109
110 if (min <= 0 || max <= 0)
111 return;
112
113 if (WARN_ON(drm_crtc_vblank_get(&crtc->base)))
114 return;
115
116 /*
117 * Wait for psr to idle out after enabling the VBL interrupts
118 * VBL interrupts will start the PSR exit and prevent a PSR
119 * re-entry as well.
120 */
> 121 if (intel_psr_wait_for_idle(dev_priv))
122 DRM_ERROR("PSR idle timed out, atomic update may fail\n");
123
124 local_irq_disable();
125
126 crtc->debug.min_vbl = min;
127 crtc->debug.max_vbl = max;
128 trace_i915_pipe_update_start(crtc);
129
130 for (;;) {
131 /*
132 * prepare_to_wait() has a memory barrier, which guarantees
133 * other CPUs can see the task state update by the time we
134 * read the scanline.
135 */
136 prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE);
137
138 scanline = intel_get_crtc_scanline(crtc);
139 if (scanline < min || scanline > max)
140 break;
141
142 if (!timeout) {
143 DRM_ERROR("Potential atomic update failure on pipe %c\n",
144 pipe_name(crtc->pipe));
145 break;
146 }
147
148 local_irq_enable();
149
150 timeout = schedule_timeout(timeout);
151
152 local_irq_disable();
153 }
154
155 finish_wait(wq, &wait);
156
157 drm_crtc_vblank_put(&crtc->base);
158
159 /*
160 * On VLV/CHV DSI the scanline counter would appear to
161 * increment approx. 1/3 of a scanline before start of vblank.
162 * The registers still get latched at start of vblank however.
163 * This means we must not write any registers on the first
164 * line of vblank (since not the whole line is actually in
165 * vblank). And unfortunately we can't use the interrupt to
166 * wait here since it will fire too soon. We could use the
167 * frame start interrupt instead since it will fire after the
168 * critical scanline, but that would require more changes
169 * in the interrupt code. So for now we'll just do the nasty
170 * thing and poll for the bad scanline to pass us by.
171 *
172 * FIXME figure out if BXT+ DSI suffers from this as well
173 */
174 while (need_vlv_dsi_wa && scanline == vblank_start)
175 scanline = intel_get_crtc_scanline(crtc);
176
177 crtc->debug.scanline_start = scanline;
178 crtc->debug.start_vbl_time = ktime_get();
179 crtc->debug.start_vbl_count = intel_crtc_get_vblank_counter(crtc);
180
181 trace_i915_pipe_update_vblank_evaded(crtc);
182 }
183
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 29546 bytes --]
[-- Attachment #3: Type: text/plain, Size: 160 bytes --]
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2018-06-22 10:38 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-06-22 9:01 [PATCH v4] drm/i915: Wait for PSR exit before checking for vblank evasion Tarun Vyas
2018-06-22 9:26 ` ✗ Fi.CI.BAT: failure for " Patchwork
2018-06-22 10:35 ` [PATCH v4] " kbuild test robot
2018-06-22 10:37 ` kbuild test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox