If a counter more than overflows just as we read it on switch out then,
if using sampling mode, we will negate this small value to give a huge
reload count, and if we later switch back in that context we will
validate that value against pm_reloadcount and panic an INVARIANTS
kernel with:
panic: [pmc,1470] pmcval outside of expected range cpu=2 ri=16 pmcval=fffff292 pm_reloadcount=10000
or similar. Presumably in a non-INVARIANTS kernel we will instead just
use the provided value as the reload count, which would lead to the
overflow not happing for a very long time (e.g. 78 minutes for a 48-bit
counter incrementing at an averate rate of 1GHz).
Instead, clamp the reload count to 0 (which corresponds precisely to the
value we would compute if it had just overflowed and no more), which
will result in hwpmc using the full original reload count again. This is
the approach used by core for Intel (for both fixed and programmable
counters).
Whilst here,As part of this, armv7 and arm64 are made conceptually simpler; fix broken calculations in mips's sampling mode support.rather
Negating a valuethan skipping mod 2^N is done with 2^N - x, not with x - 2^(N-1),ifying the overflow count for sampling mode counters so
nor with 2^(N-1) - x, both of which were in use. Howeverit's always kept as ~0, we also needthose special cases are removed so it's always
to be careful about UB, since ps_counter_width can be 64 in the case ofapplicable and the concatentation of it and the hardware counter can
Octeonalways be viewed as a 64-bit counter, so use a sign-extending approach like amd instead and then do awhich also makes them look more
full 64-bit negation on read, and explicitly truncate on write as I
don't know if we can rely on it being implicitly truncated when written
to the registers like amdlike other architectures.
MFC after: 1 weekWhilst here, fix an instance of UB (shifting a 1 into the sign bit) for
amd in its sign-extension code.