acln0/perf

Other things from `perf list`, e.g. hw_interrupts.received

Closed this issue · 5 comments

I'd like to record hw_interrupts.received:

perf stat -v -e hw_interrupts.received bash -c 'for i in {1..10000}; do echo hi; done > /dev/null'
Using CPUID GenuineIntel-6-9E
hw_interrupts.received -> cpu/umask=0x1,period=100003,event=0xcb/
hw_interrupts.received: 3 13527404 13527404

 Performance counter stats for 'bash -c for i in {1..10000}; do echo hi; done > /dev/null':

                 3      hw_interrupts.received  

I can't yet figure out how to do it, but I'll update the thread if I do figure out how to.

I'd be interested in seeing that the perf API does eventually cover this and other events given by perf list in an intuitive way.

acln0 commented

I'm a little hazy on the event types / categories and how to query them from sysfs. Does https://godoc.org/acln.ro/perf#LookupEventType give something for "hw_interrupts"? For dynamic selection of tracepoints, we have https://godoc.org/acln.ro/perf#LookupTracepointConfig, but maybe there is a more general interface to be found here.

If it's just looking in /sys/bus/event_source/devices, there is not a hw_interrupts in that directory.

Found it, it's defined here:
https://github.com/torvalds/linux/blob/3bfe1fc46794631366faa3ef075e1b0ff7ba120a/tools/perf/pmu-events/arch/x86/skylake/other.json#L43

Found it by doing perf list -v pmu and then searching for the description, because it only appears as HW_INTERRUPTS and I was grepping for only the lower case. 🤦‍♂️

Reading around a bit I think I want a PERF_EVENT_COUNT_RAW:

              If type is PERF_TYPE_RAW, then a custom "raw" config value is needed.  Most CPUs support events that are not covered by the "generalized" events.  These are implementation
              defined; see your CPU manual (for example the Intel Volume 3B documentation or the AMD BIOS and Kernel Developer Guide).  The libpfm4 library can be used to translate from
              the name in the architectural manuals to the raw hex value perf_event_open() expects in this field.

I was able to get this event by doing the following:

	hwInt := includeKernel(&perf.Attr{
		Label:  "hw_interrupts.received",
		Type:   perf.RawEvent,
		Config: 0x1CB,
	})
func includeKernel(c perf.Configurator) perf.Configurator {
	tpattr := new(perf.Attr)
	c.Configure(tpattr)
	tpattr.Options.ExcludeKernel = false
	return tpattr
}

I figured this out with strace -f -eperf_event_open. I figure that 0x1CB is <UMask><EventCode> from other.json linked above (and also appearing in the perf -v output, in the body of this issue.

I'm going to call this issue closed. We could potentially open up a new issue to come up with a friendlier API for doing this, perhaps, but I'm unsure of the value of that at the moment.