diff options
| -rw-r--r-- | usr/src/uts/common/os/exec.c | 7 | ||||
| -rw-r--r-- | usr/src/uts/common/os/lwp.c | 3 | ||||
| -rw-r--r-- | usr/src/uts/common/os/sig.c | 46 | ||||
| -rw-r--r-- | usr/src/uts/common/os/timers.c | 61 | ||||
| -rw-r--r-- | usr/src/uts/common/sys/proc.h | 1 | ||||
| -rw-r--r-- | usr/src/uts/common/sys/timer.h | 5 | ||||
| -rw-r--r-- | usr/src/uts/i86pc/os/trap.c | 2 | ||||
| -rw-r--r-- | usr/src/uts/intel/ia32/os/syscall.c | 49 | ||||
| -rw-r--r-- | usr/src/uts/intel/sys/archsystm.h | 5 | ||||
| -rw-r--r-- | usr/src/uts/sparc/os/syscall.c | 50 | ||||
| -rw-r--r-- | usr/src/uts/sparc/sys/archsystm.h | 1 | ||||
| -rw-r--r-- | usr/src/uts/sun4/os/trap.c | 2 |
12 files changed, 129 insertions, 103 deletions
diff --git a/usr/src/uts/common/os/exec.c b/usr/src/uts/common/os/exec.c index 2ca011f17b..7bd4273c1d 100644 --- a/usr/src/uts/common/os/exec.c +++ b/usr/src/uts/common/os/exec.c @@ -1801,6 +1801,13 @@ exec_args(execa_t *uap, uarg_t *args, intpdata_t *intp, void **auxvpp) if (p->p_itimer != NULL) timer_exit(); + /* + * Delete the ITIMER_REALPROF interval timer. + * The other ITIMER_* interval timers are specified + * to be inherited across exec(). + */ + delete_itimer_realprof(); + if (audit_active) audit_exec(args->stk_base, args->stk_base + args->arglen, args->na - args->ne, args->ne); diff --git a/usr/src/uts/common/os/lwp.c b/usr/src/uts/common/os/lwp.c index a4bc1bffd2..bf827dd106 100644 --- a/usr/src/uts/common/os/lwp.c +++ b/usr/src/uts/common/os/lwp.c @@ -57,6 +57,7 @@ #include <sys/sdt.h> #include <sys/cmn_err.h> #include <sys/brand.h> +#include <sys/cyclic.h> /* hash function for the lwpid hash table, p->p_tidhash[] */ #define TIDHASH(tid, hash_sz) ((tid) & ((hash_sz) - 1)) @@ -205,7 +206,7 @@ lwp_create(void (*proc)(), caddr_t arg, size_t len, proc_t *p, /* * Allocate the SIGPROF buffer if ITIMER_REALPROF is in effect. */ - if (timerisset(&p->p_rprof_timer.it_value)) + if (p->p_rprof_cyclic != CYCLIC_NONE) t->t_rprof = kmem_zalloc(sizeof (struct rprof), KM_SLEEP); if (cid != NOCLASS) diff --git a/usr/src/uts/common/os/sig.c b/usr/src/uts/common/os/sig.c index 454b9e600f..481d6575af 100644 --- a/usr/src/uts/common/os/sig.c +++ b/usr/src/uts/common/os/sig.c @@ -56,6 +56,7 @@ #include <sys/core.h> #include <sys/schedctl.h> #include <sys/contract/process_impl.h> +#include <sys/cyclic.h> #include <sys/dtrace.h> #include <sys/sdt.h> @@ -2550,6 +2551,51 @@ trapsig(k_siginfo_t *ip, int restartable) mutex_exit(&p->p_lock); } +/* + * Arrange for the real time profiling signal to be dispatched. + */ +void +realsigprof(int sysnum, int nsysarg, int error) +{ + proc_t *p; + klwp_t *lwp; + + if (curthread->t_rprof->rp_anystate == 0) + return; + p = ttoproc(curthread); + lwp = ttolwp(curthread); + mutex_enter(&p->p_lock); + if (p->p_rprof_cyclic == CYCLIC_NONE) { + bzero(curthread->t_rprof, sizeof (*curthread->t_rprof)); + mutex_exit(&p->p_lock); + return; + } + if (sigismember(&p->p_ignore, SIGPROF) || + signal_is_blocked(curthread, SIGPROF)) { + mutex_exit(&p->p_lock); + return; + } + lwp->lwp_siginfo.si_signo = SIGPROF; + lwp->lwp_siginfo.si_code = PROF_SIG; + lwp->lwp_siginfo.si_errno = error; + hrt2ts(gethrtime(), &lwp->lwp_siginfo.si_tstamp); + lwp->lwp_siginfo.si_syscall = sysnum; + lwp->lwp_siginfo.si_nsysarg = nsysarg; + lwp->lwp_siginfo.si_fault = lwp->lwp_lastfault; + lwp->lwp_siginfo.si_faddr = lwp->lwp_lastfaddr; + lwp->lwp_lastfault = 0; + lwp->lwp_lastfaddr = NULL; + sigtoproc(p, curthread, SIGPROF); + mutex_exit(&p->p_lock); + ASSERT(lwp->lwp_cursig == 0); + if (issig(FORREAL)) + psig(); + mutex_enter(&p->p_lock); + lwp->lwp_siginfo.si_signo = 0; + bzero(curthread->t_rprof, sizeof (*curthread->t_rprof)); + mutex_exit(&p->p_lock); +} + #ifdef _SYSCALL32_IMPL /* diff --git a/usr/src/uts/common/os/timers.c b/usr/src/uts/common/os/timers.c index fbc204e526..2fc7b7bff2 100644 --- a/usr/src/uts/common/os/timers.c +++ b/usr/src/uts/common/os/timers.c @@ -18,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -519,6 +520,61 @@ xsetitimer(uint_t which, struct itimerval *itv, int iskaddr) } /* + * Delete the ITIMER_REALPROF interval timer. + * Called only from exec_args() when exec occurs. + * The other ITIMER_* interval timers are specified + * to be inherited across exec(), so leave them alone. + */ +void +delete_itimer_realprof(void) +{ + kthread_t *t = curthread; + struct proc *p = ttoproc(t); + klwp_t *lwp = ttolwp(t); + cyclic_id_t cyclic; + + mutex_enter(&p->p_lock); + + /* we are performing execve(); assert we are single-threaded */ + ASSERT(t == p->p_tlist && t == t->t_forw); + + if ((cyclic = p->p_rprof_cyclic) == CYCLIC_NONE) { + mutex_exit(&p->p_lock); + } else { + p->p_rprof_cyclic = CYCLIC_NONE; + /* + * Delete any current instance of SIGPROF. + */ + if (lwp->lwp_cursig == SIGPROF) { + lwp->lwp_cursig = 0; + lwp->lwp_extsig = 0; + if (lwp->lwp_curinfo) { + siginfofree(lwp->lwp_curinfo); + lwp->lwp_curinfo = NULL; + } + } + /* + * Delete any pending instances of SIGPROF. + */ + sigdelset(&p->p_sig, SIGPROF); + sigdelset(&p->p_extsig, SIGPROF); + sigdelq(p, NULL, SIGPROF); + sigdelset(&t->t_sig, SIGPROF); + sigdelset(&t->t_extsig, SIGPROF); + sigdelq(p, t, SIGPROF); + + mutex_exit(&p->p_lock); + + /* + * Remove the ITIMER_REALPROF cyclic. + */ + mutex_enter(&cpu_lock); + cyclic_remove(cyclic); + mutex_exit(&cpu_lock); + } +} + +/* * Real interval timer expired: * send process whose timer expired an alarm signal. * If time is not set up to reload, then just return. @@ -578,7 +634,8 @@ realprofexpire(void *arg) kthread_t *t; mutex_enter(&p->p_lock); - if ((t = p->p_tlist) == NULL) { + if (p->p_rprof_cyclic == CYCLIC_NONE || + (t = p->p_tlist) == NULL) { mutex_exit(&p->p_lock); return; } diff --git a/usr/src/uts/common/sys/proc.h b/usr/src/uts/common/sys/proc.h index 43407bab38..daacb058f7 100644 --- a/usr/src/uts/common/sys/proc.h +++ b/usr/src/uts/common/sys/proc.h @@ -613,6 +613,7 @@ extern void psignal(proc_t *, int); extern void tsignal(kthread_t *, int); extern void sigtoproc(proc_t *, kthread_t *, int); extern void trapsig(k_siginfo_t *, int); +extern void realsigprof(int, int, int); extern int eat_signal(kthread_t *, int); extern int signal_is_blocked(kthread_t *, int); extern int sigcheck(proc_t *, kthread_t *); diff --git a/usr/src/uts/common/sys/timer.h b/usr/src/uts/common/sys/timer.h index 05d08bb489..604ddf5d83 100644 --- a/usr/src/uts/common/sys/timer.h +++ b/usr/src/uts/common/sys/timer.h @@ -20,15 +20,13 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _SYS_TIMER_H #define _SYS_TIMER_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <sys/proc.h> #include <sys/thread.h> @@ -106,6 +104,7 @@ extern void timespecsub(timespec_t *, timespec_t *); extern void timespecfix(timespec_t *); extern int xgetitimer(uint_t, struct itimerval *, int); extern int xsetitimer(uint_t, struct itimerval *, int); +extern void delete_itimer_realprof(void); #define timerspecisset(tvp) ((tvp)->tv_sec || (tvp)->tv_nsec) #define timerspeccmp(tvp, uvp) (((tvp)->tv_sec - (uvp)->tv_sec) ? \ diff --git a/usr/src/uts/i86pc/os/trap.c b/usr/src/uts/i86pc/os/trap.c index fe6c2ca66b..cebc1d064a 100644 --- a/usr/src/uts/i86pc/os/trap.c +++ b/usr/src/uts/i86pc/os/trap.c @@ -1473,7 +1473,7 @@ trap(struct regs *rp, caddr_t addr, processorid_t cpuid) } if (ct->t_rprof != NULL) { - realsigprof(0, 0); + realsigprof(0, 0, 0); ct->t_sig_check = 1; } diff --git a/usr/src/uts/intel/ia32/os/syscall.c b/usr/src/uts/intel/ia32/os/syscall.c index ea01b28e7e..1ec901e231 100644 --- a/usr/src/uts/intel/ia32/os/syscall.c +++ b/usr/src/uts/intel/ia32/os/syscall.c @@ -20,12 +20,10 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/param.h> #include <sys/vmparam.h> #include <sys/types.h> @@ -83,47 +81,6 @@ void deferred_singlestep_trap(caddr_t); #endif /* - * Arrange for the real time profiling signal to be dispatched. - */ -void -realsigprof(int sysnum, int error) -{ - proc_t *p; - klwp_t *lwp; - - if (curthread->t_rprof->rp_anystate == 0) - return; - p = ttoproc(curthread); - lwp = ttolwp(curthread); - mutex_enter(&p->p_lock); - if (sigismember(&p->p_ignore, SIGPROF) || - signal_is_blocked(curthread, SIGPROF)) { - mutex_exit(&p->p_lock); - return; - } - lwp->lwp_siginfo.si_signo = SIGPROF; - lwp->lwp_siginfo.si_code = PROF_SIG; - lwp->lwp_siginfo.si_errno = error; - hrt2ts(gethrtime(), &lwp->lwp_siginfo.si_tstamp); - lwp->lwp_siginfo.si_syscall = sysnum; - lwp->lwp_siginfo.si_nsysarg = (sysnum > 0 && sysnum < NSYSCALL) ? - LWP_GETSYSENT(lwp)[sysnum].sy_narg : 0; - lwp->lwp_siginfo.si_fault = lwp->lwp_lastfault; - lwp->lwp_siginfo.si_faddr = lwp->lwp_lastfaddr; - lwp->lwp_lastfault = 0; - lwp->lwp_lastfaddr = NULL; - sigtoproc(p, curthread, SIGPROF); - mutex_exit(&p->p_lock); - ASSERT(lwp->lwp_cursig == 0); - if (issig(FORREAL)) - psig(); - mutex_enter(&p->p_lock); - lwp->lwp_siginfo.si_signo = 0; - bzero(curthread->t_rprof, sizeof (*curthread->t_rprof)); - mutex_exit(&p->p_lock); -} - -/* * If watchpoints are active, don't make copying in of * system call arguments take a read watchpoint trap. */ @@ -696,7 +653,9 @@ sig_check: } if (sigprof) { - realsigprof(code, error); + int nargs = (code > 0 && code < NSYSCALL)? + LWP_GETSYSENT(lwp)[code].sy_narg : 0; + realsigprof(code, nargs, error); t->t_sig_check = 1; /* recheck next time */ } diff --git a/usr/src/uts/intel/sys/archsystm.h b/usr/src/uts/intel/sys/archsystm.h index 44f8958723..fdd4f00478 100644 --- a/usr/src/uts/intel/sys/archsystm.h +++ b/usr/src/uts/intel/sys/archsystm.h @@ -18,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -136,8 +137,6 @@ struct regs; extern int instr_size(struct regs *, caddr_t *, enum seg_rw); -extern void realsigprof(int, int); - extern int enable_cbcp; /* patchable in /etc/system */ extern uint_t cpu_hwcap_flags; diff --git a/usr/src/uts/sparc/os/syscall.c b/usr/src/uts/sparc/os/syscall.c index bc5b2824f9..ea6b4bdf38 100644 --- a/usr/src/uts/sparc/os/syscall.c +++ b/usr/src/uts/sparc/os/syscall.c @@ -20,12 +20,10 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/param.h> #include <sys/vmparam.h> #include <sys/types.h> @@ -84,48 +82,6 @@ lwp_getsysent(klwp_t *lwp) #endif /* - * Arrange for the real time profiling signal to be dispatched. - */ -void -realsigprof(int sysnum, int error) -{ - proc_t *p; - klwp_t *lwp; - - if (curthread->t_rprof->rp_anystate == 0) - return; - p = ttoproc(curthread); - lwp = ttolwp(curthread); - mutex_enter(&p->p_lock); - if (sigismember(&p->p_ignore, SIGPROF) || - signal_is_blocked(curthread, SIGPROF)) { - mutex_exit(&p->p_lock); - return; - } - lwp->lwp_siginfo.si_signo = SIGPROF; - lwp->lwp_siginfo.si_code = PROF_SIG; - lwp->lwp_siginfo.si_errno = error; - hrt2ts(gethrtime(), &lwp->lwp_siginfo.si_tstamp); - lwp->lwp_siginfo.si_syscall = sysnum; - lwp->lwp_siginfo.si_nsysarg = (sysnum > 0 && sysnum < NSYSCALL) ? - LWP_GETSYSENT(lwp)[sysnum].sy_narg : 0; - lwp->lwp_siginfo.si_fault = lwp->lwp_lastfault; - lwp->lwp_siginfo.si_faddr = lwp->lwp_lastfaddr; - lwp->lwp_lastfault = 0; - lwp->lwp_lastfaddr = NULL; - sigtoproc(p, curthread, SIGPROF); - mutex_exit(&p->p_lock); - ASSERT(lwp->lwp_cursig == 0); - if (issig(FORREAL)) { - psig(); - } - mutex_enter(&p->p_lock); - lwp->lwp_siginfo.si_signo = 0; - bzero(curthread->t_rprof, sizeof (*curthread->t_rprof)); - mutex_exit(&p->p_lock); -} - -/* * Called to restore the lwp's register window just before * returning to user level (only if the registers have been * fetched or modified through /proc). @@ -793,7 +749,9 @@ sig_check: } if (sigprof) { - realsigprof(code, error); + int nargs = (code > 0 && code < NSYSCALL)? + LWP_GETSYSENT(lwp)[code].sy_narg : 0; + realsigprof(code, nargs, error); t->t_sig_check = 1; /* recheck next time */ } diff --git a/usr/src/uts/sparc/sys/archsystm.h b/usr/src/uts/sparc/sys/archsystm.h index 3d13f987bc..bdd3ea66b1 100644 --- a/usr/src/uts/sparc/sys/archsystm.h +++ b/usr/src/uts/sparc/sys/archsystm.h @@ -49,7 +49,6 @@ extern greg_t getpsr(void); extern uint_t getpil(void); extern void setpil(uint_t); extern greg_t gettbr(void); -extern void realsigprof(int, int); extern uintptr_t shm_alignment; diff --git a/usr/src/uts/sun4/os/trap.c b/usr/src/uts/sun4/os/trap.c index 1bef1b475e..0d80f1e8d6 100644 --- a/usr/src/uts/sun4/os/trap.c +++ b/usr/src/uts/sun4/os/trap.c @@ -1312,7 +1312,7 @@ trap_cleanup( } if (curthread->t_rprof != NULL) { - realsigprof(0, 0); + realsigprof(0, 0, 0); curthread->t_sig_check = 1; } } |
