backend-drm: improve atomic commit failure handling

When an atomic commit fails then the output will be stuck in
REPAINT_AWAITING_COMPLETION state. It is waiting for a vblank event that was
never scheduled.
If the error is EBUSY then it can be expected to be a transient error. So
propagate the error and schedule a new repaint in the core compositor.

This is necessary because there are some circumstances when the commit can fail
unexpectedly:
- With 'state_invalid == true' one commit will disable all planes. If another
  commit for a different output is triggered immediately afterwards, then this
  commit can temporarily fail with EBUSY because it tries to use the same
  planes.
- At least with i915, if one commit enables an output then a second commit for a
  different output immediately afterwards can temporarily fail with EBUSY. This
  is probably caused by some hardware interdependency.

Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
This commit is contained in:
Michael Olbrich
2022-06-22 08:22:06 +02:00
parent d4eafbaa98
commit 3b3fdc52c3
2 changed files with 26 additions and 6 deletions
+3 -3
View File
@@ -593,8 +593,8 @@ drm_output_start_repaint_loop(struct weston_output *output_base)
if (ret != 0) {
weston_log("applying repaint-start state failed: %s\n",
strerror(errno));
if (ret == -EACCES)
return -1;
if (ret == -EACCES || ret == -EBUSY)
return ret;
goto finish_frame;
}
@@ -657,7 +657,7 @@ drm_repaint_flush(struct weston_compositor *compositor)
drm_debug(b, "[repaint] flushed pending_state %p\n", pending_state);
device->repaint_data = NULL;
return (ret == -EACCES) ? -1 : 0;
return (ret == -EACCES || ret == -EBUSY) ? ret : 0;
}
/**