Skip to content

freedreno: Handle timeout == PIPE_TIMEOUT_INFINITE and rollover

The fd_fence_finish() may be passed a special timeout value PIPE_TIMEOUT_INFINITE. This gets propagated all the way to get_abs_timeout(), where it gets converted to a huge timeout value and passed down to the kernel. At least on iMX53, the kernel may complain about this value being too large and emit a backtrace. The relevant piece of information there is the following:

schedule_timeout: wrong timeout value bf94984b

Per suggestion by Rob Clark, fix this in get_abs_timeout() by picking the same rollover implementation present in etnaviv. This fixes one part of the problem where the tv_nsec becomes larger than NSEC_PER_SEC, which is invalid.

However, the PIPE_TIMEOUT_INFINITE is sufficiently large to make tv_secs larger than KTIME_SEC_MAX, which makes kernel-side ktime_set() return KTIME_MAX and that in turn triggers the above "wrong timeout value N" message. Fix this by setting the timeout to large enough value in case of PIPE_TIMEOUT_INFINITE. While the timeout is not truly infinite, the timeout is long enough as anything longer than a few seconds means the GPU got hung.

The "util/timespec.h" is added so we can use NSEC_PER_SEC instead of ad-hoc constant 1000000000 . The "pipe/p_defines.h" is needed for PIPE_TIMEOUT_INFINITE.

This problem can be reliably triggered on iMX53 using Qt5 with EGLFS support, using the qtbase examples, as follows:

/usr/share/examples/opengl/qopenglwidget/qopenglwidget -platform eglfs

Fixes: f3cc0d27 ("freedreno: import libdrm_freedreno + redesign submit")

Paging @flto @robclark

Merge request reports