FreeBSD/sys/dev/hwpmc/hwpmc_mod.c
/*
 * Attach a process and optionally its children
 */
Attach a process and optionally its children
Attach a process and optionally its children
static int
pmc_attach_process(struct proc *p, struct pmc *pm)
{
	int error;
	struct proc *top;
	sx_assert(&pmc_sx, SX_XLOCKED);
	PMCDBG5(PRC,ATT,1, "attach pm=%p ri=%d proc=%p (%d, %s)", pm,
	    PMC_TO_ROWINDEX(pm), p, p->p_pid, p->p_comm);
	if ((pm->pm_flags & PMC_PP_ENABLE_MSR_ACCESS) != 0)
		return EPERM;
	if ((pm->pm_flags & PMC_F_DESCENDANTS) == 0)
		return pmc_attach_one_process(p, pm);
	sx_slock(&proctree_lock);
	top = p;
	for (;;) {
		if ((error = pmc_attach_one_process(p, pm)) != 0)
			break;
		if (!LIST_EMPTY(&p->p_children))
			p = LIST_FIRST(&p->p_children);
		else for (;;) {
			if (p == top)
				goto done;
			if (LIST_NEXT(p, p_sibling)) {
				p = LIST_NEXT(p, p_sibling);
				break;
			}
			p = p->p_pptr;
		}
	}
	if (error)
		(void) pmc_detach_process(top, pm);
 done:
	sx_sunlock(&proctree_lock);
	return error;
}
static int pmc_attach_process ( struct proc * p , struct pmc * pm ) { int error ; struct proc * top ; sx_assert ( & pmc_sx , SX_XLOCKED ) ; PMCDBG5 ( PRC , ATT , 1 , " " , pm , PMC_TO_ROWINDEX ( pm ) , p , p -> p_pid , p -> p_comm ) ; if ( ( pm -> pm_flags & PMC_PP_ENABLE_MSR_ACCESS ) != 0 ) return EPERM ; if ( ( pm -> pm_flags & PMC_F_DESCENDANTS ) == 0 ) return pmc_attach_one_process ( p , pm ) ; sx_slock ( & proctree_lock ) ; top = p ; for ( ; ; ) { if ( ( error = pmc_attach_one_process ( p , pm ) ) != 0 ) break ; if ( ! LIST_EMPTY ( & p -> p_children ) ) p = LIST_FIRST ( & p -> p_children ) ; else for ( ; ; ) { if ( p == top ) goto done ; if ( LIST_NEXT ( p , p_sibling ) ) { p = LIST_NEXT ( p , p_sibling ) ; break ; } p = p -> p_pptr ; } } if ( error ) ( void ) pmc_detach_process ( top , pm ) ; done : sx_sunlock ( & proctree_lock ) ; return error ; }
Attach a process and optionally its children
Attach a process and optionally its children
/*
	 * If this PMC successfully allowed a GETMSR operation
	 * in the past, disallow further ATTACHes.
	 */ /*
	 * Traverse all child processes, attaching them to
	 * this PMC.
	 */