capability device: get it to compile
[akaros.git] / Documentation / profiling.txt
index 92f1171..50af4cb 100644 (file)
 Akaros Profiling
 ===========================
-2015-07-15 Barret Rhoden (brho)
 
-Contents
----------------------------
-"Kprof"
+Contents:
 
-"Kprof"
----------------------------
-Akaros has a very basic sampling profiler, similar to oprofile.  The kernel
-generates traces, which you copy off the machine and process on Linux using
-Linux perf.
-First build the Akaros kernel:
+ (*) Perf
+     - Setup
+     - Example
+     - More Complicated Examples
+     - Differences From Linux
 
-/ $ make && make xcc-headers-install && make apps-install
+ (*) mpstat
 
-To get started, make sure #K is mounted.  The basic ifconfig script will do
-this, as will:
 
-/ $ bind -a \#K /prof/
+===========================
+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:
 
-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.
+(linux) $ ./scripts/perf report
 
-The timer 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 profiler accepts a few configuration options.
-There is a queue size limit of 64MB by default, and it is used as circular
-buffer, so old data will be dropped.
-To change its value:
+The perf.data file is implied, so the above command is equivalent to:
 
-/ $ echo prof_qlimit SIZE_KB > /prof/kpctl
+(linux) $ ./scripts/perf report -i perf.data
 
-This should be run before starting the profiler.
-There is a limit of the maximum call strace dept, by default 16.
-To change it:
 
-/ $ echo prof_btdepth DEPTH > /prof/kpctl
+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.
 
-This should be run before starting the profiler as well.
-It is possible to configure the timer period, which defaults to 1000us, though
-it is not suggested to move too far from the default:
+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.
 
-/ $ echo timer period 1000 > /prof/kpctl
+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:
 
-And then start the Akaros profiler system-wide.
+- Generic events (called "pre-defined" events on Linux)
+- Libpfm events
+- Raw events
 
-/ $ echo start > /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
+Linux's perf only takes Generic and Raw events, so the libpfm4 is an added
+bonus.
 
-Run whatever command you want, then stop the profiler.
+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.
 
-/ $ foo
-/ $ echo stop > /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.
 
-The trace will be then available in the /prof/kpdata file.
-The data will be available until the next start of the profiler.
-Then copy this on your dev box.
-The easiest way is via 9p:
+To see the list of events available, use `perf list [regex]`, supplying an
+optional search regex.  For example, on a Haswell:
 
-/ $ cp /prof/kpdata /mnt/
+/ $ 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)
 
-Or by using the simple netcat (snc) utility.
-On your dev box:
+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:
 
-/ $ nc -l PORT > kpdata.data
+/ $ perf stat -e ix86arch::UNHALTED_REFERENCE_CYCLES ls
 
-On Akaros:
+Here's how to specify multiple events:
 
-/ $ scn -s DEVBOX_IP -p PORT -i /prof/kpdata
+/ $ perf record -e cycles,instructions ls
 
-In order to process the Akaros kprof file, you need to convert it to the
-Linux perf one.
-You can do that, on your dev box, with:
+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.
 
-/ $ ./tools/profile/kprof2perf/kprof2perf-linux -k `pwd`/obj/kern/akaros-kernel-64b -i kpdata.data -o perf.data
+For starters, bind kprof somewhere.  The basic ifconfig script binds it to
+/prof.
 
-You then need to build the Akaros specific Linux perf binary.
-First you need to install (if you have not already) libelf-dev:
+To see the CPU usage, cat mpstat:
 
-\ $ sudo apt-get install libelf-dev
+/ $ cat /prof/mpstat
+ CPU:             irq             kern              user                 idle
+   0: 1.707136 (  0%), 24.978659 (  0%), 0.162845 (  0%), 13856.233909 ( 99%)
 
-Then pull the Linux kernel source code which is closer to the kernel
-version you are running in your dev box, and patch it:
+To reset the count:
 
-/ $ cd linux
-/ $ patch -p 1 < $AKAROS/tools/profile/kprof2perf/perf_patches/perf_patch.diff
-/ $ cd tools/perf
-/ $ make
+/ $ echo reset > /prof/mpstat
 
-Then you should be able to run Linux perf data analysis command on it:
-Example:
+To see the output for a particular command:
 
-$ /PATH_TO/perf --root-dir $AKAROS/kern/kfs/ report -g -i perf.data
+/ $ echo reset > /prof/mpstat ; COMMAND ; cat /prof/mpstat