From 380344a7af2843a004d4d34feb19fccad8ebfb1f Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Tue, 8 Mar 2016 00:43:03 +0000 Subject: Fix fasttrap tracepoint locking. Upstream, tracepoints are protected by per-CPU mutexes. An unlinked tracepoint may be freed once all the tracepoint mutexes have been acquired and released - this is done in fasttrap_mod_barrier(). This mechanism was not properly ported: in some places, the proc lock is used in place of a tracepoint lock, and in others the locking is omitted entirely. This change implements tracepoint locking with an rmlock, where the read lock is used in fasttrap probe context. As a side effect, this fixes a recursion on the proc lock when the raise action is used from a userland probe. MFC after: 1 month --- .../contrib/opensolaris/uts/powerpc/dtrace/fasttrap_isa.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'sys/cddl/contrib/opensolaris/uts/powerpc') diff --git a/sys/cddl/contrib/opensolaris/uts/powerpc/dtrace/fasttrap_isa.c b/sys/cddl/contrib/opensolaris/uts/powerpc/dtrace/fasttrap_isa.c index 8e4c647199ce..e8dd684a4530 100644 --- a/sys/cddl/contrib/opensolaris/uts/powerpc/dtrace/fasttrap_isa.c +++ b/sys/cddl/contrib/opensolaris/uts/powerpc/dtrace/fasttrap_isa.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #define OP(x) ((x) >> 26) @@ -288,10 +289,12 @@ static void fasttrap_return_common(struct reg *rp, uintptr_t pc, pid_t pid, uintptr_t new_pc) { + struct rm_priotracker tracker; fasttrap_tracepoint_t *tp; fasttrap_bucket_t *bucket; fasttrap_id_t *id; + rm_rlock(&fasttrap_tp_lock, &tracker); bucket = &fasttrap_tpoints.fth_table[FASTTRAP_TPOINTS_INDEX(pid, pc)]; for (tp = bucket->ftb_data; tp != NULL; tp = tp->ftt_next) { @@ -306,6 +309,7 @@ fasttrap_return_common(struct reg *rp, uintptr_t pc, pid_t pid, * is not essential to the correct execution of the process. */ if (tp == NULL) { + rm_runlock(&fasttrap_tp_lock, &tracker); return; } @@ -323,6 +327,7 @@ fasttrap_return_common(struct reg *rp, uintptr_t pc, pid_t pid, pc - id->fti_probe->ftp_faddr, rp->fixreg[3], rp->fixreg[4], 0, 0); } + rm_runlock(&fasttrap_tp_lock, &tracker); } @@ -351,6 +356,7 @@ fasttrap_branch_taken(int bo, int bi, struct reg *regs) int fasttrap_pid_probe(struct reg *rp) { + struct rm_priotracker tracker; proc_t *p = curproc; uintptr_t pc = rp->pc; uintptr_t new_pc = 0; @@ -381,8 +387,7 @@ fasttrap_pid_probe(struct reg *rp) curthread->t_dtrace_scrpc = 0; curthread->t_dtrace_astpc = 0; - - PROC_LOCK(p); + rm_rlock(&fasttrap_tp_lock, &tracker); pid = p->p_pid; bucket = &fasttrap_tpoints.fth_table[FASTTRAP_TPOINTS_INDEX(pid, pc)]; @@ -401,7 +406,7 @@ fasttrap_pid_probe(struct reg *rp) * fasttrap_ioctl), or somehow we have mislaid this tracepoint. */ if (tp == NULL) { - PROC_UNLOCK(p); + rm_runlock(&fasttrap_tp_lock, &tracker); return (-1); } @@ -455,7 +460,7 @@ fasttrap_pid_probe(struct reg *rp) * tracepoint again later if we need to light up any return probes. */ tp_local = *tp; - PROC_UNLOCK(p); + rm_runlock(&fasttrap_tp_lock, &tracker); tp = &tp_local; /* -- cgit v1.2.3