FreeBSD/sys/cddl/contrib/opensolaris/uts/common/dtrace/fasttrap.c
/*
 * This is called from cfork() via dtrace_fasttrap_fork(). The child
 * process's address space is (roughly) a copy of the parent process's so
 * we have to remove all the instrumentation we had previously enabled in the
 * parent.
 */
This is called from cfork() via dtrace_fasttrap_fork(). The child
process's address space is (roughly) a copy of the parent process's so
we have to remove all the instrumentation we had previously enabled in the
parent.
This is called from cfork () via dtrace_fasttrap_fork () . The child process ' s address space is ( roughly ) a copy of the parent process ' s so we have to remove all the instrumentation we had previously enabled in the parent .
static void
fasttrap_fork(proc_t *p, proc_t *cp)
{
#ifndef illumos
	fasttrap_scrblock_t *scrblk;
	fasttrap_proc_t *fprc = NULL;
#endif
	pid_t ppid = p->p_pid;
	int i;
#ifdef illumos
	ASSERT(curproc == p);
	ASSERT(p->p_proc_flag & P_PR_LOCK);
#else
	PROC_LOCK_ASSERT(p, MA_OWNED);
#endif
#ifdef illumos
	ASSERT(p->p_dtrace_count > 0);
#else
	if (p->p_dtrace_helpers) {
		_PHOLD(cp);
		PROC_UNLOCK(p);
		PROC_UNLOCK(cp);
		dtrace_helpers_duplicate(p, cp);
		PROC_LOCK(cp);
		PROC_LOCK(p);
		_PRELE(cp);
	}
	if (p->p_dtrace_count == 0)
		return;
#endif
	ASSERT(cp->p_dtrace_count == 0);
#ifdef illumos
	mtx_lock_spin(&cp->p_slock);
	sprlock_proc(cp);
	mtx_unlock_spin(&cp->p_slock);
#else
	_PHOLD(cp);
	PROC_UNLOCK(cp);
	PROC_UNLOCK(p);
#endif
	for (i = 0; i < fasttrap_tpoints.fth_nent; i++) {
		fasttrap_tracepoint_t *tp;
		fasttrap_bucket_t *bucket = &fasttrap_tpoints.fth_table[i];
		mutex_enter(&bucket->ftb_mtx);
		for (tp = bucket->ftb_data; tp != NULL; tp = tp->ftt_next) {
			if (tp->ftt_pid == ppid &&
			    tp->ftt_proc->ftpc_acount != 0) {
				int ret = fasttrap_tracepoint_remove(cp, tp);
				ASSERT(ret == 0);
				ASSERT(tp->ftt_proc->ftpc_acount != 0);
#ifndef illumos
				fprc = tp->ftt_proc;
#endif
			}
		}
		mutex_exit(&bucket->ftb_mtx);
#ifndef illumos
		if (fprc != NULL) {
			mutex_enter(&fprc->ftpc_mtx);
			LIST_FOREACH(scrblk, &fprc->ftpc_scrblks, ftsb_next) {
				vm_map_remove(&cp->p_vmspace->vm_map,
				    scrblk->ftsb_addr,
				    scrblk->ftsb_addr + FASTTRAP_SCRBLOCK_SIZE);
			}
			mutex_exit(&fprc->ftpc_mtx);
		}
#endif
	}
#ifdef illumos
	mutex_enter(&cp->p_lock);
	sprunlock(cp);
#else
	PROC_LOCK(p);
	PROC_LOCK(cp);
	_PRELE(cp);
#endif
}
static void fasttrap_fork ( proc_t * p , proc_t * cp ) { #ifndef illumos fasttrap_scrblock_t * scrblk ; fasttrap_proc_t * fprc = NULL ; #endif pid_t ppid = p -> p_pid ; int i ; #ifdef illumos ASSERT ( curproc == p ) ; ASSERT ( p -> p_proc_flag & P_PR_LOCK ) ; #else PROC_LOCK_ASSERT ( p , MA_OWNED ) ; #endif #ifdef illumos ASSERT ( p -> p_dtrace_count > 0 ) ; #else if ( p -> p_dtrace_helpers ) { _PHOLD ( cp ) ; PROC_UNLOCK ( p ) ; PROC_UNLOCK ( cp ) ; dtrace_helpers_duplicate ( p , cp ) ; PROC_LOCK ( cp ) ; PROC_LOCK ( p ) ; _PRELE ( cp ) ; } if ( p -> p_dtrace_count == 0 ) return ; #endif ASSERT ( cp -> p_dtrace_count == 0 ) ; #ifdef illumos mtx_lock_spin ( & cp -> p_slock ) ; sprlock_proc ( cp ) ; mtx_unlock_spin ( & cp -> p_slock ) ; #else _PHOLD ( cp ) ; PROC_UNLOCK ( cp ) ; PROC_UNLOCK ( p ) ; #endif for ( i = 0 ; i < fasttrap_tpoints . fth_nent ; i ++ ) { fasttrap_tracepoint_t * tp ; fasttrap_bucket_t * bucket = & fasttrap_tpoints . fth_table [ i ] ; mutex_enter ( & bucket -> ftb_mtx ) ; for ( tp = bucket -> ftb_data ; tp != NULL ; tp = tp -> ftt_next ) { if ( tp -> ftt_pid == ppid && tp -> ftt_proc -> ftpc_acount != 0 ) { int ret = fasttrap_tracepoint_remove ( cp , tp ) ; ASSERT ( ret == 0 ) ; ASSERT ( tp -> ftt_proc -> ftpc_acount != 0 ) ; #ifndef illumos fprc = tp -> ftt_proc ; #endif } } mutex_exit ( & bucket -> ftb_mtx ) ; #ifndef illumos if ( fprc != NULL ) { mutex_enter ( & fprc -> ftpc_mtx ) ; LIST_FOREACH ( scrblk , & fprc -> ftpc_scrblks , ftsb_next ) { vm_map_remove ( & cp -> p_vmspace -> vm_map , scrblk -> ftsb_addr , scrblk -> ftsb_addr + FASTTRAP_SCRBLOCK_SIZE ) ; } mutex_exit ( & fprc -> ftpc_mtx ) ; } #endif } #ifdef illumos mutex_enter ( & cp -> p_lock ) ; sprunlock ( cp ) ; #else PROC_LOCK ( p ) ; PROC_LOCK ( cp ) ; _PRELE ( cp ) ; #endif }
This is called from cfork() via dtrace_fasttrap_fork().
This is called from cfork () via dtrace_fasttrap_fork () .
/*
		 * dtrace_helpers_duplicate() allocates memory.
		 */ /*
	 * This check is purposely here instead of in kern_fork.c because,
	 * for legal resons, we cannot include the dtrace_cddl.h header
	 * inside kern_fork.c and insert if-clause there.
	 */ /*
	 * This would be simpler and faster if we maintained per-process
	 * hash tables of enabled tracepoints. It could, however, potentially
	 * slow down execution of a tracepoint since we'd need to go
	 * through two levels of indirection. In the future, we should
	 * consider either maintaining per-process ancillary lists of
	 * enabled tracepoints or hanging a pointer to a per-process hash
	 * table of enabled tracepoints off the proc structure.
	 */ /*
	 * We don't have to worry about the child process disappearing
	 * because we're in fork().
	 */ /*
	 * fasttrap_tracepoint_remove() expects the child process to be
	 * unlocked and the VM then expects curproc to be unlocked.
	 */ /*
	 * Iterate over every tracepoint looking for ones that belong to the
	 * parent process, and remove each from the child process.
	 */ /*
				 * The count of active providers can only be
				 * decremented (i.e. to zero) during exec,
				 * exit, and removal of a meta provider so it
				 * should be impossible to drop the count
				 * mid-fork.
				 */ /*
		 * Unmap any scratch space inherited from the parent's address
		 * space.
		 */