From 98c2b8ac8ef57c41a8fa17a7d32c47a45fe26e1e Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Sat, 28 Aug 2010 11:06:08 -0700 Subject: [PATCH] kernel - procfs_token work * Cover proc_stop(), proc_unstop(), and setrunnable() with proc_token. Remove the MP lock assertion from setrunnable(). * Cover procfs operations with proc_token. * Cover lwp_signotify() and friends with proc_token. --- sys/kern/kern_checkpoint.c | 3 +++ sys/kern/kern_sig.c | 32 ++++++++++++++++++++++++++------ sys/kern/kern_synch.c | 7 ++++--- sys/sys/signalvar.h | 1 - sys/vfs/procfs/procfs_ctl.c | 4 ++++ sys/vfs/procfs/procfs_subr.c | 12 ++++++++++-- 6 files changed, 47 insertions(+), 12 deletions(-) diff --git a/sys/kern/kern_checkpoint.c b/sys/kern/kern_checkpoint.c index a24e9edeae..b515a9e6b5 100644 --- a/sys/kern/kern_checkpoint.c +++ b/sys/kern/kern_checkpoint.c @@ -692,6 +692,8 @@ ckpt_freeze_proc(struct lwp *lp, struct file *fp) rlim_t limit; int error; + lwkt_gettoken(&proc_token); /* needed for proc_*() calls */ + PRINTF(("calling generic_elf_coredump\n")); limit = p->p_rlimit[RLIMIT_CORE].rlim_cur; if (limit) { @@ -703,6 +705,7 @@ ckpt_freeze_proc(struct lwp *lp, struct file *fp) } else { error = ERANGE; } + lwkt_reltoken(&proc_token); return error; } diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 66be9e4621..f930f27b3a 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -79,6 +79,7 @@ static char *expand_name(const char *, uid_t, pid_t); static int dokillpg(int sig, int pgid, int all); static int sig_ffs(sigset_t *set); static int sigprop(int sig); +static void lwp_signotify(struct lwp *lp); #ifdef SMP static void signotify_remote(void *arg); #endif @@ -1233,10 +1234,15 @@ out: crit_exit(); } -void +/* + * proc_token must be held + */ +static void lwp_signotify(struct lwp *lp) { + ASSERT_LWKT_TOKEN_HELD(&proc_token); crit_enter(); + if (lp->lwp_stat == LSSLEEP || lp->lwp_stat == LSSTOP) { /* * Thread is in tsleep. @@ -1332,16 +1338,22 @@ signotify_remote(void *arg) #endif +/* + * Caller must hold proc_token + */ void proc_stop(struct proc *p) { struct lwp *lp; + ASSERT_LWKT_TOKEN_HELD(&proc_token); + crit_enter(); + /* If somebody raced us, be happy with it */ - if (p->p_stat == SSTOP || p->p_stat == SZOMB) + if (p->p_stat == SSTOP || p->p_stat == SZOMB) { + crit_exit(); return; - - crit_enter(); + } p->p_stat = SSTOP; FOREACH_LWP_IN_PROC(lp, p) { @@ -1386,15 +1398,22 @@ proc_stop(struct proc *p) crit_exit(); } +/* + * Caller must hold proc_token + */ void proc_unstop(struct proc *p) { struct lwp *lp; - if (p->p_stat != SSTOP) + ASSERT_LWKT_TOKEN_HELD(&proc_token); + crit_enter(); + + if (p->p_stat != SSTOP) { + crit_exit(); return; + } - crit_enter(); p->p_stat = SACTIVE; FOREACH_LWP_IN_PROC(lp, p) { @@ -1673,6 +1692,7 @@ issignal(struct lwp *lp, int maytrace) int sig, prop; lwkt_gettoken(&proc_token); + for (;;) { int traced = (p->p_flag & P_TRACED) || (p->p_stops & S_SIG); diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index 6230739044..a739ad2ea9 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -830,8 +830,8 @@ endtsleep(void *arg) thread_t td = arg; struct lwp *lp; - ASSERT_MP_LOCK_HELD(curthread); crit_enter(); + lwkt_gettoken(&proc_token); /* * cpu interlock. Thread flags are only manipulated on @@ -849,6 +849,7 @@ endtsleep(void *arg) _tsleep_wakeup(td); } } + lwkt_reltoken(&proc_token); crit_exit(); } @@ -1032,7 +1033,7 @@ wakeup_domain_one(const volatile void *ident, int domain) /* * setrunnable() * - * Make a process runnable. The MP lock must be held on call. This only + * Make a process runnable. The proc_token must be held on call. This only * has an effect if we are in SSLEEP. We only break out of the * tsleep if LWP_BREAKTSLEEP is set, otherwise we just fix-up the state. * @@ -1042,8 +1043,8 @@ wakeup_domain_one(const volatile void *ident, int domain) void setrunnable(struct lwp *lp) { + ASSERT_LWKT_TOKEN_HELD(&proc_token); crit_enter(); - ASSERT_MP_LOCK_HELD(curthread); if (lp->lwp_stat == LSSTOP) lp->lwp_stat = LSSLEEP; if (lp->lwp_stat == LSSLEEP && (lp->lwp_flag & LWP_BREAKTSLEEP)) diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h index 875fa24a52..076b632455 100644 --- a/sys/sys/signalvar.h +++ b/sys/sys/signalvar.h @@ -200,7 +200,6 @@ void pgsignal (struct pgrp *pgrp, int sig, int checkctty); void postsig (int sig); void ksignal (struct proc *p, int sig); void lwpsignal (struct proc *p, struct lwp *lp, int sig); -void lwp_signotify (struct lwp *lp); void siginit (struct proc *p); void trapsignal (struct lwp *p, int sig, u_long code); diff --git a/sys/vfs/procfs/procfs_ctl.c b/sys/vfs/procfs/procfs_ctl.c index 3912fd1094..4fdb164cdb 100644 --- a/sys/vfs/procfs/procfs_ctl.c +++ b/sys/vfs/procfs/procfs_ctl.c @@ -111,6 +111,8 @@ procfs_control(struct proc *curp, struct lwp *lp, int op) struct proc *p = lp->lwp_proc; int error; + ASSERT_LWKT_TOKEN_HELD(&proc_token); + /* Can't trace a process that's currently exec'ing. */ if ((p->p_flag & P_INEXEC) != 0) return EAGAIN; @@ -289,6 +291,8 @@ procfs_doctl(struct proc *curp, struct lwp *lp, struct pfsnode *pfs, char msg[PROCFS_CTLLEN+1]; vfs_namemap_t *nm; + ASSERT_LWKT_TOKEN_HELD(&proc_token); + if (uio->uio_rw != UIO_WRITE) return (EOPNOTSUPP); diff --git a/sys/vfs/procfs/procfs_subr.c b/sys/vfs/procfs/procfs_subr.c index f9d8eb88e1..2186445bf7 100644 --- a/sys/vfs/procfs/procfs_subr.c +++ b/sys/vfs/procfs/procfs_subr.c @@ -272,11 +272,17 @@ procfs_rw(struct vop_read_args *ap) if ((curp = curtd->td_proc) == NULL) /* XXX */ return (EINVAL); + lwkt_gettoken(&proc_token); + p = PFIND(pfs->pfs_pid); - if (p == NULL) + if (p == NULL) { + lwkt_reltoken(&proc_token); return (EINVAL); - if (p->p_pid == 1 && securelevel > 0 && uio->uio_rw == UIO_WRITE) + } + if (p->p_pid == 1 && securelevel > 0 && uio->uio_rw == UIO_WRITE) { + lwkt_reltoken(&proc_token); return (EACCES); + } /* XXX lwp */ lp = FIRST_LWP_IN_PROC(p); LWPHOLD(lp); @@ -338,7 +344,9 @@ procfs_rw(struct vop_read_args *ap) } LWPRELE(lp); pfs->pfs_lockowner = 0; + lwkt_reltoken(&proc_token); wakeup(&pfs->pfs_lockowner); + return rtval; } -- 2.11.4.GIT