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-all
mailing list