On the road to Xen : LTTng and relay CPU hotplug support

Mathieu Desnoyers <[email protected]>
Newsgroups gmane.linux.kernel.tracing
Message-ID <20061116154809.GA9468@Krystal>
Hi,

In my current work of porting LTTng to the Xen hypervisor, I notice that their
project use the Linux CPU hotplug feature extensively in the domain-0 and
domain-Us. This brings me to a preliminary adaptation phase of the LTTng kernel
tracer : adding CPU hotplug support.

The basic idea is that we have (at least) to create a new buffer for every
channel when a CPU is "UP_PREPARE". In order to do that, Relay must be
modified so the buffer creation function is less coupled with the channel
creation and that this function is exported as part of the API.
(I just implemented this modification) We can also destroy the buffer when the
CPU goes down (see below).

Relay cannot, by itself, deal with the CPU hotplug events because it does not
have a list of the allocated channels. This is why I choose to put the hotplug
event handler inside LTTng. LTTng must also have proper synchronization between
each calls that results in a for_each_online_cpu and trace list modification
(this trace list is used in the CPU hotplug handler to iterate on each channel).

I will also have to add inotify support to lttd so it discovers the creation of
new channel buffer files.

However, there is a design choice that I have to do. Here is the dilemma : we
can either :

A - create new buffers when a new CPU appears and _not_ flush/destroy it when
  the CPU goes down.
  
  This choice imply that we have to iterate on each_possible_cpu and verify if
  the buffer is allocated when we do operations on the trace.
  It will also consume unnecessary memory in cases where a system starts
  tracing with many CPUs and later put some of them offline (very plausible
  in Xen).

B - create new buffers when a new CPU appears and flush/destroy it when a CPU
  goes down.

  This implies that we can iterate on each_online_cpu at any time, but it has
  some other implications :
  If we think of a scenario where the CPU goes up/down/up really fast on a
  machine while a trace is taken, it will result in the possible scenario where
  the buffer is unreferenced by LTTng, still referenced by the consumer (lttd)
  and the CPU coming up wants to recreate it (both the data structures and the
  debugfs file). Clearly, this operation should never fail. A solution around
  this would be to have to ability to "recycle" the buffers when they are
  referenced by the consumer, but not by the writer anymore. Care must be taken
  about things like the "finalized" flag, atomicity, whether lttd will drop the
  reference and must be inotified of the new file, ...
  
  Another problem is when a CPU would have a short life-time : going up/tracing
  a few events/going down. If the consumer (lttd) did not get the chance to
  receive the inotify and therefore cannot open the buffer file, the data will
  never be written to disk before the buffer is destroyed.

  It will also have a performance cost when a cpu is going up/down repeatedly.
  One thing we could do to make this performance hit less problematic is to do
  a lazy buffer removal : X seconds after the CPU is down, we destroy the
  buffer.


What I could do is to implement (A), keeping in mind that the proper way to do
it would be (B), the longer term target therefore being (B). In the mindset of
doing incremental changes that "works", I think (A) would be a good start.

Having your insight on this would be appreciated,

Thanks,

Mathieu


OpenPGP public key:              http://krystal.dyndns.org:8080/key/compudj.gpg
Key fingerprint:     8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.