@@ -20,14 +20,14 @@ dynamic_events is the same as the ioctl with the u: prefix applied.
2020
2121Typically programs will register a set of events that they wish to expose to
2222tools that can read trace_events (such as ftrace and perf). The registration
23- process gives back two ints to the program for each event. The first int is the
24- status index . This index describes which byte in the
23+ process gives back two ints to the program for each event. The first int is
24+ the status bit . This describes which bit in little-endian format in the
2525/sys/kernel/debug/tracing/user_events_status file represents this event. The
26- second int is the write index. This index describes the data when a write() or
26+ second int is the write index which describes the data when a write() or
2727writev() is called on the /sys/kernel/debug/tracing/user_events_data file.
2828
29- The structures referenced in this document are contained with the
30- /include/uap /linux/user_events.h file in the source tree.
29+ The structures referenced in this document are contained within the
30+ /include/uapi /linux/user_events.h file in the source tree.
3131
3232**NOTE: ** *Both user_events_status and user_events_data are under the tracefs
3333filesystem and may be mounted at different paths than above. *
@@ -38,18 +38,18 @@ Registering within a user process is done via ioctl() out to the
3838/sys/kernel/debug/tracing/user_events_data file. The command to issue is
3939DIAG_IOCSREG.
4040
41- This command takes a struct user_reg as an argument::
41+ This command takes a packed struct user_reg as an argument::
4242
4343 struct user_reg {
4444 u32 size;
4545 u64 name_args;
46- u32 status_index ;
46+ u32 status_bit ;
4747 u32 write_index;
4848 };
4949
5050The struct user_reg requires two inputs, the first is the size of the structure
5151to ensure forward and backward compatibility. The second is the command string
52- to issue for registering. Upon success two outputs are set, the status index
52+ to issue for registering. Upon success two outputs are set, the status bit
5353and the write index.
5454
5555User based events show up under tracefs like any other event under the
@@ -111,15 +111,56 @@ in realtime. This allows user programs to only incur the cost of the write() or
111111writev() calls when something is actively attached to the event.
112112
113113User programs call mmap() on /sys/kernel/debug/tracing/user_events_status to
114- check the status for each event that is registered. The byte to check in the
115- file is given back after the register ioctl() via user_reg.status_index.
114+ check the status for each event that is registered. The bit to check in the
115+ file is given back after the register ioctl() via user_reg.status_bit. The bit
116+ is always in little-endian format. Programs can check if the bit is set either
117+ using a byte-wise index with a mask or a long-wise index with a little-endian
118+ mask.
119+
116120Currently the size of user_events_status is a single page, however, custom
117121kernel configurations can change this size to allow more user based events. In
118122all cases the size of the file is a multiple of a page size.
119123
120- For example, if the register ioctl() gives back a status_index of 3 you would
121- check byte 3 of the returned mmap data to see if anything is attached to that
122- event.
124+ For example, if the register ioctl() gives back a status_bit of 3 you would
125+ check byte 0 (3 / 8) of the returned mmap data and then AND the result with 8
126+ (1 << (3 % 8)) to see if anything is attached to that event.
127+
128+ A byte-wise index check is performed as follows::
129+
130+ int index, mask;
131+ char *status_page;
132+
133+ index = status_bit / 8;
134+ mask = 1 << (status_bit % 8);
135+
136+ ...
137+
138+ if (status_page[index] & mask) {
139+ /* Enabled */
140+ }
141+
142+ A long-wise index check is performed as follows::
143+
144+ #include <asm/bitsperlong.h>
145+ #include <endian.h>
146+
147+ #if __BITS_PER_LONG == 64
148+ #define endian_swap(x) htole64(x)
149+ #else
150+ #define endian_swap(x) htole32(x)
151+ #endif
152+
153+ long index, mask, *status_page;
154+
155+ index = status_bit / __BITS_PER_LONG;
156+ mask = 1L << (status_bit % __BITS_PER_LONG);
157+ mask = endian_swap(mask);
158+
159+ ...
160+
161+ if (status_page[index] & mask) {
162+ /* Enabled */
163+ }
123164
124165Administrators can easily check the status of all registered events by reading
125166the user_events_status file directly via a terminal. The output is as follows::
@@ -137,29 +178,18 @@ For example, on a system that has a single event the output looks like this::
137178
138179 Active: 1
139180 Busy: 0
140- Max: 4096
181+ Max: 32768
141182
142183If a user enables the user event via ftrace, the output would change to this::
143184
144185 1:test # Used by ftrace
145186
146187 Active: 1
147188 Busy: 1
148- Max: 4096
149-
150- **NOTE: ** *A status index of 0 will never be returned. This allows user
151- programs to have an index that can be used on error cases. *
152-
153- Status Bits
154- ^^^^^^^^^^^
155- The byte being checked will be non-zero if anything is attached. Programs can
156- check specific bits in the byte to see what mechanism has been attached.
157-
158- The following values are defined to aid in checking what has been attached:
159-
160- **EVENT_STATUS_FTRACE ** - Bit set if ftrace has been attached (Bit 0).
189+ Max: 32768
161190
162- **EVENT_STATUS_PERF ** - Bit set if perf has been attached (Bit 1).
191+ **NOTE: ** *A status bit of 0 will never be returned. This allows user programs
192+ to have a bit that can be used on error cases. *
163193
164194Writing Data
165195------------
0 commit comments