[PATCH] sna: avoid negative timeouts
Chris Wilson
chris at chris-wilson.co.uk
Thu Oct 3 01:17:12 PDT 2013
On Thu, Oct 03, 2013 at 03:06:03AM -0500, Felipe Contreras wrote:
> On Thu, Oct 3, 2013 at 2:36 AM, Chris Wilson <chris at chris-wilson.co.uk> wrote:
> > On Thu, Oct 03, 2013 at 01:29:29AM -0500, Felipe Contreras wrote:
> >> It's nice to avoid X server crashes (by not passing negative values to
> >> select(3)).
> >>
> >> For more information:
> >> http://article.gmane.org/gmane.comp.freedesktop.xorg.devel/37388
> >>
> >> Signed-off-by: Felipe Contreras <felipe.contreras at gmail.com>
> >
> > Thanks for the patch, I pushed a slightly different version to consume
> > the expired flush timeout immediately.
> >
> > However, in order for this to happen something within the BlockHandler
> > must have run for at least 4ms. Which is itself very worrying - the two
> > candidates are the throttle or lock contention. (The throttle is also
> > prone to being influenced by a third party.) Such stalls are likely to
> > be noticeable as jitter or judder, so if you can spot their source
> > hopefully we can tackle the root cause.
>
> What exactly do you mean by third party? I wouldn't notice if there
> was jitter because it's a loading screen, and there's absolutely no
> updates on the screen; it's static.
Other users of /dev/dri/card0. The most likely cause for the delay here
is waiting for the GPU to complete an operation or for waiting for
access to the GPU.
> Do you mean you would like me to add debugging in
> sna_accel_block_handler() to figure exactly which block is taking too
> long to complete?
Right, if you do something like:
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 21cd342..31ea1a3 100644
@@ -15931,6 +15931,8 @@ void sna_accel_close(struct sna *sna)
void sna_accel_block_handler(struct sna *sna, struct timeval **tv)
{
+ uint32_t duration[NUM_TIMERS] = { 0 };
+
sigtrap_assert();
if (sna->kgem.need_retire)
@@ -15947,19 +15949,28 @@ void sna_accel_block_handler(struct sna *sna, struct timeval **tv)
}
restart:
- if (sna_accel_do_flush(sna))
+ if (sna_accel_do_flush(sna)) {
+ duration[FLUSH_TIMER] = TIME;
sna_accel_flush(sna);
+ duration[FLUSH_TIMER] = TIME - duration[FLUSH_TIMER];
+ }
assert(sna_accel_scanout(sna) == NULL ||
sna_accel_scanout(sna)->gpu_bo->exec == NULL ||
sna->timer_active & (1<<(FLUSH_TIMER)));
- if (sna_accel_do_throttle(sna))
+ if (sna_accel_do_throttle(sna)) {
+ duration[THROTTLE_TIMER] = TIME;
sna_accel_throttle(sna);
+ duration[THROTTLE_TIMER] = TIME - duration[THROTTLE_TIMER];
+ }
assert(!sna->kgem.need_retire ||
sna->timer_active & (1<<(THROTTLE_TIMER)));
- if (sna_accel_do_expire(sna))
+ if (sna_accel_do_expire(sna)) {
+ duration[EXPIRE_TIMER] = TIME;
sna_accel_expire(sna);
+ duration[EXPIRE_TIMER] = TIME - duration[EXPIRE_TIMER];
+ }
assert(!sna->kgem.need_expire ||
sna->timer_active & (1<<(EXPIRE_TIMER)));
@@ -15981,8 +15992,14 @@ restart:
timeout = sna->timer_expire[FLUSH_TIMER] - TIME;
DBG(("%s: flush timer expires in %d [%d]\n",
__FUNCTION__, timeout, sna->timer_expire[FLUSH_TIMER]));
- if (timeout < 3)
+ if (timeout < 3) {
+ ErrorF("restarting timeout[%d] (%d, %d, %d)\n",
+ timeout,
+ duration[FLUSH_TIMER],
+ duration[THROTTLE_TIMER],
+ duration[EXPIRE_TIMER]);
goto restart;
+ }
if (*tv == NULL) {
*tv = &sna->timer_tv;
That will hopefully catch which path is consuming too much time
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
More information about the xorg-devel
mailing list