| 1 | |
| 2 |
|
| 3 | ===============
|
| 4 | Tracing Remotes
|
| 5 | ===============
|
| 6 |
|
| 7 | :Author: Vincent Donnefort <[email protected]>
|
| 8 |
|
| 9 | Overview
|
| 10 | ========
|
| 11 | Firmware and hypervisors are black boxes to the kernel. Having a way to see what
|
| 12 | they are doing can be useful to debug both. This is where remote tracing buffers
|
| 13 | come in. A remote tracing buffer is a ring buffer executed by the firmware or
|
| 14 | hypervisor into memory that is memory mapped to the host kernel. This is similar
|
| 15 | to how user space memory maps the kernel ring buffer but in this case the kernel
|
| 16 | is acting like user space and the firmware or hypervisor is the "kernel" side.
|
| 17 | With a trace remote ring buffer, the firmware and hypervisor can record events
|
| 18 | for which the host kernel can see and expose to user space.
|
| 19 |
|
| 20 | Register a remote
|
| 21 | =================
|
| 22 | A remote must provide a set of callbacks `struct trace_remote_callbacks` whom
|
| 23 | description can be found below. Those callbacks allows Tracefs to enable and
|
| 24 | disable tracing and events, to load and unload a tracing buffer (a set of
|
| 25 | ring-buffers) and to swap a reader page with the head page, which enables
|
| 26 | consuming reading.
|
| 27 |
|
| 28 | .. kernel-doc:: include/linux/trace_remote.h
|
| 29 |
|
| 30 | Once registered, an instance will appear for this remote in the Tracefs
|
| 31 | directory **remotes/**. Buffers can then be read using the usual Tracefs files
|
| 32 | **trace_pipe** and **trace**.
|
| 33 |
|
| 34 | Declare a remote event
|
| 35 | ======================
|
| 36 | Macros are provided to ease the declaration of remote events, in a similar
|
| 37 | fashion to in-kernel events. A declaration must provide an ID, a description of
|
| 38 | the event arguments and how to print the event:
|
| 39 |
|
| 40 | .. code-block:: c
|
| 41 |
|
| 42 | REMOTE_EVENT(foo, EVENT_FOO_ID,
|
| 43 | RE_STRUCT(
|
| 44 | re_field(u64, bar)
|
| 45 | ),
|
| 46 | RE_PRINTK("bar=%lld", __entry->bar)
|
| 47 | );
|
| 48 |
|
| 49 | Then those events must be declared in a C file with the following:
|
| 50 |
|
| 51 | .. code-block:: c
|
| 52 |
|
| 53 | #define REMOTE_EVENT_INCLUDE_FILE foo_events.h
|
| 54 | #include <trace/define_remote_events.h>
|
| 55 |
|
| 56 | This will provide a `struct remote_event remote_event_foo` that can be given to
|
| 57 | `trace_remote_register`.
|
| 58 |
|
| 59 | Registered events appear in the remote directory under **events/**.
|
| 60 |
|
| 61 | Simple ring-buffer
|
| 62 | ==================
|
| 63 | A simple implementation for a ring-buffer writer can be found in
|
| 64 | kernel/trace/simple_ring_buffer.c.
|
| 65 |
|
| 66 | .. kernel-doc:: include/linux/simple_ring_buffer.h
|