tracepoints: make tracepoint_counter generally useful

tracepoint_counter is a useful class which allows counting the number
of times that a particular tracepoint occured, *without* enabling
the tracepoint and post-processing the tracepoint log.

tracepoint_counter works by setting up the tracepoint to, every time it
is reached, increment a per-cpu counter (without logging the tracepoint).
This process is very efficient, and incurs only a small performance
overhead - even for tracepoints reached millions of times a second
(where logging the events and post-processing them would be totally
unrealistic).

Previously, tracepoint_counter lived in the tracepoint.cc, a JNI library
which we used to implement the "perf stat" command in the Java-based
shell. This patch extracts this class to a new header file,
<osv/trace-count.hh>, where we can use it not just for Java code.
In the next patch, we intend to use the same class to provide
tracepoint counting also for the REST API.

Signed-off-by: Nadav Har'El <nyh@cloudius-systems.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
httpserver: add operations for counting tracepoints

This patch adds to httpserver's REST API the ability to efficiently count
the number of times that a particular tracepoint is reached, by using the
tracepoint_counter OSv feature provided by the previous patch.
In the next patch we will use this REST API to provide a "freq.py"
script which can efficiently display the frequency of various tracepoints,
from outside the guest.

This patch adds three operations:

/trace/count/<tracepoint-name> (POST): enable or disable the counting of
a particular tracepoint. When counting of a tracepoint is enabled, each
time this tracepoint is reached a counter is efficiently (per-cpu)
incremented. This counting continues indefinitely until the counting of
this tracepoint is later disabled. Disabling and later renabling a
counter starts again with the zero count. Similarly, enabling an already-
enabled counter also zeros the counter.

/trace/count (DELETE): a shortcut for disabling all enabled counter.

/trace/count (GET): retrieve the counts for all enabled tracepoint counters.

Signed-off-by: Nadav Har'El <nyh@cloudius-systems.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
add "freq.py" tool to show tracepoint frequency in a running OSv guest

This patch adds a tool "freq.py" which can be used from outside the OSv
guest to find the frequency of *any* tracepoint. This is done efficiently
(see tracepoint_counter) and does not involve fully enabling (logging)
this tracepoint. It can even be used for tracepoints which occur
millions a time each second.

Freq.py takes the guest's address:port (the port defaults to 8000), and
a list of tracepoints whose frequency to display. To just see the whole
list of tracepoints to choose from, run freq.py Without parameters
(except the host). The frequency of each selected tracepoint (number of
occurances per second) is averaged over 2-second periods and displayed
every 2 seconds.

Here is an example of the output for three tracepoints on a guest
running memcached, before and after "memaslap" started exercising it:

$ scripts/freq.py 192.168.122.89 sched_switch mutex_lock memory_malloc
Showing number of events per second. Refreshing every 2 seconds
   sched_switch     mutex_lock  memory_malloc
           2650           4057            265
           2274           1298            163
           2033           1665            175
           3447           6344            343
          52782         805701         227800  <--- memaslap started here
          78631        1068659         304723
          84144        1060092         301155

To reiterate, you *do not* need to enable tracepoints in the traditional
sense (e.g., the "--trace ..." paramters to run.py) for this to work,
and you can ask freq.py to count *any* existing tracepoint.
The counted tracepoints are only counted - not logged to the trace log
(of course, you can do both if you wish).

One caveat on this implementation:

By design, the REST API is session-less. When freq.py enables a counter,
the kernel will never stop counting it - until freq.py asks it to stop
counting. We were careful about stopping all counters when freq.py exits
(even if it is killed by a signal), but this can still happen - e.g., if
the host running freq.py dies. Moreover, freq.py is currently not designed
to support two freq.py runs on the same OSv guest concurrently. As the
code is written now, the second concurrent freq.py invocation will cancel
all the counters requested by the first invocation, and confuse it.
This situation can be fixed, but not easily (will involve some sort of
reference counting?) but I'll leave it to a follow-up patch. I think
this patch is already quite useful as-is.

Signed-off-by: Nadav Har'El <nyh@cloudius-systems.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>