1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
--- 6 unchanged lines hidden (view full) ---
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 *
21 * Portions Copyright 2010 The FreeBSD Foundation
22 *
23 * $FreeBSD: head/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c 264434 2014-04-14 00:22:42Z markj $
24 */
25
26/*
27 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
29 */
30
31#if defined(sun)
--- 24 unchanged lines hidden (view full) ---
56#include <sys/proc.h>
57#include <sys/policy.h>
58#if defined(sun)
59#include <util/qsort.h>
60#endif
61#include <sys/mutex.h>
62#include <sys/kernel.h>
63#if !defined(sun)
64#include <sys/dtrace_bsd.h>
65#include <sys/eventhandler.h>
66#include <sys/user.h>
67#include <vm/vm.h>
68#include <vm/pmap.h>
69#include <vm/vm_map.h>
70#include <vm/vm_param.h>
71#include <cddl/dev/dtrace/dtrace_cddl.h>
72#endif
73
74/*
75 * User-Land Trap-Based Tracing
76 * ----------------------------
77 *
78 * The fasttrap provider allows DTrace consumers to instrument any user-level
--- 127 unchanged lines hidden (view full) ---
206static fasttrap_provider_t *fasttrap_provider_lookup(pid_t, const char *,
207 const dtrace_pattr_t *);
208static void fasttrap_provider_retire(pid_t, const char *, int);
209static void fasttrap_provider_free(fasttrap_provider_t *);
210
211static fasttrap_proc_t *fasttrap_proc_lookup(pid_t);
212static void fasttrap_proc_release(fasttrap_proc_t *);
213
214#if !defined(sun)
215static void fasttrap_thread_dtor(void *, struct thread *);
216#endif
217
218#define FASTTRAP_PROVS_INDEX(pid, name) \
219 ((fasttrap_hash_str(name) + (pid)) & fasttrap_provs.fth_mask)
220
221#define FASTTRAP_PROCS_INDEX(pid) ((pid) & fasttrap_procs.fth_mask)
222
223#if !defined(sun)
224static kmutex_t fasttrap_cpuc_pid_lock[MAXCPU];
225static eventhandler_tag fasttrap_thread_dtor_tag;
226#endif
227
228static int
229fasttrap_highbit(ulong_t i)
230{
231 int h = 1;
232
233 if (i == 0)
--- 60 unchanged lines hidden (view full) ---
294 ksi->ksi_code = TRAP_DTRACE;
295 ksi->ksi_addr = (caddr_t)pc;
296 PROC_LOCK(p);
297 (void) tdksignal(t, SIGTRAP, ksi);
298 PROC_UNLOCK(p);
299#endif
300}
301
302#if !defined(sun)
303/*
304 * Obtain a chunk of scratch space in the address space of the target process.
305 */
306fasttrap_scrspace_t *
307fasttrap_scraddr(struct thread *td, fasttrap_proc_t *fprc)
308{
309 fasttrap_scrblock_t *scrblk;
310 fasttrap_scrspace_t *scrspc;
311 struct proc *p;
312 vm_offset_t addr;
313 int error, i;
314
315 scrspc = NULL;
316 if (td->t_dtrace_sscr != NULL) {
317 /* If the thread already has scratch space, we're done. */
318 scrspc = (fasttrap_scrspace_t *)td->t_dtrace_sscr;
319 return (scrspc);
320 }
321
322 p = td->td_proc;
323
324 mutex_enter(&fprc->ftpc_mtx);
325 if (LIST_EMPTY(&fprc->ftpc_fscr)) {
326 /*
327 * No scratch space is available, so we'll map a new scratch
328 * space block into the traced process' address space.
329 */
330 addr = 0;
331 error = vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr,
332 FASTTRAP_SCRBLOCK_SIZE, 0, VMFS_ANY_SPACE, VM_PROT_ALL,
333 VM_PROT_ALL, 0);
334 if (error != KERN_SUCCESS)
335 goto done;
336
337 scrblk = malloc(sizeof(*scrblk), M_SOLARIS, M_WAITOK);
338 scrblk->ftsb_addr = addr;
339 LIST_INSERT_HEAD(&fprc->ftpc_scrblks, scrblk, ftsb_next);
340
341 /*
342 * Carve the block up into chunks and put them on the free list.
343 */
344 for (i = 0;
345 i < FASTTRAP_SCRBLOCK_SIZE / FASTTRAP_SCRSPACE_SIZE; i++) {
346 scrspc = malloc(sizeof(*scrspc), M_SOLARIS, M_WAITOK);
347 scrspc->ftss_addr = addr +
348 i * FASTTRAP_SCRSPACE_SIZE;
349 LIST_INSERT_HEAD(&fprc->ftpc_fscr, scrspc,
350 ftss_next);
351 }
352 }
353
354 /*
355 * Take the first scratch chunk off the free list, put it on the
356 * allocated list, and return its address.
357 */
358 scrspc = LIST_FIRST(&fprc->ftpc_fscr);
359 LIST_REMOVE(scrspc, ftss_next);
360 LIST_INSERT_HEAD(&fprc->ftpc_ascr, scrspc, ftss_next);
361
362 /*
363 * This scratch space is reserved for use by td until the thread exits.
364 */
365 td->t_dtrace_sscr = scrspc;
366
367done:
368 mutex_exit(&fprc->ftpc_mtx);
369
370 return (scrspc);
371}
372
373/*
374 * Return any allocated per-thread scratch space chunks back to the process'
375 * free list.
376 */
377static void
378fasttrap_thread_dtor(void *arg __unused, struct thread *td)
379{
380 fasttrap_bucket_t *bucket;
381 fasttrap_proc_t *fprc;
382 fasttrap_scrspace_t *scrspc;
383 pid_t pid;
384
385 if (td->t_dtrace_sscr == NULL)
386 return;
387
388 pid = td->td_proc->p_pid;
389 bucket = &fasttrap_procs.fth_table[FASTTRAP_PROCS_INDEX(pid)];
390 fprc = NULL;
391
392 /* Look up the fasttrap process handle for this process. */
393 mutex_enter(&bucket->ftb_mtx);
394 for (fprc = bucket->ftb_data; fprc != NULL; fprc = fprc->ftpc_next) {
395 if (fprc->ftpc_pid == pid) {
396 mutex_enter(&fprc->ftpc_mtx);
397 mutex_exit(&bucket->ftb_mtx);
398 break;
399 }
400 }
401 if (fprc == NULL) {
402 mutex_exit(&bucket->ftb_mtx);
403 return;
404 }
405
406 scrspc = (fasttrap_scrspace_t *)td->t_dtrace_sscr;
407 LIST_REMOVE(scrspc, ftss_next);
408 LIST_INSERT_HEAD(&fprc->ftpc_fscr, scrspc, ftss_next);
409
410 mutex_exit(&fprc->ftpc_mtx);
411}
412#endif
413
414/*
415 * This function ensures that no threads are actively using the memory
416 * associated with probes that were formerly live.
417 */
418static void
419fasttrap_mod_barrier(uint64_t gen)
420{
421 int i;
422
--- 143 unchanged lines hidden (view full) ---
566 * This is called from cfork() via dtrace_fasttrap_fork(). The child
567 * process's address space is (roughly) a copy of the parent process's so
568 * we have to remove all the instrumentation we had previously enabled in the
569 * parent.
570 */
571static void
572fasttrap_fork(proc_t *p, proc_t *cp)
573{
574#if !defined(sun)
575 fasttrap_scrblock_t *scrblk;
576 fasttrap_proc_t *fprc = NULL;
577#endif
578 pid_t ppid = p->p_pid;
579 int i;
580
581#if defined(sun)
582 ASSERT(curproc == p);
583 ASSERT(p->p_proc_flag & P_PR_LOCK);
584#else
585 PROC_LOCK_ASSERT(p, MA_OWNED);
--- 69 unchanged lines hidden (view full) ---
655 /*
656 * The count of active providers can only be
657 * decremented (i.e. to zero) during exec,
658 * exit, and removal of a meta provider so it
659 * should be impossible to drop the count
660 * mid-fork.
661 */
662 ASSERT(tp->ftt_proc->ftpc_acount != 0);
663#if !defined(sun)
664 fprc = tp->ftt_proc;
665#endif
666 }
667 }
668 mutex_exit(&bucket->ftb_mtx);
669
670#if !defined(sun)
671 /*
672 * Unmap any scratch space inherited from the parent's address
673 * space.
674 */
675 if (fprc != NULL) {
676 mutex_enter(&fprc->ftpc_mtx);
677 LIST_FOREACH(scrblk, &fprc->ftpc_scrblks, ftsb_next) {
678 vm_map_remove(&cp->p_vmspace->vm_map,
679 scrblk->ftsb_addr,
680 scrblk->ftsb_addr + FASTTRAP_SCRBLOCK_SIZE);
681 }
682 mutex_exit(&fprc->ftpc_mtx);
683 }
684#endif
685 }
686
687#if defined(sun)
688 mutex_enter(&cp->p_lock);
689 sprunlock(cp);
690#else
691 PROC_LOCK(p);
692 PROC_LOCK(cp);
--- 4 unchanged lines hidden (view full) ---
697/*
698 * This is called from proc_exit() or from exec_common() if p_dtrace_probes
699 * is set on the proc structure to indicate that there is a pid provider
700 * associated with this process.
701 */
702static void
703fasttrap_exec_exit(proc_t *p)
704{
705#if !defined(sun)
706 struct thread *td;
707#endif
708
709#if defined(sun)
710 ASSERT(p == curproc);
711#else
712 PROC_LOCK_ASSERT(p, MA_OWNED);
713 _PHOLD(p);
714 /*
715 * Since struct threads may be recycled, we cannot rely on t_dtrace_sscr
716 * fields to be zeroed by kdtrace_thread_ctor. Thus we must zero it
717 * ourselves when a process exits.
718 */
719 FOREACH_THREAD_IN_PROC(p, td)
720 td->t_dtrace_sscr = NULL;
721 PROC_UNLOCK(p);
722#endif
723
724 /*
725 * We clean up the pid provider for this process here; user-land
726 * static probes are handled by the meta-provider remove entry point.
727 */
728 fasttrap_provider_retire(p->p_pid, FASTTRAP_PID_NAME, 0);
729#if !defined(sun)
730 if (p->p_dtrace_helpers)
731 dtrace_helpers_destroy(p);
732 PROC_LOCK(p);
733 _PRELE(p);
734#endif
735}
736
737
738/*ARGSUSED*/
739static void
740fasttrap_pid_provide(void *arg, dtrace_probedesc_t *desc)
741{
742 /*
--- 776 unchanged lines hidden (view full) ---
1519}
1520
1521static void
1522fasttrap_proc_release(fasttrap_proc_t *proc)
1523{
1524 fasttrap_bucket_t *bucket;
1525 fasttrap_proc_t *fprc, **fprcp;
1526 pid_t pid = proc->ftpc_pid;
1527#if !defined(sun)
1528 fasttrap_scrblock_t *scrblk, *scrblktmp;
1529 fasttrap_scrspace_t *scrspc, *scrspctmp;
1530 struct proc *p;
1531 struct thread *td;
1532#endif
1533
1534 mutex_enter(&proc->ftpc_mtx);
1535
1536 ASSERT(proc->ftpc_rcount != 0);
1537 ASSERT(proc->ftpc_acount <= proc->ftpc_rcount);
1538
1539 if (--proc->ftpc_rcount != 0) {
1540 mutex_exit(&proc->ftpc_mtx);
1541 return;
1542 }
1543
1544#if !defined(sun)
1545 /*
1546 * Free all structures used to manage per-thread scratch space.
1547 */
1548 LIST_FOREACH_SAFE(scrblk, &proc->ftpc_scrblks, ftsb_next,
1549 scrblktmp) {
1550 LIST_REMOVE(scrblk, ftsb_next);
1551 free(scrblk, M_SOLARIS);
1552 }
1553 LIST_FOREACH_SAFE(scrspc, &proc->ftpc_fscr, ftss_next, scrspctmp) {
1554 LIST_REMOVE(scrspc, ftss_next);
1555 free(scrspc, M_SOLARIS);
1556 }
1557 LIST_FOREACH_SAFE(scrspc, &proc->ftpc_ascr, ftss_next, scrspctmp) {
1558 LIST_REMOVE(scrspc, ftss_next);
1559 free(scrspc, M_SOLARIS);
1560 }
1561
1562 if ((p = pfind(pid)) != NULL) {
1563 FOREACH_THREAD_IN_PROC(p, td)
1564 td->t_dtrace_sscr = NULL;
1565 PROC_UNLOCK(p);
1566 }
1567#endif
1568
1569 mutex_exit(&proc->ftpc_mtx);
1570
1571 /*
1572 * There should definitely be no live providers associated with this
1573 * process at this point.
1574 */
1575 ASSERT(proc->ftpc_acount == 0);
1576
--- 969 unchanged lines hidden (view full) ---
2546 for (i = 0; i < fasttrap_procs.fth_nent; i++)
2547 mutex_init(&fasttrap_procs.fth_table[i].ftb_mtx,
2548 "processes bucket mtx", MUTEX_DEFAULT, NULL);
2549
2550 CPU_FOREACH(i) {
2551 mutex_init(&fasttrap_cpuc_pid_lock[i], "fasttrap barrier",
2552 MUTEX_DEFAULT, NULL);
2553 }
2554
2555 /*
2556 * This event handler must run before kdtrace_thread_dtor() since it
2557 * accesses the thread's struct kdtrace_thread.
2558 */
2559 fasttrap_thread_dtor_tag = EVENTHANDLER_REGISTER(thread_dtor,
2560 fasttrap_thread_dtor, NULL, EVENTHANDLER_PRI_FIRST);
2561#endif
2562
2563 /*
2564 * Install our hooks into fork(2), exec(2), and exit(2).
2565 */
2566 dtrace_fasttrap_fork = &fasttrap_fork;
2567 dtrace_fasttrap_exit = &fasttrap_exec_exit;
2568 dtrace_fasttrap_exec = &fasttrap_exec_exit;
--- 85 unchanged lines hidden (view full) ---
2654
2655#ifdef DEBUG
2656 mutex_enter(&fasttrap_count_mtx);
2657 ASSERT(fasttrap_pid_count == 0);
2658 mutex_exit(&fasttrap_count_mtx);
2659#endif
2660
2661#if !defined(sun)
2662 EVENTHANDLER_DEREGISTER(thread_dtor, fasttrap_thread_dtor_tag);
2663
2664 for (i = 0; i < fasttrap_tpoints.fth_nent; i++)
2665 mutex_destroy(&fasttrap_tpoints.fth_table[i].ftb_mtx);
2666 for (i = 0; i < fasttrap_provs.fth_nent; i++)
2667 mutex_destroy(&fasttrap_provs.fth_table[i].ftb_mtx);
2668 for (i = 0; i < fasttrap_procs.fth_nent; i++)
2669 mutex_destroy(&fasttrap_procs.fth_table[i].ftb_mtx);
2670#endif
2671 kmem_free(fasttrap_tpoints.fth_table,
--- 54 unchanged lines hidden ---
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
--- 6 unchanged lines hidden (view full) ---
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 *
21 * Portions Copyright 2010 The FreeBSD Foundation
22 *
23 * $FreeBSD: head/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c 264434 2014-04-14 00:22:42Z markj $
24 */
25
26/*
27 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
29 */
30
31#if defined(sun)
--- 24 unchanged lines hidden (view full) ---
56#include <sys/proc.h>
57#include <sys/policy.h>
58#if defined(sun)
59#include <util/qsort.h>
60#endif
61#include <sys/mutex.h>
62#include <sys/kernel.h>
63#if !defined(sun)
64#include <sys/dtrace_bsd.h>
65#include <sys/eventhandler.h>
66#include <sys/user.h>
67#include <vm/vm.h>
68#include <vm/pmap.h>
69#include <vm/vm_map.h>
70#include <vm/vm_param.h>
71#include <cddl/dev/dtrace/dtrace_cddl.h>
72#endif
73
74/*
75 * User-Land Trap-Based Tracing
76 * ----------------------------
77 *
78 * The fasttrap provider allows DTrace consumers to instrument any user-level
--- 127 unchanged lines hidden (view full) ---
206static fasttrap_provider_t *fasttrap_provider_lookup(pid_t, const char *,
207 const dtrace_pattr_t *);
208static void fasttrap_provider_retire(pid_t, const char *, int);
209static void fasttrap_provider_free(fasttrap_provider_t *);
210
211static fasttrap_proc_t *fasttrap_proc_lookup(pid_t);
212static void fasttrap_proc_release(fasttrap_proc_t *);
213
214#if !defined(sun)
215static void fasttrap_thread_dtor(void *, struct thread *);
216#endif
217
218#define FASTTRAP_PROVS_INDEX(pid, name) \
219 ((fasttrap_hash_str(name) + (pid)) & fasttrap_provs.fth_mask)
220
221#define FASTTRAP_PROCS_INDEX(pid) ((pid) & fasttrap_procs.fth_mask)
222
223#if !defined(sun)
224static kmutex_t fasttrap_cpuc_pid_lock[MAXCPU];
225static eventhandler_tag fasttrap_thread_dtor_tag;
226#endif
227
228static int
229fasttrap_highbit(ulong_t i)
230{
231 int h = 1;
232
233 if (i == 0)
--- 60 unchanged lines hidden (view full) ---
294 ksi->ksi_code = TRAP_DTRACE;
295 ksi->ksi_addr = (caddr_t)pc;
296 PROC_LOCK(p);
297 (void) tdksignal(t, SIGTRAP, ksi);
298 PROC_UNLOCK(p);
299#endif
300}
301
302#if !defined(sun)
303/*
304 * Obtain a chunk of scratch space in the address space of the target process.
305 */
306fasttrap_scrspace_t *
307fasttrap_scraddr(struct thread *td, fasttrap_proc_t *fprc)
308{
309 fasttrap_scrblock_t *scrblk;
310 fasttrap_scrspace_t *scrspc;
311 struct proc *p;
312 vm_offset_t addr;
313 int error, i;
314
315 scrspc = NULL;
316 if (td->t_dtrace_sscr != NULL) {
317 /* If the thread already has scratch space, we're done. */
318 scrspc = (fasttrap_scrspace_t *)td->t_dtrace_sscr;
319 return (scrspc);
320 }
321
322 p = td->td_proc;
323
324 mutex_enter(&fprc->ftpc_mtx);
325 if (LIST_EMPTY(&fprc->ftpc_fscr)) {
326 /*
327 * No scratch space is available, so we'll map a new scratch
328 * space block into the traced process' address space.
329 */
330 addr = 0;
331 error = vm_map_find(&p->p_vmspace->vm_map, NULL, 0, &addr,
332 FASTTRAP_SCRBLOCK_SIZE, 0, VMFS_ANY_SPACE, VM_PROT_ALL,
333 VM_PROT_ALL, 0);
334 if (error != KERN_SUCCESS)
335 goto done;
336
337 scrblk = malloc(sizeof(*scrblk), M_SOLARIS, M_WAITOK);
338 scrblk->ftsb_addr = addr;
339 LIST_INSERT_HEAD(&fprc->ftpc_scrblks, scrblk, ftsb_next);
340
341 /*
342 * Carve the block up into chunks and put them on the free list.
343 */
344 for (i = 0;
345 i < FASTTRAP_SCRBLOCK_SIZE / FASTTRAP_SCRSPACE_SIZE; i++) {
346 scrspc = malloc(sizeof(*scrspc), M_SOLARIS, M_WAITOK);
347 scrspc->ftss_addr = addr +
348 i * FASTTRAP_SCRSPACE_SIZE;
349 LIST_INSERT_HEAD(&fprc->ftpc_fscr, scrspc,
350 ftss_next);
351 }
352 }
353
354 /*
355 * Take the first scratch chunk off the free list, put it on the
356 * allocated list, and return its address.
357 */
358 scrspc = LIST_FIRST(&fprc->ftpc_fscr);
359 LIST_REMOVE(scrspc, ftss_next);
360 LIST_INSERT_HEAD(&fprc->ftpc_ascr, scrspc, ftss_next);
361
362 /*
363 * This scratch space is reserved for use by td until the thread exits.
364 */
365 td->t_dtrace_sscr = scrspc;
366
367done:
368 mutex_exit(&fprc->ftpc_mtx);
369
370 return (scrspc);
371}
372
373/*
374 * Return any allocated per-thread scratch space chunks back to the process'
375 * free list.
376 */
377static void
378fasttrap_thread_dtor(void *arg __unused, struct thread *td)
379{
380 fasttrap_bucket_t *bucket;
381 fasttrap_proc_t *fprc;
382 fasttrap_scrspace_t *scrspc;
383 pid_t pid;
384
385 if (td->t_dtrace_sscr == NULL)
386 return;
387
388 pid = td->td_proc->p_pid;
389 bucket = &fasttrap_procs.fth_table[FASTTRAP_PROCS_INDEX(pid)];
390 fprc = NULL;
391
392 /* Look up the fasttrap process handle for this process. */
393 mutex_enter(&bucket->ftb_mtx);
394 for (fprc = bucket->ftb_data; fprc != NULL; fprc = fprc->ftpc_next) {
395 if (fprc->ftpc_pid == pid) {
396 mutex_enter(&fprc->ftpc_mtx);
397 mutex_exit(&bucket->ftb_mtx);
398 break;
399 }
400 }
401 if (fprc == NULL) {
402 mutex_exit(&bucket->ftb_mtx);
403 return;
404 }
405
406 scrspc = (fasttrap_scrspace_t *)td->t_dtrace_sscr;
407 LIST_REMOVE(scrspc, ftss_next);
408 LIST_INSERT_HEAD(&fprc->ftpc_fscr, scrspc, ftss_next);
409
410 mutex_exit(&fprc->ftpc_mtx);
411}
412#endif
413
414/*
415 * This function ensures that no threads are actively using the memory
416 * associated with probes that were formerly live.
417 */
418static void
419fasttrap_mod_barrier(uint64_t gen)
420{
421 int i;
422
--- 143 unchanged lines hidden (view full) ---
566 * This is called from cfork() via dtrace_fasttrap_fork(). The child
567 * process's address space is (roughly) a copy of the parent process's so
568 * we have to remove all the instrumentation we had previously enabled in the
569 * parent.
570 */
571static void
572fasttrap_fork(proc_t *p, proc_t *cp)
573{
574#if !defined(sun)
575 fasttrap_scrblock_t *scrblk;
576 fasttrap_proc_t *fprc = NULL;
577#endif
578 pid_t ppid = p->p_pid;
579 int i;
580
581#if defined(sun)
582 ASSERT(curproc == p);
583 ASSERT(p->p_proc_flag & P_PR_LOCK);
584#else
585 PROC_LOCK_ASSERT(p, MA_OWNED);
--- 69 unchanged lines hidden (view full) ---
655 /*
656 * The count of active providers can only be
657 * decremented (i.e. to zero) during exec,
658 * exit, and removal of a meta provider so it
659 * should be impossible to drop the count
660 * mid-fork.
661 */
662 ASSERT(tp->ftt_proc->ftpc_acount != 0);
663#if !defined(sun)
664 fprc = tp->ftt_proc;
665#endif
666 }
667 }
668 mutex_exit(&bucket->ftb_mtx);
669
670#if !defined(sun)
671 /*
672 * Unmap any scratch space inherited from the parent's address
673 * space.
674 */
675 if (fprc != NULL) {
676 mutex_enter(&fprc->ftpc_mtx);
677 LIST_FOREACH(scrblk, &fprc->ftpc_scrblks, ftsb_next) {
678 vm_map_remove(&cp->p_vmspace->vm_map,
679 scrblk->ftsb_addr,
680 scrblk->ftsb_addr + FASTTRAP_SCRBLOCK_SIZE);
681 }
682 mutex_exit(&fprc->ftpc_mtx);
683 }
684#endif
685 }
686
687#if defined(sun)
688 mutex_enter(&cp->p_lock);
689 sprunlock(cp);
690#else
691 PROC_LOCK(p);
692 PROC_LOCK(cp);
--- 4 unchanged lines hidden (view full) ---
697/*
698 * This is called from proc_exit() or from exec_common() if p_dtrace_probes
699 * is set on the proc structure to indicate that there is a pid provider
700 * associated with this process.
701 */
702static void
703fasttrap_exec_exit(proc_t *p)
704{
705#if !defined(sun)
706 struct thread *td;
707#endif
708
709#if defined(sun)
710 ASSERT(p == curproc);
711#else
712 PROC_LOCK_ASSERT(p, MA_OWNED);
713 _PHOLD(p);
714 /*
715 * Since struct threads may be recycled, we cannot rely on t_dtrace_sscr
716 * fields to be zeroed by kdtrace_thread_ctor. Thus we must zero it
717 * ourselves when a process exits.
718 */
719 FOREACH_THREAD_IN_PROC(p, td)
720 td->t_dtrace_sscr = NULL;
721 PROC_UNLOCK(p);
722#endif
723
724 /*
725 * We clean up the pid provider for this process here; user-land
726 * static probes are handled by the meta-provider remove entry point.
727 */
728 fasttrap_provider_retire(p->p_pid, FASTTRAP_PID_NAME, 0);
729#if !defined(sun)
730 if (p->p_dtrace_helpers)
731 dtrace_helpers_destroy(p);
732 PROC_LOCK(p);
733 _PRELE(p);
734#endif
735}
736
737
738/*ARGSUSED*/
739static void
740fasttrap_pid_provide(void *arg, dtrace_probedesc_t *desc)
741{
742 /*
--- 776 unchanged lines hidden (view full) ---
1519}
1520
1521static void
1522fasttrap_proc_release(fasttrap_proc_t *proc)
1523{
1524 fasttrap_bucket_t *bucket;
1525 fasttrap_proc_t *fprc, **fprcp;
1526 pid_t pid = proc->ftpc_pid;
1527#if !defined(sun)
1528 fasttrap_scrblock_t *scrblk, *scrblktmp;
1529 fasttrap_scrspace_t *scrspc, *scrspctmp;
1530 struct proc *p;
1531 struct thread *td;
1532#endif
1533
1534 mutex_enter(&proc->ftpc_mtx);
1535
1536 ASSERT(proc->ftpc_rcount != 0);
1537 ASSERT(proc->ftpc_acount <= proc->ftpc_rcount);
1538
1539 if (--proc->ftpc_rcount != 0) {
1540 mutex_exit(&proc->ftpc_mtx);
1541 return;
1542 }
1543
1544#if !defined(sun)
1545 /*
1546 * Free all structures used to manage per-thread scratch space.
1547 */
1548 LIST_FOREACH_SAFE(scrblk, &proc->ftpc_scrblks, ftsb_next,
1549 scrblktmp) {
1550 LIST_REMOVE(scrblk, ftsb_next);
1551 free(scrblk, M_SOLARIS);
1552 }
1553 LIST_FOREACH_SAFE(scrspc, &proc->ftpc_fscr, ftss_next, scrspctmp) {
1554 LIST_REMOVE(scrspc, ftss_next);
1555 free(scrspc, M_SOLARIS);
1556 }
1557 LIST_FOREACH_SAFE(scrspc, &proc->ftpc_ascr, ftss_next, scrspctmp) {
1558 LIST_REMOVE(scrspc, ftss_next);
1559 free(scrspc, M_SOLARIS);
1560 }
1561
1562 if ((p = pfind(pid)) != NULL) {
1563 FOREACH_THREAD_IN_PROC(p, td)
1564 td->t_dtrace_sscr = NULL;
1565 PROC_UNLOCK(p);
1566 }
1567#endif
1568
1569 mutex_exit(&proc->ftpc_mtx);
1570
1571 /*
1572 * There should definitely be no live providers associated with this
1573 * process at this point.
1574 */
1575 ASSERT(proc->ftpc_acount == 0);
1576
--- 969 unchanged lines hidden (view full) ---
2546 for (i = 0; i < fasttrap_procs.fth_nent; i++)
2547 mutex_init(&fasttrap_procs.fth_table[i].ftb_mtx,
2548 "processes bucket mtx", MUTEX_DEFAULT, NULL);
2549
2550 CPU_FOREACH(i) {
2551 mutex_init(&fasttrap_cpuc_pid_lock[i], "fasttrap barrier",
2552 MUTEX_DEFAULT, NULL);
2553 }
2554
2555 /*
2556 * This event handler must run before kdtrace_thread_dtor() since it
2557 * accesses the thread's struct kdtrace_thread.
2558 */
2559 fasttrap_thread_dtor_tag = EVENTHANDLER_REGISTER(thread_dtor,
2560 fasttrap_thread_dtor, NULL, EVENTHANDLER_PRI_FIRST);
2561#endif
2562
2563 /*
2564 * Install our hooks into fork(2), exec(2), and exit(2).
2565 */
2566 dtrace_fasttrap_fork = &fasttrap_fork;
2567 dtrace_fasttrap_exit = &fasttrap_exec_exit;
2568 dtrace_fasttrap_exec = &fasttrap_exec_exit;
--- 85 unchanged lines hidden (view full) ---
2654
2655#ifdef DEBUG
2656 mutex_enter(&fasttrap_count_mtx);
2657 ASSERT(fasttrap_pid_count == 0);
2658 mutex_exit(&fasttrap_count_mtx);
2659#endif
2660
2661#if !defined(sun)
2662 EVENTHANDLER_DEREGISTER(thread_dtor, fasttrap_thread_dtor_tag);
2663
2664 for (i = 0; i < fasttrap_tpoints.fth_nent; i++)
2665 mutex_destroy(&fasttrap_tpoints.fth_table[i].ftb_mtx);
2666 for (i = 0; i < fasttrap_provs.fth_nent; i++)
2667 mutex_destroy(&fasttrap_provs.fth_table[i].ftb_mtx);
2668 for (i = 0; i < fasttrap_procs.fth_nent; i++)
2669 mutex_destroy(&fasttrap_procs.fth_table[i].ftb_mtx);
2670#endif
2671 kmem_free(fasttrap_tpoints.fth_table,
--- 54 unchanged lines hidden ---