On Thu, 16 Aug 2018 at 15:15, Mike Bazov mike@perception-point.io wrote:
Greetings,
When tracing via sysFS and keeping the default configuration, everything that is happening on a processor is logged. That is called "CPU-wide". Any process that get scheduled out of the processor won't be traced. On perf one can execute: # perf record -e cs_etm/@20070000.etr/ --per-thread my_application (example 1) # perf record -e cs_etm/@20070000.etr/ -C 2,3,4 my_application (example 2) For example 1, perf will switch on the tracer associated to the CPU where my_application has been installed for execution. If the process gets scheduled on a different CPU perf will do the right thing and follow it around. That is called "per-thread". In example 2 everything that is happening on CPU 2,3,4 will be traced for as long as my_application is executing, regardless of where my_application is executing. That is also a CPU-wide trace scenario.
I was more under the impression that CPU-wide records everything that the CPU executes (this is achieved by using sysfs like you described), regardless of the term "thread".
That is exactly that it does and "threads" are irrelevant in that context. The default configuration in sysFS is set to do CPU-wide but it is also possible to do "per-thread" if the configuration is changed from the command line. As far as perf is concerned, it was easier to do per-thread scenarios first. Once I am done with CPU-wide it will be possible to do both.
I don't really understand why CPU-wide is the right term for example 2. Both of the examples record "per-thread", except of the CPU mask. Example 1 doesn't mask any CPUs, where
In example 2 code for my_application will not be recorded if it is executed on CPU 1 or 2, but whatever happens on CPU 2, 3 and 4 will for as long as it is executing. In CPU-wide mode the application itself is not important, it is how long is executes for that is. As such you can replace "my_application" with "sleep 5" and the result will be the same.
example 2 masks all CPUs except 2, 3, 4, It still doesn't record "CPU-wide", only "per-thread", but on non-masked CPUs(if it weren't "per-thread", it wouldn't care about scheduling a thread and disable/enable accordingly). I'm a little confused, It really seems like sysfs==cpu-wide and perf==per-thread. Perhaps chagning the modes to "CS_MODE_PER_THREAD", "CS_MODE_CPU_WIDE" and make the sysfs and perf implementation use these modes is something that solves the puzzle for me.
That won't work. As explained above it is possible to do CPU-wide and per-thread from sysFS and (soon), the same from perf.
As such you will find places like that where things aren't exactly how
they should be - heck, I find them in my original code all the time. You should test it but once again I think you are correct - coresight_enable_source() should be called from etm_event_start().
After a second look, actually i think calling coresight_enable_source() will be problematic. Using the sysfs implementation(coresight.c) from perf is problematic, since it maintains a reference count per-device. If there's a sysfs session running on a tracer, and perf uses the __same__ path to the sink and the same source, using coresight_enable_path() will result in simply increasing the reference count without returning any errors..
And that is a problem that needs to be fixed.
So calling source_ops(source)->enable() directly actually will result in an error, which is the expected behavior(?)
Also, just out of curiosity, what happens when perf is requested to record a multithreaded process? the "per-thread" mechanism doesn't seem to fit here, because of the "single tracer to single-sink" rule.
Yes that is problematic. The issue should be handled when I am done with my current work that associates perf sessions with sinks. As such any event (or child event) that comes from the same session will be allowed to use the same sink.
Mathieu.