git: 71dfe98e34ac - stable/12 - tty_wait_background: improve locking.

Konstantin Belousov kib at FreeBSD.org
Sun Jan 17 05:10:46 UTC 2021


The branch stable/12 has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=71dfe98e34acdcb8b0f90880de28611e66662e91

commit 71dfe98e34acdcb8b0f90880de28611e66662e91
Author:     Konstantin Belousov <kib at FreeBSD.org>
AuthorDate: 2020-12-31 13:45:06 +0000
Commit:     Konstantin Belousov <kib at FreeBSD.org>
CommitDate: 2021-01-17 04:45:47 +0000

    tty_wait_background: improve locking.
    
    (cherry picked from commit a008bdeda3b8278fe600cf83ecf44acd1ccb30b6)
---
 sys/kern/tty.c | 33 ++++++++++++++++++---------------
 1 file changed, 18 insertions(+), 15 deletions(-)

diff --git a/sys/kern/tty.c b/sys/kern/tty.c
index 63324ac3e881..693032908b3a 100644
--- a/sys/kern/tty.c
+++ b/sys/kern/tty.c
@@ -413,7 +413,7 @@ tty_is_ctty(struct tty *tp, struct proc *p)
 int
 tty_wait_background(struct tty *tp, struct thread *td, int sig)
 {
-	struct proc *p = td->td_proc;
+	struct proc *p;
 	struct pgrp *pg;
 	ksiginfo_t ksi;
 	int error;
@@ -421,8 +421,22 @@ tty_wait_background(struct tty *tp, struct thread *td, int sig)
 	MPASS(sig == SIGTTIN || sig == SIGTTOU);
 	tty_assert_locked(tp);
 
+	p = td->td_proc;
 	for (;;) {
+		pg = p->p_pgrp;
+		PGRP_LOCK(pg);
 		PROC_LOCK(p);
+
+		/*
+		 * pg may no longer be our process group.
+		 * Re-check after locking.
+		 */
+		if (p->p_pgrp != pg) {
+			PROC_UNLOCK(p);
+			PGRP_UNLOCK(pg);
+			continue;
+		}
+
 		/*
 		 * The process should only sleep, when:
 		 * - This terminal is the controlling terminal
@@ -435,6 +449,7 @@ tty_wait_background(struct tty *tp, struct thread *td, int sig)
 		if (!tty_is_ctty(tp, p) || p->p_pgrp == tp->t_pgrp) {
 			/* Allow the action to happen. */
 			PROC_UNLOCK(p);
+			PGRP_UNLOCK(pg);
 			return (0);
 		}
 
@@ -442,13 +457,14 @@ tty_wait_background(struct tty *tp, struct thread *td, int sig)
 		    SIGISMEMBER(td->td_sigmask, sig)) {
 			/* Only allow them in write()/ioctl(). */
 			PROC_UNLOCK(p);
+			PGRP_UNLOCK(pg);
 			return (sig == SIGTTOU ? 0 : EIO);
 		}
 
-		pg = p->p_pgrp;
 		if ((p->p_flag & P_PPWAIT) != 0 || pg->pg_jobc == 0) {
 			/* Don't allow the action to happen. */
 			PROC_UNLOCK(p);
+			PGRP_UNLOCK(pg);
 			return (EIO);
 		}
 		PROC_UNLOCK(p);
@@ -463,20 +479,7 @@ tty_wait_background(struct tty *tp, struct thread *td, int sig)
 			ksi.ksi_signo = sig;
 			sig = 0;
 		}
-		PGRP_LOCK(pg);
-
-		/*
-		 * pg may no longer be our process group.
-		 * Re-check after locking process group.
-		 */
-		PROC_LOCK(p);
-		if (p->p_pgrp != pg) {
-			PROC_UNLOCK(p);
-			PGRP_UNLOCK(pg);
-			continue;
-		}
 
-		PROC_UNLOCK(p);
 		pgsignal(pg, ksi.ksi_signo, 1, &ksi);
 		PGRP_UNLOCK(pg);
 


More information about the dev-commits-src-branches mailing list