source: rtems/cpukit/include/rtems/recorddata.h @ dca6184

5
Last change on this file since dca6184 was dca6184, checked in by Sebastian Huber <sebastian.huber@…>, on 04/28/18 at 09:36:11

Add low level event recording support

Add low level event recording infrastructure for system and user
defined events. The infrastructure is able to record high frequency
events such as

  • SMP lock acquire/release,
  • interrupt entry/exit,
  • thread switches,
  • UMA zone allocate/free, and
  • Ethernet packet input/output, etc.

It allows post-mortem analysis in fatal error handlers, e.g. the last
events are in the record buffer, the newest event overwrites the oldest
event. It is possible to detect record buffer overflows for consumers
that expect a continuous stream of events, e.g. to display the system
state in real-time.

The implementation supports high-end SMP machines (more than 1GHz
processor frequency, more than four processors).

Add a new API instead. The implementation uses per-processor data
structures and no atomic read-modify-write operations. It is uses
per-processor ring buffers to record the events.

The CPU counter is used to get the time of events. It is combined with
periodic uptime events to synchronize it with CLOCK_REALTIME.

The existing capture engine tries to solve this problem also, but its
performance is not good enough for high-end production systems. The
main issues are the variable-size buffers and the use of SMP locks for
synchronization. To fix this, the API would change significantly.

Update #3665.

  • Property mode set to 100644
