svn commit: r319913 - head/sys/dev/hwpmc

Andrew Turner andrew at fubar.geek.nz
Tue Jun 13 23:32:23 UTC 2017


> On 13 Jun 2017, at 19:53, Zbigniew Bodek <zbb at freebsd.org> wrote:
> 
> Author: zbb
> Date: Tue Jun 13 18:53:56 2017
> New Revision: 319913
> URL: https://svnweb.freebsd.org/changeset/base/319913
> 
> Log:
>  Fix INVARIANTS debug code in HWPMC
> 
>  When HWPMC stops sampling, ps_pmc may be freed before samples
>  are processed. In such situation treat PMC as stopped.

What is the sequence leading up to this?

...
> Modified: head/sys/dev/hwpmc/hwpmc_mod.c
> ==============================================================================
> --- head/sys/dev/hwpmc/hwpmc_mod.c	Tue Jun 13 18:52:39 2017	(r319912)
> +++ head/sys/dev/hwpmc/hwpmc_mod.c	Tue Jun 13 18:53:56 2017	(r319913)
> @@ -4224,7 +4224,8 @@ pmc_capture_user_callchain(int cpu, int ring, struct t
> 	ps_end = psb->ps_write;
> 	do {
> #ifdef	INVARIANTS
> -		if (ps->ps_pmc->pm_state != PMC_STATE_RUNNING)
> +		if ((ps->ps_pmc == NULL) ||
> +		    (ps->ps_pmc->pm_state != PMC_STATE_RUNNING))

Isn’t this just moving the NULL pointer dereference later in the function? I’m interested in knowing how the NULL pointer got into this function.

> 			nfree++;
> #endif
> 		if (ps->ps_nsamples != PMC_SAMPLE_INUSE)
> @@ -4262,9 +4263,11 @@ next:
> 			ps = psb->ps_samples;
> 	} while (ps != ps_end);
> 
> +#ifdef	INVARIANTS
> 	KASSERT(ncallchains > 0 || nfree > 0,
> 	    ("[pmc,%d] cpu %d didn't find a sample to collect", __LINE__,
> 		cpu));
> +#endif

Why is this needed? KASSERT is a top when INVARIANTS is undefined.

Andrew



More information about the svn-src-head mailing list