DF-5235 / fix.diff
--- a/sys/dev/drm/include/linux/completion.h +++ b/sys/dev/drm/include/linux/completion.h @@ -80,14 +80,23 @@ unsigned long timeout, int flags) { int start_jiffies, elapsed_jiffies, remaining_jiffies; + int timo; bool timeout_expired = false, awakened = false; long ret = 1; + /* + * lksleep()'s timo is an int. MAX_SCHEDULE_TIMEOUT (LONG_MAX) does + * not fit and truncates to -1, which _callout_setup_quick() clamps + * to the *next* tick -- turning every "infinite" completion wait + * into a ~1-tick wait. Convert exactly like schedule_timeout() in + * linux/sched.h does: 0 means "no timeout" for tsleep/lksleep. + */ + timo = (timeout >= INT_MAX) ? 0 : (int)timeout; start_jiffies = ticks; lockmgr(&c->wait.lock, LK_EXCLUSIVE); while (c->done == 0 && !timeout_expired) { - ret = lksleep(&c->wait, &c->wait.lock, flags, "lwfcg", timeout); + ret = lksleep(&c->wait, &c->wait.lock, flags, "lwfcg", timo); switch(ret) { case EWOULDBLOCK: timeout_expired = true; |