File size: 8.8 KB
Line 
1/*
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (C) 2018, 2019 embedded brains GmbH
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28/*
29 * This file must be compatible to general purpose POSIX system, e.g. Linux,
30 * FreeBSD.  It may be used for utility programs.
31 */
32
33#ifndef _RTEMS_RECORDDATA_H
34#define _RTEMS_RECORDDATA_H
35
36#include <stdint.h>
37
38#ifdef __cplusplus
39extern "C" {
40#endif /* __cplusplus */
41
42/**
43 * @defgroup RTEMSRecord Event Recording
44 *
45 * @brief Low-level event recording support.
46 *
47 * @{
48 */
49
50/**
51 * @brief The record version.
52 *
53 * The record version reflects the record event definitions.  It is reported by
54 * the RTEMS_RECORD_VERSION event.
55 */
56#define RTEMS_RECORD_THE_VERSION 1
57
58/**
59 * @brief The items are in 32-bit little-endian format.
60 */
61#define RTEMS_RECORD_FORMAT_LE_32 0x11111111
62
63/**
64 * @brief The items are in 64-bit little-endian format.
65 */
66#define RTEMS_RECORD_FORMAT_LE_64 0x22222222
67
68/**
69 * @brief The items are in 32-bit big-endian format.
70 */
71#define RTEMS_RECORD_FORMAT_BE_32 0x33333333
72
73/**
74 * @brief The items are in 64-bit big-endian format.
75 */
76#define RTEMS_RECORD_FORMAT_BE_64 0x44444444
77
78/**
79 * @brief Magic number to identify a record item stream.
80 *
81 * This is a random number.
82 */
83#define RTEMS_RECORD_MAGIC 0x82e14ec1
84
85/**
86 * @brief The record events.
87 */
88typedef enum {
89  /* There are 512 events reserved for the system */
90  RTEMS_RECORD_EMPTY,
91  RTEMS_RECORD_VERSION,
92
93  /*
94   * Keep the following system events in lexicographical order, increment
95   * RTEMS_RECORD_THE_VERSION after each change.
96   */
97  RTEMS_RECORD_ACCEPT,
98  RTEMS_RECORD_BIND,
99  RTEMS_RECORD_BUFFER,
100  RTEMS_RECORD_CHOWN,
101  RTEMS_RECORD_CLOSE,
102  RTEMS_RECORD_CONNECT,
103  RTEMS_RECORD_COUNT,
104  RTEMS_RECORD_ETHER_INPUT,
105  RTEMS_RECORD_ETHER_OUTPUT,
106  RTEMS_RECORD_FCHMOD,
107  RTEMS_RECORD_FCNTL,
108  RTEMS_RECORD_FDATASYNC,
109  RTEMS_RECORD_FREQUENCY,
110  RTEMS_RECORD_FSTAT,
111  RTEMS_RECORD_FSYNC,
112  RTEMS_RECORD_FTRUNCATE,
113  RTEMS_RECORD_GIT_HASH,
114  RTEMS_RECORD_HEAD,
115  RTEMS_RECORD_HEAP_ALLOC,
116  RTEMS_RECORD_HEAP_FREE,
117  RTEMS_RECORD_HEAP_SIZE,
118  RTEMS_RECORD_HEAP_USAGE,
119  RTEMS_RECORD_INTERUPT_BEGIN,
120  RTEMS_RECORD_INTERUPT_END,
121  RTEMS_RECORD_INTERUPT_INSTALL,
122  RTEMS_RECORD_INTERUPT_REMOVE,
123  RTEMS_RECORD_IOCTL,
124  RTEMS_RECORD_IP6_INPUT,
125  RTEMS_RECORD_IP6_OUTPUT,
126  RTEMS_RECORD_IP_INPUT,
127  RTEMS_RECORD_IP_OUTPUT,
128  RTEMS_RECORD_KEVENT,
129  RTEMS_RECORD_KQUEUE,
130  RTEMS_RECORD_LENGTH,
131  RTEMS_RECORD_LINK,
132  RTEMS_RECORD_LSEEK,
133  RTEMS_RECORD_MKNOD,
134  RTEMS_RECORD_MMAP,
135  RTEMS_RECORD_MOUNT,
136  RTEMS_RECORD_OPEN,
137  RTEMS_RECORD_OVERFLOW,
138  RTEMS_RECORD_PAGE_ALLOC,
139  RTEMS_RECORD_PAGE_FREE,
140  RTEMS_RECORD_POLL,
141  RTEMS_RECORD_PROCESSOR,
142  RTEMS_RECORD_PROCESSOR_MAXIMUM,
143  RTEMS_RECORD_READ,
144  RTEMS_RECORD_READLINK,
145  RTEMS_RECORD_READV,
146  RTEMS_RECORD_RECV,
147  RTEMS_RECORD_RECVFROM,
148  RTEMS_RECORD_RECVMSG,
149  RTEMS_RECORD_RENAME,
150  RTEMS_RECORD_RTEMS_BARRIER_CREATE,
151  RTEMS_RECORD_RTEMS_BARRIER_DELETE,
152  RTEMS_RECORD_RTEMS_BARRIER_RELEASE,
153  RTEMS_RECORD_RTEMS_BARRIER_WAIT,
154  RTEMS_RECORD_RTEMS_EVENT_RECEIVE,
155  RTEMS_RECORD_RTEMS_EVENT_SEND,
156  RTEMS_RECORD_RTEMS_EVENT_SYSTEM_RECEIVE,
157  RTEMS_RECORD_RTEMS_EVENT_SYSTEM_SEND,
158  RTEMS_RECORD_RTEMS_MESSAGE_QUEUE_BROADCAST,
159  RTEMS_RECORD_RTEMS_MESSAGE_QUEUE_CREATE,
160  RTEMS_RECORD_RTEMS_MESSAGE_QUEUE_DELETE,
161  RTEMS_RECORD_RTEMS_MESSAGE_QUEUE_FLUSH,
162  RTEMS_RECORD_RTEMS_MESSAGE_QUEUE_RECEIVE,
163  RTEMS_RECORD_RTEMS_MESSAGE_QUEUE_SEND,
164  RTEMS_RECORD_RTEMS_MESSAGE_QUEUE_URGENT,
165  RTEMS_RECORD_RTEMS_PARTITION_CREATE,
166  RTEMS_RECORD_RTEMS_PARTITION_DELETE,
167  RTEMS_RECORD_RTEMS_PARTITION_GET_BUFFER,
168  RTEMS_RECORD_RTEMS_PARTITION_RETURN_BUFFER,
169  RTEMS_RECORD_RTEMS_RATE_MONOTONIC_CANCEL,
170  RTEMS_RECORD_RTEMS_RATE_MONOTONIC_CREATE,
171  RTEMS_RECORD_RTEMS_RATE_MONOTONIC_DELETE,
172  RTEMS_RECORD_RTEMS_RATE_MONOTONIC_PERIOD,
173  RTEMS_RECORD_RTEMS_SEMAPHORE_CREATE,
174  RTEMS_RECORD_RTEMS_SEMAPHORE_DELETE,
175  RTEMS_RECORD_RTEMS_SEMAPHORE_FLUSH,
176  RTEMS_RECORD_RTEMS_SEMAPHORE_OBTAIN,
177  RTEMS_RECORD_RTEMS_SEMAPHORE_RELEASE,
178  RTEMS_RECORD_RTEMS_TIMER_CANCEL,
179  RTEMS_RECORD_RTEMS_TIMER_CREATE,
180  RTEMS_RECORD_RTEMS_TIMER_DELETE,
181  RTEMS_RECORD_RTEMS_TIMER_FIRE_AFTER,
182  RTEMS_RECORD_RTEMS_TIMER_FIRE_WHEN,
183  RTEMS_RECORD_RTEMS_TIMER_RESET,
184  RTEMS_RECORD_RTEMS_TIMER_SERVER_FIRE_AFTER,
185  RTEMS_RECORD_RTEMS_TIMER_SERVER_FIRE_WHEN,
186  RTEMS_RECORD_SELECT,
187  RTEMS_RECORD_SEND,
188  RTEMS_RECORD_SENDMSG,
189  RTEMS_RECORD_SENDTO,
190  RTEMS_RECORD_SOCKET,
191  RTEMS_RECORD_STATVFS,
192  RTEMS_RECORD_SYMLINK,
193  RTEMS_RECORD_TAIL,
194  RTEMS_RECORD_TCP_INPUT,
195  RTEMS_RECORD_TCP_OUTPUT,
196  RTEMS_RECORD_THREAD_BEGIN,
197  RTEMS_RECORD_THREAD_CREATE,
198  RTEMS_RECORD_THREAD_DELETE,
199  RTEMS_RECORD_THREAD_EXIT,
200  RTEMS_RECORD_THREAD_EXITTED,
201  RTEMS_RECORD_THREAD_ID,
202  RTEMS_RECORD_THREAD_PRIO_CURRENT_HIGH,
203  RTEMS_RECORD_THREAD_PRIO_CURRENT_LOW,
204  RTEMS_RECORD_THREAD_PRIO_REAL_HIGH,
205  RTEMS_RECORD_THREAD_PRIO_REAL_LOW,
206  RTEMS_RECORD_THREAD_QUEUE_ENQUEUE,
207  RTEMS_RECORD_THREAD_QUEUE_ENQUEUE_STICKY,
208  RTEMS_RECORD_THREAD_QUEUE_EXTRACT,
209  RTEMS_RECORD_THREAD_QUEUE_SURRENDER,
210  RTEMS_RECORD_THREAD_QUEUE_SURRENDER_STICKY,
211  RTEMS_RECORD_THREAD_RESTART,
212  RTEMS_RECORD_THREAD_STACK_CURRENT,
213  RTEMS_RECORD_THREAD_STACK_SIZE,
214  RTEMS_RECORD_THREAD_STACK_USAGE,
215  RTEMS_RECORD_THREAD_START,
216  RTEMS_RECORD_THREAD_STATE_CLEAR,
217  RTEMS_RECORD_THREAD_STATE_SET,
218  RTEMS_RECORD_THREAD_SWITCH_IN,
219  RTEMS_RECORD_THREAD_SWITCH_OUT,
220  RTEMS_RECORD_THREAD_TERMINATE,
221  RTEMS_RECORD_UDP_INPUT,
222  RTEMS_RECORD_UDP_OUTPUT,
223  RTEMS_RECORD_UMA_ALLOC_PTR,
224  RTEMS_RECORD_UMA_ALLOC_ZONE,
225  RTEMS_RECORD_UMA_FREE_PTR,
226  RTEMS_RECORD_UMA_FREE_ZONE,
227  RTEMS_RECORD_UNLINK,
228  RTEMS_RECORD_UNMOUNT,
229  RTEMS_RECORD_UPTIME_HIGH,
230  RTEMS_RECORD_UPTIME_LOW,
231  RTEMS_RECORD_WORKSPACE_ALLOC,
232  RTEMS_RECORD_WORKSPACE_FREE,
233  RTEMS_RECORD_WORKSPACE_SIZE,
234  RTEMS_RECORD_WORKSPACE_USAGE,
235  RTEMS_RECORD_WRITE,
236  RTEMS_RECORD_WRITEV,
237
238  /* There are 512 events reserved for the user */
239  RTEMS_RECORD_USER = 512,
240
241  RTEMS_RECORD_LAST = 1023
242} rtems_record_event;
243
244/**
245 * @brief Bits in the record item event member reserved for the actual event.
246 */
247#define RTEMS_RECORD_EVENT_BITS 10
248
249/**
250 * @brief Bits in the record item event member reserved for the time of the
251 * event.
252 */
253#define RTEMS_RECORD_TIME_BITS 22
254
255/**
256 * @brief Builds a time event for the specified time stamp and event.
257 *
258 * The events are stored in the record item with a time stamp.  There are 22
259 * bits allocated to the time stamp and 10 bits allocated to the event.  The 22
260 * bits are enough to get reliable time stamps on a system with a 4GHz CPU
261 * counter and a 1000Hz clock tick.
262 */
263#define RTEMS_RECORD_TIME_EVENT( time, event ) \
264  ( ( ( time ) << RTEMS_RECORD_EVENT_BITS ) | ( event ) )
265
266/**
267 * @brief Gets the time of a time event.
268 */
269#define RTEMS_RECORD_GET_TIME( time_event ) \
270  ( ( time_event ) >> RTEMS_RECORD_EVENT_BITS )
271
272/**
273 * @brief Gets the event of a time event.
274 */
275#define RTEMS_RECORD_GET_EVENT( time_event ) \
276  ( ( time_event ) & ( ( 1U << RTEMS_RECORD_EVENT_BITS ) - 1U ) )
277
278/**
279 * @brief The record data integer type.
280 *
281 * It is big enough to store 32-bit integers and pointers.
282 */
283typedef unsigned long rtems_record_data;
284
285/**
286 * @brief The native record item.
287 */
288typedef struct __attribute__((__packed__)) {
289  uint32_t          event;
290  rtems_record_data data;
291} rtems_record_item;
292
293/**
294 * @brief The 32-bit format record item.
295 */
296typedef struct {
297  uint32_t event;
298  uint32_t data;
299} rtems_record_item_32;
300
301/**
302 * @brief The 64-bit format record item.
303 */
304typedef struct __attribute__((__packed__)) {
305  uint32_t event;
306  uint64_t data;
307} rtems_record_item_64;
308
309const char *rtems_record_event_text( rtems_record_event event );
310
311/** @} */
312
313#ifdef __cplusplus
314}
315#endif /* __cplusplus */
316
317#endif /* _RTEMS_RECORDDATA_H */
Note: See TracBrowser for help on using the repository browser.