The branch stable/12 has been updated by kib:

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

commit 71dfe98e34acdcb8b0f90880de28611e66662e91
Author:     Konstantin Belousov <[email protected]>
AuthorDate: 2020-12-31 13:45:06 +0000
Commit:     Konstantin Belousov <[email protected]>
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);
 
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to