Module Name: src Committed By: martin Date: Mon Oct 30 17:45:10 UTC 2023
Modified Files: src/sys/dev/usb [netbsd-10]: ehci.c Log Message: Pull up following revision(s) (requested by riastradh in ticket #440): sys/dev/usb/ehci.c: revision 1.318 sys/dev/usb/ehci.c: revision 1.319 ehci(4): Fix cv_timedwait loop in ehci_sync_hc. Stop when now - starttime >= delta, i.e., when at least delta ticks have elapsed since the start, not when endtime - now > delta, i.e., more than delta ticks _remain_ to sleep, which is never going to happen (except on arithmetic overflow). As is, what will happen in the case that should time out is that we wake up after delta ticks, and find now = getticks() is exactly endtime, so we retry cv_timedwait with timo=(endtime - now)=0 which means sleep indefinitely with no timeout as if with cv_wait. PR port-i386/57662 ehci(4): Fix bug causing missed wakeups since ehci.c 1.308. For reasons beyond me now, I used cv_signal on the same cv that is used to wait for the doorbell to be available _and_ to wait for the host controller to acknowledge the doorbell. Which means when the host controller acknowledges the doorbell, we might wake some thread waiting for the doorbell to be available -- and leave the thread waiting for the doorbell acknowledgment hanging indefinitely. PR port-i386/57662 To generate a diff of this commit: cvs rdiff -u -r1.315.2.1 -r1.315.2.2 src/sys/dev/usb/ehci.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/usb/ehci.c diff -u src/sys/dev/usb/ehci.c:1.315.2.1 src/sys/dev/usb/ehci.c:1.315.2.2 --- src/sys/dev/usb/ehci.c:1.315.2.1 Wed Aug 2 10:20:38 2023 +++ src/sys/dev/usb/ehci.c Mon Oct 30 17:45:10 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: ehci.c,v 1.315.2.1 2023/08/02 10:20:38 martin Exp $ */ +/* $NetBSD: ehci.c,v 1.315.2.2 2023/10/30 17:45:10 martin Exp $ */ /* * Copyright (c) 2004-2012,2016,2020 The NetBSD Foundation, Inc. @@ -54,7 +54,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.315.2.1 2023/08/02 10:20:38 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.315.2.2 2023/10/30 17:45:10 martin Exp $"); #include "ohci.h" #include "uhci.h" @@ -821,7 +821,7 @@ ehci_doorbell(void *addr) if (sc->sc_doorbelllwp == NULL) DPRINTF("spurious doorbell interrupt", 0, 0, 0, 0); sc->sc_doorbelllwp = NULL; - cv_signal(&sc->sc_doorbell); + cv_broadcast(&sc->sc_doorbell); mutex_exit(&sc->sc_lock); } @@ -2272,9 +2272,9 @@ ehci_sync_hc(ehci_softc_t *sc) */ while (sc->sc_doorbelllwp == curlwp) { now = getticks(); - if (endtime - now > delta) { + if (now - starttime >= delta) { sc->sc_doorbelllwp = NULL; - cv_signal(&sc->sc_doorbell); + cv_broadcast(&sc->sc_doorbell); DPRINTF("doorbell timeout", 0, 0, 0, 0); #ifdef DIAGNOSTIC /* XXX DIAGNOSTIC abuse, do this differently */ printf("ehci_sync_hc: timed out\n");