Export CONFIG_ options via #version/kconfig
[akaros.git] / Documentation / profiling.txt
index 0216597..50af4cb 100644 (file)
 Akaros Profiling
 ===========================
 Akaros Profiling
 ===========================
-2015-07-15 Barret Rhoden (brho)
 
 
-Contents
----------------------------
-"Oprofile"
+Contents:
 
 
-"Oprofile"
----------------------------
-Akaros has a very basic sampling profiler, similar to oprofile.  The kernel
-generates traces, which you copy off the machine and process on Linux.
+ (*) Perf
+     - Setup
+     - Example
+     - More Complicated Examples
+     - Differences From Linux
 
 
-To get started, make sure #K is mounted.  The basic ifconfig script will do
-this, as will:
+ (*) mpstat
 
 
-/ $ bind -a \#K /prof/
 
 
-You control the profiler with the kpctl file.  The general style is to start
-the events that trigger a sample, such as a timer tick, then you start and stop
-the profiling.  The distinction between the two steps is that one actually
-fires the events (e.g. the timer IRQ), and the other enables *collection* of profiling info when those events occur.
+===========================
+PERF
+===========================
+Akaros has limited support for perf_events.  perf is a tool which utilizes CPU
+performance counters for performance monitoring and troubleshooting.
+
+Akaros has its own version of perf, similar in spirit to Linux's perf, that
+produces PERFILE2 ABI compliant perf.data files (if not, file a bug!).  The
+kernel generates traces, under the direction of perf.  You then copy the traces
+to a Linux host and process using Linux's perf.
+
+
+SETUP
+--------------------
+To build Akaros's perf directly:
+
+(linux)$ cd tools/dev-libs/elfutils ; make install; cd -
+(linux)$ cd tools/dev-util/perf ; make install; cd -
+
+Or to build it along with all apps:
+
+(linux)$ make apps-install
+
+You will also need suitable recent Linux perf for the reporting of the data
+(something that understands PERFILE2 format).  Unpatched Linux 4.5 perf did the
+trick.  You'll also want libelf and maybe other libraries on your Linux
+machine.
+
+First, install libelf according to your distro.  On ubuntu:
+(linux) $ sudo apt-get install libelf-dev
+
+Then try to just install perf using your Linux distro, and install any needed
+dependencies.  On ubuntu, you can install linux-tools-common and whatever else
+it asks for (something particular to your host kernel).
+
+Linux perf changes a lot.  Newer versions are usually nicer.  I recommend
+building one of them:  Download Linux source, then
+
+(linux) $ cd tools/perf/
+(linux) $ make
+
+Then use your new perf binary.  This all is just installing a recent perf - it
+has little to do with Akaros at this point.  If you run into incompatibilities
+between our perf.data format and the latest Linux, file a bug.
+
+
+BASIC EXAMPLE
+--------------------
+Perf on Akaros supports record, stat, and a few custom options.
+
+You should be able to do the following:
+
+/ $ perf record ls
+
+Then scp perf.data to Linux
+
+(linux) $ scp AKAROS_MACHINE:perf.data .
+(linux) $ perf report --kallsyms=obj/kern/ksyms.map --symfs=kern/kfs/
+
+Perf will look on your host machine for the kernel symbol table and for
+binaries.  We need to tell it kallsyms and symfs to override those settings.
+
+It can be a hassle to type out the kallsyms and symfs, so we have a script that
+will automate that.  Use scripts/perf in any place that you'd normally use
+perf.  Set your $AKAROS_ROOT (default is ".") and optionally override $PERF_CMD
+("default is "perf").  For most people, this will just be:
+
+(linux) $ ./scripts/perf report
 
 
-The optimer command takes the core id (or "all"), followed by "on" or "off".
-As with all good devices, if you echo garbage, in, you should get the usage as
-an errstr.  That'll be kept up to date more than documentation.
+The perf.data file is implied, so the above command is equivalent to:
 
 
-/ $ echo garbage > /prof/kpctl
-echo failed: Unspecified, startclr|start|stop|clear|opstart|opstop|optimer
+(linux) $ ./scripts/perf report -i perf.data
 
 
-/ $ echo optimer garbage > /prof/kpctl
-echo failed: Unspecified, optimer [<0|1|..|n|all> <on|off>] [period USEC]
 
 
-Let's set up the timer on core 0:
+MORE COMPLICATED EXAMPLES
+--------------------
+First, try perf --help for usage.  Then check out
+https://perf.wiki.kernel.org/index.php/Tutorial.  We strive to be mostly
+compatible with the usage of Linux perf.
 
 
-/ $ echo optimer 0 on > /prof/kpctl
+perf stat runs a command and reports the count of events during the run of the
+command.  perf record runs a command and outputs perf.data, which contains
+backtrace samples from when the event counters overflowed.  For those familiar
+with other perfmon systems, perf stat is like PAPI and perf record is like
+Oprofile.
 
 
-And then start oprofile system-wide.
+perf record and stat both track a set of events with the -e flag.  -e takes a
+comma-separated list of events.  Events can be expressed in one of three forms:
 
 
-/ $ echo opstart > /prof/kpctl
-Enable tracing on 0
-Enable tracing on 1
-Enable tracing on 2
-Enable tracing on 3
-Enable tracing on 4
-Enable tracing on 5
-Enable tracing on 6
-Enable tracing on 7
+- Generic events (called "pre-defined" events on Linux)
+- Libpfm events
+- Raw events
 
 
-Run whatever command you want, then stop the profiler.
+Linux's perf only takes Generic and Raw events, so the libpfm4 is an added
+bonus.
 
 
-/ $ foo
-/ $ echo opstop > /prof/kpctl
-Core 0 has data
-After qibwrite in oprofile_cpubuf_flushone, opq len 303080
+Generic events consist of strings like "cycles" or "cache-misses".  Raw events
+aresimple strings of the form "rXXX", where the X's are hex nibbles.  The hex
+codes are passed directly to the PMU.  You can actually have 2-4 Xs on Akaros.
 
 
-Might as well turn off the timers:
-/ $ echo optimer all off > /prof/kpctl
+Libpfm events are strings that correspond to events specific to your machine.
+Libpfm knows about PMU events for a given machine.  It figures out what machine
+perf is running on and selects events that should be available.  Check out
+http://perfmon2.sourceforge.net/ for more info.
 
 
-Now we need to extract the trace.  The easiest way is via 9p.
-/ $ cat /prof/kpoprofile > trace
-/ $ cp trace /mnt/
+To see the list of events available, use `perf list [regex]`, supplying an
+optional search regex.  For example, on a Haswell:
 
 
-Once the trace has been read from kpoprofile, it cannot be read again.  The
-read drains the kernel's trace buffer.
+/ $ perf list unhalted_reference_cycles
+#-----------------------------
+IDX      : 37748738
+PMU name : ix86arch (Intel X86 architectural PMU)
+Name     : UNHALTED_REFERENCE_CYCLES
+Equiv    : None
+Flags    : None
+Desc     : count reference clock cycles while the clock signal on the specific core is running. The reference clock operates at a fixed frequency, irrespective of c
+ore frequency changes due to performance state transitions
+Code     : 0x13c
+Modif-00 : 0x00 : PMU : [k] : monitor at priv level 0 (boolean)
+Modif-01 : 0x01 : PMU : [u] : monitor at priv level 1, 2, 3 (boolean)
+Modif-02 : 0x02 : PMU : [e] : edge level (may require counter-mask >= 1) (boolean)
+Modif-03 : 0x03 : PMU : [i] : invert (boolean)
+Modif-04 : 0x04 : PMU : [c] : counter-mask in range [0-255] (integer)
+Modif-05 : 0x05 : PMU : [t] : measure any thread (boolean)
+#-----------------------------
+IDX      : 322961409
+PMU name : hsw_ep (Intel Haswell EP)
+Name     : UNHALTED_REFERENCE_CYCLES
+Equiv    : None
+Flags    : None
+Desc     : Unhalted reference cycles
+Code     : 0x300
+Modif-00 : 0x00 : PMU : [k] : monitor at priv level 0 (boolean)
+Modif-01 : 0x01 : PMU : [u] : monitor at priv level 1, 2, 3 (boolean)
+Modif-02 : 0x05 : PMU : [t] : measure any thread (boolean)
 
 
-The trace that the kernel generates is in an Akaros-specific format.  There is
-a go program at tools/profile/op2.go that translates from the Akaros format to
-pprof format.  You could run this on Akaros, since we support Go programs, but
-since we don't have a port of pprof, it's easier to do it all in Linux.
+There are two different events for UNHALTED_REFERENCE_CYCLES (case
+insensitive).  libpfm will select the most appropriate one.  You can override
+this selection by specifying a PMU:
 
 
-So now we're in linux, and say our 9p ufs server is rooted at mnt/netroot/.  Run op2:
+/ $ perf stat -e ix86arch::UNHALTED_REFERENCE_CYCLES ls
 
 
-(linux) $ op2 < mnt/netroot/trace > trace-pp
+Here's how to specify multiple events:
+
+/ $ perf record -e cycles,instructions ls
+
+Events also take a set of modifiers.  For instance, you can specify running
+counters only in kernel mode or user mode.  Modifiers are separated by a ':'.
+
+This will track only user cycles (default is user and kernel):
+
+/ $ perf record -e cycles:u ls
+
+To use a raw event, you need to know the event number.  You can either look in
+your favorite copy of the SDM, or you can ask libpfm.  Though if you ask
+libpfm, you might as well just use its string processing.  For example:
+
+/ $ perf list FLUSH
+#-----------------------------
+IDX      : 322961462
+PMU name : hsw_ep (Intel Haswell EP)
+Name     : TLB_FLUSH
+Equiv    : None
+Flags    : None
+Desc     : TLB flushes
+Code     : 0xbd
+Umask-00 : 0x01 : PMU : [DTLB_THREAD] : None : Count number of DTLB flushes of thread-specific entries
+Umask-01 : 0x20 : PMU : [STLB_ANY] : None : Count number of any STLB flushes
+Modif-00 : 0x00 : PMU : [k] : monitor at priv level 0 (boolean)
+Modif-01 : 0x01 : PMU : [u] : monitor at priv level 1, 2, 3 (boolean)
+Modif-02 : 0x02 : PMU : [e] : edge level (may require counter-mask >= 1) (boolean)
+Modif-03 : 0x03 : PMU : [i] : invert (boolean)
+Modif-04 : 0x04 : PMU : [c] : counter-mask in range [0-255] (integer)
+Modif-05 : 0x05 : PMU : [t] : measure any thread (boolean)
+Modif-06 : 0x07 : PMU : [intx] : monitor only inside transactional memory region (boolean)
+Modif-07 : 0x08 : PMU : [intxcp] : do not count occurrences inside aborted transactional memory region (boolean)
+
+The raw code is 0xbd.  So the following are equivalent (but slightly buggy!):
+
+/ $ perf stat -e TLB_FLUSH ls
+/ $ perf stat -e rbd ls
+
+If you actually run those, rbd will have zero hits, and TLB_FLUSH will give you
+the error "Failed to parse event string TLB_FLUSH".
+
+Some events actually rather particular to their Umasks, and TLB_FLUSH is one of
+them.  TLB_FLUSH wants a Umask.  Umasks are selectors for specific sub-types of
+events.  In the case of TLB_FLUSH, we can choose between DTLB_THREAD and
+STLB_ANY.  Umasks are not always required - they just happen to be on my
+Haswell for TLB_FLUSH.  That being said, we can ask for the event like so:
+
+/ $ perf stat -e TLB_FLUSH:STLB_ANY ls
+/ $ perf stat -e r20bd ls
+
+Note that the Umask is placed before the Code.  These 16 bits are passed
+directly to the PMU, and on Intel the format is "umask:event".
+
+perf record is based on recording samples when event counters overflow.  The
+number of events required to trigger a sample is referred to as the
+sample_period.  You can set it with -c, e.g.
+
+/ $ perf record -c 10000 ls
+
+
+DIFFERENCES FROM LINUX
+--------------------
+For the most part, Akaros perf is similar to Linux.  A few things are
+different.
+
+The biggest difference is that our perf does not follow processes around.  We
+count events for cores, not processes.  You can specify certain cores, but not
+certain processes.  Any options related to tracking specific processes are
+unsupported.
+
+The -F option (frequency) is loosely supported.  The kernel cannot adjust the
+sampling count dynamically to meet a certain frequencey.  Instead, we guess
+that -F is used with cycles, and pick a sample period that will generate
+samples at the desired frequency if the core is unhalted.  YMMV.
+
+Akaros currently supports only PMU events.  In the future, we may add events
+like context-switches.
+
+
+===========================
+mpstat
+===========================
+Akaros has basic support for mpstat.  mpstat gives a high-level glance at where
+each core is spending its time.
 
 
-To get a sense for what the trace holds, you might want to start with looking at the raw addresses to distinguish between the kernel and the user.
+For starters, bind kprof somewhere.  The basic ifconfig script binds it to
+/prof.
 
 
-(linux) $ pprof --addresses trace-pp
-PPROF> top
-       (shows some addresses)
+To see the CPU usage, cat mpstat:
 
 
-Say the majority of the addresses are user addresses:
+/ $ cat /prof/mpstat
+ CPU:             irq             kern              user                 idle
+   0: 1.707136 (  0%), 24.978659 (  0%), 0.162845 (  0%), 13856.233909 ( 99%)
 
 
-(linux) $ pprof obj/tests/foo trace-pp
-PPROF> top
-       (shows some functions)
+To reset the count:
 
 
-Or you can visualize things:
-(linux) $ pprof --evince obj/tests/foo trace-pp
+/ $ echo reset > /prof/mpstat
 
 
-The visualization is not of much user for user programs, since the kernel does
-not record backtraces for userspace by default.  It's a little dangerous at the
-moment.  In the future, we may have an op option to control whether or not the
-kernel attempts a backtrace.
+To see the output for a particular command:
 
 
-For more info on pprof, check out:
-http://gperftools.googlecode.com/svn/trunk/doc/cpuprofile.html
+/ $ echo reset > /prof/mpstat ; COMMAND ; cat /prof/mpstat