From 717bc758983a5169f4964fcb886c4400e1c18663 Mon Sep 17 00:00:00 2001 From: Claudio Jeker Date: Fri, 13 May 2022 15:32:01 +0000 Subject: Use the process ps_mtx to protect the process sigacts structure. With this cursig(), postsig() and trapsignal() become safe to be called without KERNEL_LOCK. As a side-effect sleep with PCATCH no longer needs the KERNEL_LOCK either. Since sending a signal can happen from interrupt context raise the ps_mtx IPL to high. Feedback from mpi@ and kettenis@ OK kettenis@ --- sys/kern/kern_fork.c | 4 +- sys/kern/kern_sig.c | 152 +++++++++++++++++++++++++++++--------------------- sys/kern/kern_synch.c | 22 +------- sys/sys/proc.h | 5 +- sys/sys/signalvar.h | 25 +++++---- sys/sys/sysctl.h | 15 ++--- 6 files changed, 116 insertions(+), 107 deletions(-) diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 330c7a06a8e..8b4b4206058 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_fork.c,v 1.239 2022/03/17 14:23:34 visa Exp $ */ +/* $OpenBSD: kern_fork.c,v 1.240 2022/05/13 15:32:00 claudio Exp $ */ /* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */ /* @@ -200,7 +200,7 @@ process_initialize(struct process *pr, struct proc *p) TAILQ_INIT(&pr->ps_tslpqueue); rw_init(&pr->ps_lock, "pslock"); - mtx_init(&pr->ps_mtx, IPL_MPFLOOR); + mtx_init(&pr->ps_mtx, IPL_HIGH); timeout_set_kclock(&pr->ps_realit_to, realitexpire, pr, KCLOCK_UPTIME, 0); diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index f9bd8b74e1b..4a104265235 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sig.c,v 1.295 2022/03/11 10:05:38 claudio Exp $ */ +/* $OpenBSD: kern_sig.c,v 1.296 2022/05/13 15:32:00 claudio Exp $ */ /* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */ /* @@ -278,6 +278,7 @@ sys_sigaction(struct proc *p, void *v, register_t *retval) return (EINVAL); sa = &vec; if (osa) { + mtx_enter(&p->p_p->ps_mtx); sa->sa_handler = ps->ps_sigact[signum]; sa->sa_mask = ps->ps_catchmask[signum]; bit = sigmask(signum); @@ -296,6 +297,7 @@ sys_sigaction(struct proc *p, void *v, register_t *retval) if ((ps->ps_sigflags & SAS_NOCLDWAIT) != 0) sa->sa_flags |= SA_NOCLDWAIT; } + mtx_leave(&p->p_p->ps_mtx); if ((sa->sa_mask & bit) == 0) sa->sa_flags |= SA_NODEFER; sa->sa_mask &= ~bit; @@ -329,13 +331,10 @@ setsigvec(struct proc *p, int signum, struct sigaction *sa) { struct sigacts *ps = p->p_p->ps_sigacts; int bit; - int s; bit = sigmask(signum); - /* - * Change setting atomically. - */ - s = splhigh(); + + mtx_enter(&p->p_p->ps_mtx); ps->ps_sigact[signum] = sa->sa_handler; if ((sa->sa_flags & SA_NODEFER) == 0) sa->sa_mask |= sigmask(signum); @@ -396,7 +395,7 @@ setsigvec(struct proc *p, int signum, struct sigaction *sa) else ps->ps_sigcatch |= bit; } - splx(s); + mtx_leave(&p->p_p->ps_mtx); } /* @@ -424,6 +423,7 @@ execsigs(struct proc *p) int nc, mask; ps = p->p_p->ps_sigacts; + mtx_enter(&p->p_p->ps_mtx); /* * Reset caught signals. Held signals remain held @@ -450,6 +450,7 @@ execsigs(struct proc *p) atomic_clearbits_int(&ps->ps_sigflags, SAS_NOCLDWAIT); if (ps->ps_sigact[SIGCHLD] == SIG_IGN) ps->ps_sigact[SIGCHLD] = SIG_DFL; + mtx_leave(&p->p_p->ps_mtx); } /* @@ -779,18 +780,18 @@ out: void postsig_done(struct proc *p, int signum, sigset_t catchmask, int reset) { - KERNEL_ASSERT_LOCKED(); - p->p_ru.ru_nsignals++; atomic_setbits_int(&p->p_sigmask, catchmask); if (reset != 0) { sigset_t mask = sigmask(signum); struct sigacts *ps = p->p_p->ps_sigacts; + mtx_enter(&p->p_p->ps_mtx); ps->ps_sigcatch &= ~mask; if (signum != SIGCONT && sigprop[signum] & SA_IGNORE) ps->ps_sigignore |= mask; ps->ps_sigact[signum] = SIG_DFL; + mtx_leave(&p->p_p->ps_mtx); } } @@ -804,10 +805,9 @@ trapsignal(struct proc *p, int signum, u_long trapno, int code, union sigval sigval) { struct process *pr = p->p_p; - struct sigacts *ps = pr->ps_sigacts; + struct sigctx ctx; int mask; - KERNEL_LOCK(); switch (signum) { case SIGILL: case SIGBUS: @@ -817,28 +817,25 @@ trapsignal(struct proc *p, int signum, u_long trapno, int code, } mask = sigmask(signum); - if ((pr->ps_flags & PS_TRACED) == 0 && - (ps->ps_sigcatch & mask) != 0 && + setsigctx(p, signum, &ctx); + if ((pr->ps_flags & PS_TRACED) == 0 && ctx.sig_catch != 0 && (p->p_sigmask & mask) == 0) { siginfo_t si; - sigset_t catchmask = ps->ps_catchmask[signum]; - int info = (ps->ps_siginfo & mask) != 0; - int onstack = (ps->ps_sigonstack & mask) != 0; - int reset = (ps->ps_sigreset & mask) != 0; initsiginfo(&si, signum, trapno, code, sigval); #ifdef KTRACE if (KTRPOINT(p, KTR_PSIG)) { - ktrpsig(p, signum, ps->ps_sigact[signum], + ktrpsig(p, signum, ctx.sig_action, p->p_sigmask, code, &si); } #endif - if (sendsig(ps->ps_sigact[signum], signum, p->p_sigmask, &si, - info, onstack)) { + if (sendsig(ctx.sig_action, signum, p->p_sigmask, &si, + ctx.sig_info, ctx.sig_onstack)) { + KERNEL_LOCK(); sigexit(p, SIGILL); /* NOTREACHED */ } - postsig_done(p, signum, catchmask, reset); + postsig_done(p, signum, ctx.sig_catchmask, ctx.sig_reset); } else { p->p_sisig = signum; p->p_sitrapno = trapno; /* XXX for core dump/debugger */ @@ -854,14 +851,14 @@ trapsignal(struct proc *p, int signum, u_long trapno, int code, signum != SIGKILL && (p->p_sigmask & mask) != 0) { int s; - pr->ps_xsig = signum; - single_thread_set(p, SINGLE_SUSPEND, 0); + pr->ps_xsig = signum; SCHED_LOCK(s); proc_stop(p, 1); SCHED_UNLOCK(s); + signum = pr->ps_xsig; single_thread_clear(p, 0); /* @@ -869,13 +866,10 @@ trapsignal(struct proc *p, int signum, u_long trapno, int code, * didn't give us a signal, skip sending the signal. */ if ((pr->ps_flags & PS_TRACED) == 0 || - pr->ps_xsig == 0) { - KERNEL_UNLOCK(); + signum == 0) return; - } /* update signal info */ - signum = pr->ps_xsig; p->p_sisig = signum; mask = sigmask(signum); } @@ -893,12 +887,16 @@ trapsignal(struct proc *p, int signum, u_long trapno, int code, */ if ((pr->ps_flags & PS_TRACED) == 0 && (sigprop[signum] & SA_KILL) && - ((p->p_sigmask & mask) || (ps->ps_sigignore & mask)) && - pr->ps_pid != 1) + ((p->p_sigmask & mask) || ctx.sig_ignore) && + pr->ps_pid != 1) { + KERNEL_LOCK(); sigexit(p, signum); + /* NOTREACHED */ + } + KERNEL_LOCK(); ptsignal(p, signum, STHREAD); + KERNEL_UNLOCK(); } - KERNEL_UNLOCK(); } /* @@ -1008,6 +1006,8 @@ ptsignal(struct proc *p, int signum, enum signal_type type) if (pr->ps_flags & PS_TRACED) { action = SIG_DFL; } else { + sigset_t sigcatch, sigignore; + /* * If the signal is being ignored, * then we forget about it immediately. @@ -1015,11 +1015,16 @@ ptsignal(struct proc *p, int signum, enum signal_type type) * and if it is set to SIG_IGN, * action will be SIG_DFL here.) */ - if (pr->ps_sigacts->ps_sigignore & mask) + mtx_enter(&pr->ps_mtx); + sigignore = pr->ps_sigacts->ps_sigignore; + sigcatch = pr->ps_sigacts->ps_sigcatch; + mtx_leave(&pr->ps_mtx); + + if (sigignore & mask) return; if (p->p_sigmask & mask) { action = SIG_HOLD; - } else if (pr->ps_sigacts->ps_sigcatch & mask) { + } else if (sigcatch & mask) { action = SIG_CATCH; } else { action = SIG_DFL; @@ -1052,7 +1057,6 @@ ptsignal(struct proc *p, int signum, enum signal_type type) atomic_clearbits_int(siglist, CONTSIGMASK); atomic_clearbits_int(&p->p_flag, P_CONTINUED); } - atomic_setbits_int(siglist, mask); /* * XXX delay processing of SA_STOP signals unless action == SIG_DFL? @@ -1066,8 +1070,11 @@ ptsignal(struct proc *p, int signum, enum signal_type type) * Defer further processing for signals which are held, * except that stopped processes must be continued by SIGCONT. */ - if (action == SIG_HOLD && ((prop & SA_CONT) == 0 || p->p_stat != SSTOP)) + if (action == SIG_HOLD && ((prop & SA_CONT) == 0 || + p->p_stat != SSTOP)) { + atomic_setbits_int(siglist, mask); return; + } SCHED_LOCK(s); @@ -1095,7 +1102,7 @@ ptsignal(struct proc *p, int signum, enum signal_type type) * be awakened. */ if ((prop & SA_CONT) && action == SIG_DFL) { - atomic_clearbits_int(siglist, mask); + mask = 0; goto out; } /* @@ -1109,7 +1116,7 @@ ptsignal(struct proc *p, int signum, enum signal_type type) */ if (pr->ps_flags & PS_PPWAIT) goto out; - atomic_clearbits_int(siglist, mask); + mask = 0; pr->ps_xsig = signum; proc_stop(p, 0); goto out; @@ -1166,7 +1173,7 @@ ptsignal(struct proc *p, int signum, enum signal_type type) * Already stopped, don't need to stop again. * (If we did the shell could get confused.) */ - atomic_clearbits_int(siglist, mask); + mask = 0; goto out; } @@ -1181,6 +1188,9 @@ ptsignal(struct proc *p, int signum, enum signal_type type) goto out; case SONPROC: + /* set siglist before issuing the ast */ + atomic_setbits_int(siglist, mask); + mask = 0; signotify(p); /* FALLTHROUGH */ default: @@ -1202,6 +1212,9 @@ runfast: run: setrunnable(p); out: + /* finally adjust siglist */ + if (mask) + atomic_setbits_int(siglist, mask); SCHED_UNLOCK(s); if (wakeparent) wakeup(pr->ps_pptr); @@ -1214,6 +1227,7 @@ setsigctx(struct proc *p, int signum, struct sigctx *sctx) struct sigacts *ps = p->p_p->ps_sigacts; sigset_t mask; + mtx_enter(&p->p_p->ps_mtx); mask = sigmask(signum); sctx->sig_action = ps->ps_sigact[signum]; sctx->sig_catchmask = ps->ps_catchmask[signum]; @@ -1222,6 +1236,8 @@ setsigctx(struct proc *p, int signum, struct sigctx *sctx) sctx->sig_intr = (ps->ps_sigintr & mask) != 0; sctx->sig_onstack = (ps->ps_sigonstack & mask) != 0; sctx->sig_ignore = (ps->ps_sigignore & mask) != 0; + sctx->sig_catch = (ps->ps_sigcatch & mask) != 0; + mtx_leave(&p->p_p->ps_mtx); } /* @@ -1246,12 +1262,14 @@ cursig(struct proc *p, struct sigctx *sctx) struct process *pr = p->p_p; int signum, mask, prop; int dolock = (p->p_flag & P_SINTR) == 0; + sigset_t ps_siglist; int s; - KERNEL_ASSERT_LOCKED(); KASSERT(p == curproc); for (;;) { + ps_siglist = READ_ONCE(pr->ps_siglist); + membar_consumer(); mask = SIGPENDING(p); if (pr->ps_flags & PS_PPWAIT) mask &= ~STOPSIGMASK; @@ -1261,8 +1279,12 @@ cursig(struct proc *p, struct sigctx *sctx) mask = sigmask(signum); /* take the signal! */ + if (atomic_cas_uint(&pr->ps_siglist, ps_siglist, + ps_siglist & ~mask) != ps_siglist) { + /* lost race taking the process signal, restart */ + continue; + } atomic_clearbits_int(&p->p_siglist, mask); - atomic_clearbits_int(&pr->ps_siglist, mask); setsigctx(p, signum, sctx); /* @@ -1279,9 +1301,8 @@ cursig(struct proc *p, struct sigctx *sctx) */ if (((pr->ps_flags & (PS_TRACED | PS_PPWAIT)) == PS_TRACED) && signum != SIGKILL) { - pr->ps_xsig = signum; - single_thread_set(p, SINGLE_SUSPEND, 0); + pr->ps_xsig = signum; if (dolock) SCHED_LOCK(s); @@ -1289,6 +1310,22 @@ cursig(struct proc *p, struct sigctx *sctx) if (dolock) SCHED_UNLOCK(s); + /* + * re-take the signal before releasing + * the other threads. Must check the continue + * conditions below and only take the signal if + * those are not true. + */ + signum = pr->ps_xsig; + mask = sigmask(signum); + setsigctx(p, signum, sctx); + if (!((pr->ps_flags & PS_TRACED) == 0 || + signum == 0 || + (p->p_sigmask & mask) != 0)) { + atomic_clearbits_int(&p->p_siglist, mask); + atomic_clearbits_int(&pr->ps_siglist, mask); + } + single_thread_clear(p, 0); /* @@ -1296,22 +1333,16 @@ cursig(struct proc *p, struct sigctx *sctx) * didn't give us a signal, look for more signals. */ if ((pr->ps_flags & PS_TRACED) == 0 || - pr->ps_xsig == 0) + signum == 0) continue; /* * If the new signal is being masked, look for other * signals. */ - signum = pr->ps_xsig; - mask = sigmask(signum); if ((p->p_sigmask & mask) != 0) continue; - /* take the signal! */ - atomic_clearbits_int(&p->p_siglist, mask); - atomic_clearbits_int(&pr->ps_siglist, mask); - setsigctx(p, signum, sctx); } prop = sigprop[signum]; @@ -1450,10 +1481,9 @@ postsig(struct proc *p, int signum, struct sigctx *sctx) int mask, returnmask; siginfo_t si; union sigval sigval; - int s, code; + int code; KASSERT(signum != 0); - KERNEL_ASSERT_LOCKED(); mask = sigmask(signum); atomic_clearbits_int(&p->p_siglist, mask); @@ -1481,6 +1511,7 @@ postsig(struct proc *p, int signum, struct sigctx *sctx) * Default action, where the default is to kill * the process. (Other cases were ignored above.) */ + KERNEL_LOCK(); sigexit(p, signum); /* NOTREACHED */ } else { @@ -1500,11 +1531,6 @@ postsig(struct proc *p, int signum, struct sigctx *sctx) * mask from before the sigpause is what we want * restored after the signal processing is completed. */ -#ifdef MULTIPROCESSOR - s = splsched(); -#else - s = splhigh(); -#endif if (p->p_flag & P_SIGSUSPEND) { atomic_clearbits_int(&p->p_flag, P_SIGSUSPEND); returnmask = p->p_oldmask; @@ -1520,11 +1546,11 @@ postsig(struct proc *p, int signum, struct sigctx *sctx) if (sendsig(sctx->sig_action, signum, returnmask, &si, sctx->sig_info, sctx->sig_onstack)) { + KERNEL_LOCK(); sigexit(p, SIGILL); /* NOTREACHED */ } postsig_done(p, signum, sctx->sig_catchmask, sctx->sig_reset); - splx(s); } } @@ -1580,12 +1606,14 @@ int sigismasked(struct proc *p, int sig) { struct process *pr = p->p_p; + int rv; - if ((pr->ps_sigacts->ps_sigignore & sigmask(sig)) || - (p->p_sigmask & sigmask(sig))) - return 1; + mtx_enter(&pr->ps_mtx); + rv = (pr->ps_sigacts->ps_sigignore & sigmask(sig)) || + (p->p_sigmask & sigmask(sig)); + mtx_leave(&pr->ps_mtx); - return 0; + return !!rv; } struct coredump_iostate { @@ -1958,10 +1986,8 @@ userret(struct proc *p) } if (SIGPENDING(p) != 0) { - KERNEL_LOCK(); while ((signum = cursig(p, &ctx)) != 0) postsig(p, signum, &ctx); - KERNEL_UNLOCK(); } /* @@ -1974,10 +2000,8 @@ userret(struct proc *p) atomic_clearbits_int(&p->p_flag, P_SIGSUSPEND); p->p_sigmask = p->p_oldmask; - KERNEL_LOCK(); while ((signum = cursig(p, &ctx)) != 0) postsig(p, signum, &ctx); - KERNEL_UNLOCK(); } if (p->p_flag & P_SUSPSINGLE) diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index 218fb9d067e..5f3e8be3482 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_synch.c,v 1.186 2022/04/30 14:44:04 visa Exp $ */ +/* $OpenBSD: kern_synch.c,v 1.187 2022/05/13 15:32:00 claudio Exp $ */ /* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */ /* @@ -219,9 +219,6 @@ msleep(const volatile void *ident, struct mutex *mtx, int priority, KASSERT(ident != &nowake || ISSET(priority, PCATCH) || timo != 0); KASSERT(mtx != NULL); - if (priority & PCATCH) - KERNEL_ASSERT_LOCKED(); - #ifdef DDB if (cold == 2) db_stack_dump(); @@ -361,19 +358,8 @@ sleep_setup(struct sleep_state *sls, const volatile void *ident, int prio, #endif sls->sls_catch = prio & PCATCH; - sls->sls_locked = 0; sls->sls_timeout = 0; - /* - * The kernel has to be locked for signal processing. - * This is done here and not in sleep_finish() because - * KERNEL_LOCK() has to be taken before SCHED_LOCK(). - */ - if (sls->sls_catch != 0) { - KERNEL_LOCK(); - sls->sls_locked = 1; - } - SCHED_LOCK(sls->sls_s); TRACEPOINT(sched, sleep, NULL); @@ -398,9 +384,6 @@ sleep_finish(struct sleep_state *sls, int do_sleep) int error = 0, error1 = 0; if (sls->sls_catch != 0) { - /* sleep_setup() has locked the kernel. */ - KERNEL_ASSERT_LOCKED(); - /* * We put ourselves on the sleep queue and start our * timeout before calling sleep_signal_check(), as we could @@ -462,9 +445,6 @@ sleep_finish(struct sleep_state *sls, int do_sleep) if (sls->sls_catch != 0) error = sleep_signal_check(); - if (sls->sls_locked) - KERNEL_UNLOCK(); - /* Signal errors are higher priority than timeouts. */ if (error == 0 && error1 != 0) error = error1; diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 241fc9e0c9a..df6c59d397d 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.h,v 1.329 2022/03/10 15:21:08 bluhm Exp $ */ +/* $OpenBSD: proc.h,v 1.330 2022/05/13 15:32:00 claudio Exp $ */ /* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */ /*- @@ -156,7 +156,7 @@ struct process { LIST_HEAD(, process) ps_orphans;/* Pointer to list of orphans. */ struct sigiolst ps_sigiolst; /* List of sigio structures. */ - struct sigacts *ps_sigacts; /* Signal actions, state */ + struct sigacts *ps_sigacts; /* [I] Signal actions, state */ struct vnode *ps_textvp; /* Vnode of executable. */ struct filedesc *ps_fd; /* Ptr to open files structure */ struct vmspace *ps_vmspace; /* Address space */ @@ -584,7 +584,6 @@ int proc_cansugid(struct proc *); struct sleep_state { int sls_s; int sls_catch; - int sls_locked; int sls_timeout; }; diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h index 3374a103749..3912d92623b 100644 --- a/sys/sys/signalvar.h +++ b/sys/sys/signalvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: signalvar.h,v 1.53 2022/02/14 11:26:05 claudio Exp $ */ +/* $OpenBSD: signalvar.h,v 1.54 2022/05/13 15:32:00 claudio Exp $ */ /* $NetBSD: signalvar.h,v 1.17 1996/04/22 01:23:31 christos Exp $ */ /* @@ -43,17 +43,21 @@ /* * Process signal actions and state, needed only within the process * (not necessarily resident). + * + * Locks used to protect struct members in struct sigacts: + * a atomic operations + * m this process' `ps_mtx' */ struct sigacts { - sig_t ps_sigact[NSIG]; /* disposition of signals */ - sigset_t ps_catchmask[NSIG]; /* signals to be blocked */ - sigset_t ps_sigonstack; /* signals to take on sigstack */ - sigset_t ps_sigintr; /* signals that interrupt syscalls */ - sigset_t ps_sigreset; /* signals that reset when caught */ - sigset_t ps_siginfo; /* signals that provide siginfo */ - sigset_t ps_sigignore; /* signals being ignored */ - sigset_t ps_sigcatch; /* signals being caught by user */ - int ps_sigflags; /* signal flags, below */ + sig_t ps_sigact[NSIG]; /* [m] disposition of signals */ + sigset_t ps_catchmask[NSIG]; /* [m] signals to be blocked */ + sigset_t ps_sigonstack; /* [m] signals to take on sigstack */ + sigset_t ps_sigintr; /* [m] signals interrupt syscalls */ + sigset_t ps_sigreset; /* [m] signals that reset when caught */ + sigset_t ps_siginfo; /* [m] signals that provide siginfo */ + sigset_t ps_sigignore; /* [m] signals being ignored */ + sigset_t ps_sigcatch; /* [m] signals being caught by user */ + int ps_sigflags; /* [a] signal flags, below */ }; /* signal flags */ @@ -97,6 +101,7 @@ struct sigctx { int sig_reset; int sig_info; int sig_ignore; + int sig_catch; }; /* diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h index 18ec56b4081..0572c2f1fd0 100644 --- a/sys/sys/sysctl.h +++ b/sys/sys/sysctl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sysctl.h,v 1.227 2022/02/25 18:05:49 rob Exp $ */ +/* $OpenBSD: sysctl.h,v 1.228 2022/05/13 15:32:00 claudio Exp $ */ /* $NetBSD: sysctl.h,v 1.16 1996/04/09 20:55:36 cgd Exp $ */ /* @@ -642,9 +642,16 @@ do { \ \ (kp)->p_siglist = (p)->p_siglist | (pr)->ps_siglist; \ (kp)->p_sigmask = (p)->p_sigmask; \ + \ + PR_LOCK(pr); \ (kp)->p_sigignore = (sa) ? (sa)->ps_sigignore : 0; \ (kp)->p_sigcatch = (sa) ? (sa)->ps_sigcatch : 0; \ \ + if (lim) \ + (kp)->p_rlim_rss_cur = \ + (lim)->pl_rlimit[RLIMIT_RSS].rlim_cur; \ + PR_UNLOCK(pr); \ + \ (kp)->p_stat = (p)->p_stat; \ (kp)->p_nice = (pr)->ps_nice; \ \ @@ -686,12 +693,6 @@ do { \ (kp)->p_wchan = PTRTOINT64((p)->p_wchan); \ } \ \ - PR_LOCK(pr); \ - if (lim) \ - (kp)->p_rlim_rss_cur = \ - (lim)->pl_rlimit[RLIMIT_RSS].rlim_cur; \ - PR_UNLOCK(pr); \ - \ if (((pr)->ps_flags & PS_ZOMBIE) == 0) { \ struct timeval __tv; \ \ -- cgit v1.2.3