Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 10 Jan 2021 02:41:54 GMT
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: a008bdeda3b8 - main - tty_wait_background: improve locking.
Message-ID:  <202101100241.10A2fsDu057605@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by kib:

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

commit a008bdeda3b8278fe600cf83ecf44acd1ccb30b6
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2020-12-31 13:45:06 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2021-01-10 02:41:20 +0000

    tty_wait_background: improve locking.
    
    Increase the scope of the process group lock ownership.  This ensures that
    we are consistent in returning EIO for tty write from an orphan and delivery
    of TTYOUT signals.
    
    Reviewed by:    jilles
    Tested by:      pho
    MFC after:      1 week
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D27871
---
 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 af4aebd18979..1f86507a6025 100644
--- a/sys/kern/tty.c
+++ b/sys/kern/tty.c
@@ -423,7 +423,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;
@@ -431,8 +431,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
@@ -445,6 +459,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);
 		}
 
@@ -452,13 +467,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);
@@ -473,20 +489,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);
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202101100241.10A2fsDu057605>