svn commit: r294472 - in head/sys: kern sys
Mateusz Guzik
mjg at FreeBSD.org
Wed Jan 20 23:34:00 UTC 2016
Author: mjg
Date: Wed Jan 20 23:33:58 2016
New Revision: 294472
URL: https://svnweb.freebsd.org/changeset/base/294472
Log:
session: avoid proctree lock on proc exit when possible
We can get away with the common case with only proc lock held.
Reviewed by: kib
Modified:
head/sys/kern/kern_exit.c
head/sys/kern/kern_proc.c
head/sys/sys/proc.h
Modified: head/sys/kern/kern_exit.c
==============================================================================
--- head/sys/kern/kern_exit.c Wed Jan 20 23:27:02 2016 (r294471)
+++ head/sys/kern/kern_exit.c Wed Jan 20 23:33:58 2016 (r294472)
@@ -189,7 +189,6 @@ exit1(struct thread *td, int rval, int s
{
struct proc *p, *nq, *q, *t;
struct thread *tdt;
- struct vnode *ttyvp = NULL;
mtx_assert(&Giant, MA_NOTOWNED);
KASSERT(rval == 0 || signo == 0, ("exit1 rv %d sig %d", rval, signo));
@@ -394,60 +393,9 @@ exit1(struct thread *td, int rval, int s
}
vmspace_exit(td);
-
- sx_xlock(&proctree_lock);
- if (SESS_LEADER(p)) {
- struct session *sp = p->p_session;
- struct tty *tp;
-
- /*
- * s_ttyp is not zero'd; we use this to indicate that
- * the session once had a controlling terminal. (for
- * logging and informational purposes)
- */
- SESS_LOCK(sp);
- ttyvp = sp->s_ttyvp;
- tp = sp->s_ttyp;
- sp->s_ttyvp = NULL;
- sp->s_ttydp = NULL;
- sp->s_leader = NULL;
- SESS_UNLOCK(sp);
-
- /*
- * Signal foreground pgrp and revoke access to
- * controlling terminal if it has not been revoked
- * already.
- *
- * Because the TTY may have been revoked in the mean
- * time and could already have a new session associated
- * with it, make sure we don't send a SIGHUP to a
- * foreground process group that does not belong to this
- * session.
- */
-
- if (tp != NULL) {
- tty_lock(tp);
- if (tp->t_session == sp)
- tty_signal_pgrp(tp, SIGHUP);
- tty_unlock(tp);
- }
-
- if (ttyvp != NULL) {
- sx_xunlock(&proctree_lock);
- if (vn_lock(ttyvp, LK_EXCLUSIVE) == 0) {
- VOP_REVOKE(ttyvp, REVOKEALL);
- VOP_UNLOCK(ttyvp, 0);
- }
- sx_xlock(&proctree_lock);
- }
- }
- fixjobc(p, p->p_pgrp, 0);
- sx_xunlock(&proctree_lock);
+ killjobc();
(void)acct_process(td);
- /* Release the TTY now we've unlocked everything. */
- if (ttyvp != NULL)
- vrele(ttyvp);
#ifdef KTRACE
ktrprocexit(td);
#endif
Modified: head/sys/kern/kern_proc.c
==============================================================================
--- head/sys/kern/kern_proc.c Wed Jan 20 23:27:02 2016 (r294471)
+++ head/sys/kern/kern_proc.c Wed Jan 20 23:33:58 2016 (r294472)
@@ -686,6 +686,79 @@ fixjobc(struct proc *p, struct pgrp *pgr
}
}
+void
+killjobc(void)
+{
+ struct session *sp;
+ struct tty *tp;
+ struct proc *p;
+ struct vnode *ttyvp;
+
+ p = curproc;
+ MPASS(p->p_flag & P_WEXIT);
+ /*
+ * Do a quick check to see if there is anything to do with the
+ * proctree_lock held. pgrp and LIST_EMPTY checks are for fixjobc().
+ */
+ PROC_LOCK(p);
+ if (!SESS_LEADER(p) &&
+ (p->p_pgrp == p->p_pptr->p_pgrp) &&
+ LIST_EMPTY(&p->p_children)) {
+ PROC_UNLOCK(p);
+ return;
+ }
+ PROC_UNLOCK(p);
+
+ sx_xlock(&proctree_lock);
+ if (SESS_LEADER(p)) {
+ sp = p->p_session;
+
+ /*
+ * s_ttyp is not zero'd; we use this to indicate that
+ * the session once had a controlling terminal. (for
+ * logging and informational purposes)
+ */
+ SESS_LOCK(sp);
+ ttyvp = sp->s_ttyvp;
+ tp = sp->s_ttyp;
+ sp->s_ttyvp = NULL;
+ sp->s_ttydp = NULL;
+ sp->s_leader = NULL;
+ SESS_UNLOCK(sp);
+
+ /*
+ * Signal foreground pgrp and revoke access to
+ * controlling terminal if it has not been revoked
+ * already.
+ *
+ * Because the TTY may have been revoked in the mean
+ * time and could already have a new session associated
+ * with it, make sure we don't send a SIGHUP to a
+ * foreground process group that does not belong to this
+ * session.
+ */
+
+ if (tp != NULL) {
+ tty_lock(tp);
+ if (tp->t_session == sp)
+ tty_signal_pgrp(tp, SIGHUP);
+ tty_unlock(tp);
+ }
+
+ if (ttyvp != NULL) {
+ sx_xunlock(&proctree_lock);
+ if (vn_lock(ttyvp, LK_EXCLUSIVE) == 0) {
+ VOP_REVOKE(ttyvp, REVOKEALL);
+ VOP_UNLOCK(ttyvp, 0);
+ }
+ vrele(ttyvp);
+ sx_xlock(&proctree_lock);
+ }
+ }
+ fixjobc(p, p->p_pgrp, 0);
+ sx_xunlock(&proctree_lock);
+}
+
/*
* A process group has become orphaned;
* if there are any stopped processes in the group,
Modified: head/sys/sys/proc.h
==============================================================================
--- head/sys/sys/proc.h Wed Jan 20 23:27:02 2016 (r294471)
+++ head/sys/sys/proc.h Wed Jan 20 23:33:58 2016 (r294472)
@@ -938,6 +938,7 @@ void fork_return(struct thread *, struct
int inferior(struct proc *p);
void kern_yield(int);
void kick_proc0(void);
+void killjobc(void);
int leavepgrp(struct proc *p);
int maybe_preempt(struct thread *td);
void maybe_yield(void);
More information about the svn-src-all
mailing list