Export CONFIG_ options via #version/kconfig
[akaros.git] / Documentation / profiling.txt
index 91f6037..50af4cb 100644 (file)
 Akaros Profiling
 ===========================
 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/
-
-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.
-Aside from timer based sampling, the Akaros `perf` tool allows to sample by
-catching performance counter overflows.
-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:
-
-/ $ echo prof_qlimit SIZE_KB > /prof/kpctl
-
-This should be run before starting the profiler.
-
-It is possible to configure the timer period, which defaults to 1000us, though
-it is not suggested to move too far from the default:
-
-/ $ echo timer period 1000 > /prof/kpctl
-
-
-                    Timer Base Profiling
+===========================
+PERF
+===========================
+Akaros has limited support for perf_events.  perf is a tool which utilizes CPU
+performance counters for performance monitoring and troubleshooting.
 
 
-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.
+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.
 
 
-For profiling, besides the counters overflow sampling handled by the `perf`
-utility, you need to enable timers:
 
 
-/ $ echo timer all on > /prof/kpctl
+SETUP
+--------------------
+To build Akaros's perf directly:
 
 
-And then start the Akaros profiler system-wide.
+(linux)$ cd tools/dev-libs/elfutils ; make install; cd -
+(linux)$ cd tools/dev-util/perf ; make install; cd -
 
 
-/ $ echo start > /prof/kpctl
+Or to build it along with all apps:
 
 
-Run whatever command you want the sampling to be based on, then stop timers
-and profiler:
+(linux)$ make apps-install
 
 
-/ $ my_test_program ...
-/ $ echo timer all off > /prof/kpctl
-/ $ echo stop > /prof/kpctl
+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.
 
 
-The trace will be then available in the /prof/kpdata file.
-The data will be available until the next start of the profiler.
+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).
 
 
-                    Akaros Perf Tool
+Linux perf changes a lot.  Newer versions are usually nicer.  I recommend
+building one of them:  Download Linux source, then
 
 
-The Akaros `perf` is a tool which allows to both programming and reading
-the CPU performance counters, and enabling counter overflow interrupt based
-tracing.
-Its help screen reads like:
+(linux) $ cd tools/perf/
+(linux) $ make
 
 
-Use: perf {list,cpucaps,record} [-mkecxh] -- CMD [ARGS ...]
-        list            Lists all the available events and their meaning.
-        cpucaps         Shows the system CPU capabilities in term of performance counters.
-        record           Setups the configured counters, runs CMD, and shows the values of the counters.
-Options:
-        -m PATH          Sets the path of the PERF file ('#arch/perf').
-        -k PATH          Sets the path of the KPROF control file ('/prof/kpctl').
-        -e EVENT_SPEC    Adds an event to be tracked.
-        -c CPUS_STR      Selects the CPU set on which the counters should be active.
-        -x EVENT_RX      Sets the event name regular expression for list.
-        -h               Displays this help screen.
+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.
 
 
-To list the counters available for sampling, you can run the following command
-(note, it might be a very long output):
 
 
-/ $ perf list
+BASIC EXAMPLE
+--------------------
+Perf on Akaros supports record, stat, and a few custom options.
 
 
-Or, if you have some hint of what you are looking for (example, "FLUSH"), you
-can run:
+You should be able to do the following:
 
 
-/ $ perf list -x FLUSH
+/ $ perf record ls
 
 
-The -x parameter accepts regular expression syntax.
-To get information about how many counters, and their bit size, are available in
-the system, you can run:
+Then scp perf.data to Linux
 
 
-/ $ perf cpucaps
+(linux) $ scp AKAROS_MACHINE:perf.data .
+(linux) $ perf report --kallsyms=obj/kern/ksyms.map --symfs=kern/kfs/
 
 
-Which produces an output like:
+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.
 
 
-PERF.version             = 2
-PERF.proc_arch_events    = 7
-PERF.bits_x_counter      = 48
-PERF.counters_x_proc     = 4
-PERF.bits_x_fix_counter  = 48
-PERF.fix_counters_x_proc = 3
+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 need to specify the list of CPUs where the counters will be active, and the
-CMD passed as `perf` parameter will be run onto.
-The format of the CPUS_STR is as follow:
+(linux) $ ./scripts/perf report
 
 
-  [[!]{all,I[.J]+,N-M}][:...]
+The perf.data file is implied, so the above command is equivalent to:
 
 
-Where:
-  all    = Enable all CPUs
-  llall  = Enable all low latency CPUs
-  I.J.K  = Enable CPUs I, J, and K
-  N-M    = Enable CPUs from N to M, included
+(linux) $ ./scripts/perf report -i perf.data
 
 
-Examples:
-  0.2.4:8-19
-  all:!2.4.8
 
 
-Setting up an event, either for simple reading, or for sampling, requires
-providing the event coordinates (of which, the output emitted by the commands
-above, will help).
-The event coordinates come as event ID and event mask couple.
-They can either be specified by numeric values (example, 0xbd:0x20), or by
-their name (TLB_FLUSH:STLB_ANY).
-The format of the -e event specification is as follow:
+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.
 
 
-  {EVENT_ID:MASK,EVENT_NAME:MASK_NAME}[,os[={0,1}]][,usr[={0,1}]]
-    [,int[={0,1}]][,invcmsk[={0,1}]][,cmask=MASK][,icount=COUNT]
+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.
 
 
-With the following meaning:
+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:
 
 
-  os     = Should the counter tick when in ring 0 (default 1)
-  usr    = Should the counter tick when in ring 1,2,3 (default 1)
-  int    = Should counter overflow interrupt based sampling be enabled (default 0)
-  icount = After how many increments in the counter value, the sampling
-           interrupt should trigger (default 0 - not allowed if int==1)
+- Generic events (called "pre-defined" events on Linux)
+- Libpfm events
+- Raw events
 
 
-After the double hyphen (--), follow the command, and its arguments, to be
-executed while the sampling is happening.
-In most cases this could simply be a `sleep` (embedded perf command).
-Example:
+Linux's perf only takes Generic and Raw events, so the libpfm4 is an added
+bonus.
 
 
-/ $ perf record -e TLB_FLUSH:STLB_ANY,int=1,icount=20 -- sleep 10
+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.
 
 
-When the command run by `perf` exits, the configured counter values are shown.
-If used as counter overflow interrupt sampling, the tracing data will be in
-the usual /prof/kpdata file.
+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.
 
 
+To see the list of events available, use `perf list [regex]`, supplying an
+optional search regex.  For example, on a Haswell:
 
 
+/ $ 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)
 
 
-                    Analyzing Profiler Data
+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:
 
 
-The profiler tracing data generated in the /prof/kpdata file, needs to be copied
-on your dev box.
-The easiest way is via 9p:
+/ $ perf stat -e ix86arch::UNHALTED_REFERENCE_CYCLES ls
 
 
-/ $ cp /prof/kpdata /mnt/
+Here's how to specify multiple events:
 
 
-Or by using the simple netcat (snc) utility.
-On your dev box:
+/ $ perf record -e cycles,instructions ls
 
 
-/ $ nc -l PORT > kpdata.data
+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 ':'.
 
 
-On Akaros:
+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.
 
 
-/ $ scn -s DEVBOX_IP -p PORT -i /prof/kpdata
 
 
-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:
+===========================
+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