git: 824f934bf9d5 - main - tty: make tty_wait_background() aware of proctree_lock ownership

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Sat, 29 Aug 2026 09:43:45 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=824f934bf9d5fcb34dd6c97d650a26823158abf1

commit 824f934bf9d5fcb34dd6c97d650a26823158abf1
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2026-08-24 14:18:35 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-08-29 09:43:00 +0000

    tty: make tty_wait_background() aware of proctree_lock ownership
    
    Reviewed by:    markj
    Tested by:      pho
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D59132
---
 sys/kern/tty.c         | 16 +++++++++++-----
 sys/kern/tty_ttydisc.c | 12 ++++++++----
 sys/sys/tty.h          |  3 ++-
 3 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/sys/kern/tty.c b/sys/kern/tty.c
index ae624227bc3a..e1e9989cee09 100644
--- a/sys/kern/tty.c
+++ b/sys/kern/tty.c
@@ -434,7 +434,8 @@ tty_is_ctty(struct tty *tp, struct proc *p)
 }
 
 int
-tty_wait_background(struct tty *tp, struct thread *td, int sig)
+tty_wait_background(struct tty *tp, struct thread *td, int sig,
+    int proctree_lock_mode)
 {
 	struct proc *p;
 	struct pgrp *pg;
@@ -443,6 +444,9 @@ tty_wait_background(struct tty *tp, struct thread *td, int sig)
 
 	MPASS(sig == SIGTTIN || sig == SIGTTOU);
 	tty_assert_locked(tp);
+	MPASS(proctree_lock_mode == LA_UNLOCKED ||
+	    proctree_lock_mode == LA_SLOCKED ||
+	    proctree_lock_mode == LA_XLOCKED);
 
 	p = td->td_proc;
 	for (;;) {
@@ -507,8 +511,8 @@ tty_wait_background(struct tty *tp, struct thread *td, int sig)
 		pgsignal(pg, ksi.ksi_signo, 1, &ksi);
 		PGRP_UNLOCK(pg);
 
-		error = tty_wait(tp, &tp->t_bgwait);
-		if (error)
+		error = tty_wait_proctree(tp, &tp->t_bgwait, proctree_lock_mode);
+		if (error != 0)
 			return (error);
 	}
 }
@@ -545,7 +549,8 @@ ttydev_write(struct cdev *dev, struct uio *uio, int ioflag)
 		return (error);
 
 	if (tp->t_termios.c_lflag & TOSTOP) {
-		error = tty_wait_background(tp, curthread, SIGTTOU);
+		error = tty_wait_background(tp, curthread, SIGTTOU,
+		    LA_UNLOCKED);
 		if (error)
 			goto done;
 	}
@@ -620,7 +625,8 @@ ttydev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
 		 * If the ioctl() causes the TTY to be modified, let it
 		 * wait in the background.
 		 */
-		error = tty_wait_background(tp, curthread, SIGTTOU);
+		error = tty_wait_background(tp, curthread, SIGTTOU,
+		    LA_UNLOCKED);
 		if (error)
 			goto done;
 	}
diff --git a/sys/kern/tty_ttydisc.c b/sys/kern/tty_ttydisc.c
index 2be6b560d4f4..9ad379b3c60d 100644
--- a/sys/kern/tty_ttydisc.c
+++ b/sys/kern/tty_ttydisc.c
@@ -199,7 +199,8 @@ ttydisc_read_canonical(struct tty *tp, struct uio *uio, int ioflag)
 	ttydisc_read_break(tp, &breakc[0], sizeof(breakc));
 
 	do {
-		error = tty_wait_background(tp, curthread, SIGTTIN);
+		error = tty_wait_background(tp, curthread, SIGTTIN,
+		    LA_UNLOCKED);
 		if (error)
 			return (error);
 
@@ -279,7 +280,8 @@ ttydisc_read_raw_no_timer(struct tty *tp, struct uio *uio, int ioflag)
 	 */
 
 	for (;;) {
-		error = tty_wait_background(tp, curthread, SIGTTIN);
+		error = tty_wait_background(tp, curthread, SIGTTIN,
+		    LA_UNLOCKED);
 		if (error)
 			return (error);
 
@@ -320,7 +322,8 @@ ttydisc_read_raw_read_timer(struct tty *tp, struct uio *uio, int ioflag,
 	timevaladd(&end, &now);
 
 	for (;;) {
-		error = tty_wait_background(tp, curthread, SIGTTIN);
+		error = tty_wait_background(tp, curthread, SIGTTIN,
+		    LA_UNLOCKED);
 		if (error)
 			return (error);
 
@@ -373,7 +376,8 @@ ttydisc_read_raw_interbyte_timer(struct tty *tp, struct uio *uio, int ioflag)
 	 */
 
 	for (;;) {
-		error = tty_wait_background(tp, curthread, SIGTTIN);
+		error = tty_wait_background(tp, curthread, SIGTTIN,
+		    LA_UNLOCKED);
 		if (error)
 			return (error);
 
diff --git a/sys/sys/tty.h b/sys/sys/tty.h
index 6a58908d97a4..65cc88f861c2 100644
--- a/sys/sys/tty.h
+++ b/sys/sys/tty.h
@@ -192,7 +192,8 @@ void	tty_signal_sessleader(struct tty *tp, int signal);
 void	tty_signal_pgrp(struct tty *tp, int signal);
 /* Waking up readers/writers. */
 int	tty_wait(struct tty *tp, struct cv *cv);
-int	tty_wait_background(struct tty *tp, struct thread *td, int sig);
+int	tty_wait_background(struct tty *tp, struct thread *td, int sig,
+    int proctree_lock_mode);
 int	tty_timedwait(struct tty *tp, struct cv *cv, int timo);
 void	tty_wakeup(struct tty *tp, int flags);