From nobody Wed Jan 01 05:48:15 2025 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4YNJlz5F6yz5jNhh; Wed, 01 Jan 2025 05:48:15 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4YNJlz4Ztwz4Q8P; Wed, 1 Jan 2025 05:48:15 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1735710495; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=T2bymZ2ZH+NrU/unUp7bk6xyOHxhbOycp2YVE9wFJbY=; b=rKkN/DS0S/wdZORnJW8o+VcAQ2p29dvq71FTuz1NOo0866Kc8AUrPHz9Rr+EOsbISITe4x DsmyFkGhoYJFEziCNfHJV0yPm1GrkyGbzIlI0CenW98R6MPHOO94ZuDmchqZlpz8Yv9kdi +dLMSOedV94BuR4hroJ62U9uiO8gQWezEsG1y47EQVKKzlS3l8SfYyvAfkD3c3JCyKwnYB m7V9h1oHejcpGqy4O8Kb+KG37aRBzqu13RftcH7li9r81FOsfJOPtetwAfa3Tfoca1dEFU /0qVo0JagZpGhN3VYAb6GwvEtGFZBXuvfxUGAqHHJXdNQ0hX9txyEdnYbP5ChQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1735710495; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=T2bymZ2ZH+NrU/unUp7bk6xyOHxhbOycp2YVE9wFJbY=; b=lLxH1Lniqs/sLj01eoG7LkYw0xHqu/ykCvBgrtCPLM4reHAU9AQHAWA6OGVaxubqhmJHgk ybw0aq4iRiB8DgdyvM/zrY/flzEXrZcKSHyFxdpGf3UtRz7oavDnJIfYvGNsZONd0cR2DW Go3Y8+VIIGCEPxxyUZukjLdIhkwI43EU1YHsSCUXAj509dCZMT1Owt8YiJiJD6RB0vy/IV qpW0COt7g3v6tLvhbWVsAfEuO5wix23WKXo1Y3AjQYB+JL5L4Jy4u8rx13zd00r8L9R8lg jALZc0mXvEVvn0S6p5ulIrHhjb1njIASkKtglbg9ujC2XIRCswMCfkTP4/J8hQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1735710495; a=rsa-sha256; cv=none; b=BqHj/EwE1JSNuCCWd+PT94ucme0xq5TxW2TcAPzeS70ltWUJid4bD+VqXaw268y/JBlg0V cNZewq5Xaa9Z8TyrIg//Iwf4yrG65E0Vklr7Z/LDwTKFNMSZC3KwNX/VavBkBnI93GS42T tORyht184qe6Cx/51T9XV1Rbxrw8yw9SA7S5Cj3UdsEC4F9Hwi6wwiBNGnDXGOqcYjOu6z x59qEGAXcoTgsWsyGwVfYvl3DU1ndaRuuGjHLm38EoqqYDAzeCHhiZ0V5hM1yYdUW+dwHD G9bn/E8d5ePHwisw6QpUDHtsmVleYVNYRqWV8UOrLppESc7UuHdJteLUFNX3HQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4YNJlz49rMz1BDb; Wed, 1 Jan 2025 05:48:15 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 5015mFXc039303; Wed, 1 Jan 2025 05:48:15 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 5015mFes039300; Wed, 1 Jan 2025 05:48:15 GMT (envelope-from git) Date: Wed, 1 Jan 2025 05:48:15 GMT Message-Id: <202501010548.5015mFes039300@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kyle Evans Subject: git: 0fb0a408a13c - stable/13 - usb: serial: allow the open/close sleep to be interruptible List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kevans X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 0fb0a408a13c7ec7ff6834a213aede35b26419fa Auto-Submitted: auto-generated The branch stable/13 has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=0fb0a408a13c7ec7ff6834a213aede35b26419fa commit 0fb0a408a13c7ec7ff6834a213aede35b26419fa Author: Kyle Evans AuthorDate: 2024-12-11 01:23:10 +0000 Commit: Kyle Evans CommitDate: 2025-01-01 05:47:47 +0000 usb: serial: allow the open/close sleep to be interruptible ucom_queue_command will issue commands for open/close, then wait on them to be finished. In the spirit of playing it safe, allow ucom_queue_command's wait to be interrupted in case the usb process gets jammed up waiting on the hardware -- we can at least recover the user thread that initiated it, even if we can't recover the usb process. Reviewed by: imp, kib (cherry picked from commit 729eb176a465cedc55c5980f116d87be592421f1) --- sys/dev/usb/serial/usb_serial.c | 14 +++++++-- sys/dev/usb/usb_process.c | 69 ++++++++++++++++++++++++++++++++--------- sys/dev/usb/usb_process.h | 1 + sys/dev/usb/usbdi.h | 2 ++ 4 files changed, 69 insertions(+), 17 deletions(-) diff --git a/sys/dev/usb/serial/usb_serial.c b/sys/dev/usb/serial/usb_serial.c index 8787d4fe3381..ce9e0ec62bb5 100644 --- a/sys/dev/usb/serial/usb_serial.c +++ b/sys/dev/usb/serial/usb_serial.c @@ -599,6 +599,7 @@ ucom_queue_command(struct ucom_softc *sc, { struct ucom_super_softc *ssc = sc->sc_super; struct ucom_param_task *task; + int error; UCOM_MTX_ASSERT(sc, MA_OWNED); @@ -628,8 +629,15 @@ ucom_queue_command(struct ucom_softc *sc, /* * Closing or opening the device should be synchronous. */ - if (fn == ucom_cfg_close || fn == ucom_cfg_open) - usb_proc_mwait(&ssc->sc_tq, t0, t1); + if (fn == ucom_cfg_close || fn == ucom_cfg_open) { + error = usb_proc_mwait_sig(&ssc->sc_tq, t0, t1); + + /* usb_proc_mwait_sig may have dropped the tty lock. */ + if (error == 0 && sc->sc_tty != NULL && tty_gone(sc->sc_tty)) + error = ENXIO; + } else { + error = 0; + } /* * In case of multiple configure requests, @@ -638,7 +646,7 @@ ucom_queue_command(struct ucom_softc *sc, if (fn == ucom_cfg_start_transfers) sc->sc_last_start_xfer = &task->hdr; - return (0); + return (error); } static void diff --git a/sys/dev/usb/usb_process.c b/sys/dev/usb/usb_process.c index d88de92336f2..4507c999f50a 100644 --- a/sys/dev/usb/usb_process.c +++ b/sys/dev/usb/usb_process.c @@ -361,25 +361,21 @@ usb_proc_is_gone(struct usb_process *up) return (0); } -/*------------------------------------------------------------------------* - * usb_proc_mwait - * - * This function will return when the USB process message pointed to - * by "pm" is no longer on a queue. This function must be called - * having "up->up_mtx" locked. - *------------------------------------------------------------------------*/ -void -usb_proc_mwait(struct usb_process *up, void *_pm0, void *_pm1) +static int +usb_proc_mwait_impl(struct usb_process *up, void *_pm0, void *_pm1, + bool interruptible) { struct usb_proc_msg *pm0 = _pm0; struct usb_proc_msg *pm1 = _pm1; + int error; /* check if gone */ if (up->up_gone) - return; + return (ENXIO); USB_MTX_ASSERT(up->up_mtx, MA_OWNED); + error = 0; if (up->up_curtd == curthread) { /* Just remove the messages from the queue. */ if (pm0->pm_qentry.tqe_prev) { @@ -391,14 +387,59 @@ usb_proc_mwait(struct usb_process *up, void *_pm0, void *_pm1) pm1->pm_qentry.tqe_prev = NULL; } } else - while (pm0->pm_qentry.tqe_prev || - pm1->pm_qentry.tqe_prev) { + while (error == 0 && (pm0->pm_qentry.tqe_prev || + pm1->pm_qentry.tqe_prev)) { /* check if config thread is gone */ if (up->up_gone) - break; + return (ENXIO); up->up_dsleep = 1; - cv_wait(&up->up_drain, up->up_mtx); + if (interruptible) { + error = cv_wait_sig(&up->up_drain, up->up_mtx); + + /* + * The fact that we were interrupted doesn't + * matter if our goal was accomplished anyways. + */ + if (error != 0 && !USB_PROC_MSG_ENQUEUED(pm0) && + !USB_PROC_MSG_ENQUEUED(pm1)) + error = 0; + } else { + cv_wait(&up->up_drain, up->up_mtx); + } } + + if (error == ERESTART) + error = EINTR; + return (error); +} + +/*------------------------------------------------------------------------* + * usb_proc_mwait + * + * This function will return when the USB process message pointed to + * by "pm" is no longer on a queue. This function must be called + * having "up->up_mtx" locked. + *------------------------------------------------------------------------*/ +void +usb_proc_mwait(struct usb_process *up, void *_pm0, void *_pm1) +{ + + (void)usb_proc_mwait_impl(up, _pm0, _pm1, false); +} + +/*------------------------------------------------------------------------* + * usb_proc_mwait_sig + * + * This function will return when the USB process message pointed to + * by "pm" is no longer on a queue. This function must be called + * having "up->up_mtx" locked. This version of usb_proc_mwait is + * interruptible. + *------------------------------------------------------------------------*/ +int +usb_proc_mwait_sig(struct usb_process *up, void *_pm0, void *_pm1) +{ + + return (usb_proc_mwait_impl(up, _pm0, _pm1, true)); } /*------------------------------------------------------------------------* diff --git a/sys/dev/usb/usb_process.h b/sys/dev/usb/usb_process.h index 6a8ac0acda33..745d214d2106 100644 --- a/sys/dev/usb/usb_process.h +++ b/sys/dev/usb/usb_process.h @@ -76,6 +76,7 @@ int usb_proc_create(struct usb_process *up, struct mtx *p_mtx, const char *pmesg, uint8_t prio); void usb_proc_drain(struct usb_process *up); void usb_proc_mwait(struct usb_process *up, void *pm0, void *pm1); +int usb_proc_mwait_sig(struct usb_process *up, void *pm0, void *pm1); void usb_proc_free(struct usb_process *up); void *usb_proc_msignal(struct usb_process *up, void *pm0, void *pm1); void usb_proc_rewakeup(struct usb_process *up); diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h index 5192591281f4..08d130aa2868 100644 --- a/sys/dev/usb/usbdi.h +++ b/sys/dev/usb/usbdi.h @@ -525,6 +525,8 @@ struct usb_proc_msg { usb_size_t pm_num; }; +#define USB_PROC_MSG_ENQUEUED(msg) ((msg)->pm_qentry.tqe_prev != NULL) + #define USB_FIFO_TX 0 #define USB_FIFO_RX 1