BCOS Home » ... » ... » ... » BCOS Boot Transition State Common Specifications |
BCOS Event Log SpecificationPreliminary Draft |
Project Map |
This specification defines the format of data used by the operating system's event log.
Any changes made in future versions of this specification are guaranteed to be backward and forward compatible.
Future versions of this specification may add additional event types or define new standard event IDs; and software should skip any event types or event IDs that it doesn't understand.
The event log conceptually (not necessarily literally) uses a fixed size buffer, where the log is compacted if the buffer become full (see Chapter 6: Compaction). This buffer contains a series of entries in chronological order.
Historical entries are created as part of compaction (see Chapter 6: Compaction) and are used to retain information that would otherwise be discarded by compaction.
Note: It is assumed that software reading the event log is reading sequentially in "oldest to newest" order. When software reaches a historical entry that contains information that the software didn't already have it uses the historical entry to establish previously discarded information; and when software reaches a historical entry that contains information that the software does already have it ignores the historical entry.
Each entry begins with a generic header.
Offset | Size | Description |
---|---|---|
0x00000000 | 2 bytes | Entry Size (see Section 4.1. Entry Header Size Field) |
0x00000002 | 2 bytes | Entry Type (see Section 4.2. Entry Header Type Field) |
0x00000004 | 4 bytes | Source ID (see Section 4.3. Entry Header Source ID Field) |
0x00000008 | 8 bytes | Timestamp (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000010 | 4 bytes | Timestamp Precision (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
The size field contains the size of the complete entry in bytes, such that the address of the next entry can be found by adding the size of an entry to the entry's address.
The type field is used to determine the format of any data that follows the header (as described in Chapter 5: Event Type Reference). The highest bit indicates that the entry is a historical entry (see Chapter 6: Compaction) when set, and the next 2 highest bits of the type are used to determine if the event relates to a process, a device or a CPU, as determined by Table 4-2. Type Bits.
Bits 13 to 14 | Meaning |
---|---|
00b | Event relates to a process |
01b | Event relates to a core |
10b | Event relates to a CPU |
11b | Event relates to a device |
The meaning of the source ID field depends on the highest 2 bits of the entry's type (see Section 4.2. Entry Header Type Field).
If the event is related to a process; the source ID field contains a (32-bit unsigned) process ID.
If the event is related to a core; the source ID field contains a (32-bit unsigned) core ID.
If the event is related to a core; the source ID field contains a (32-bit unsigned) CPU ID.
If the event is related to a device; the source ID field contains a (32-bit unsigned) device ID. Device IDs are split into ranges according to device classifications as described by Table 4-3. Device ID Ranges.
Range | Device Classification |
---|---|
0x00000000 to 0x3FFFFFFF | Storage Devices |
0x40000000 to 0x7FFFFFFF | Network Devices |
0x80000000 to 0xBFFFFFFF | User Input and Output Devices |
0xC0000000 to 0xFFFFFFFF | Other Devices |
Ideally, every event would have a timestamp with 1 nanosecond precision. Unfortunately this isn't always possible, either due to limitations caused by available timer/s or inaccuracy caused by uncertainty. For this reason the timestamps are stored as 2 fields. The timestamp field itself is used to store the earliest possible time an event could have happened, and the timestamp precision field is used to store the difference between the earliest and latest possible times that an event could have happened.
The timestamp field stores the earliest possible time that an event could have happened as (unsigned 64-bit) nanoseconds since boot. This is enough for over 584 years before it will roll over; and if a computer has been running for longer than 584 years the operating system is expected to reboot just to avoid roll over.
The timestamp precision field stores the difference between the earliest and latest possible times that an event could have happened as (unsigned 32-bit) nanoseconds. This allows for more than 4 seconds of uncertainty.
This event is used to assign a name to a process, or to change the previous name of a process. The kernel automatically generates this event when a process is started, and the first "Set Process Name" event for a process determines when the process was started.
Offset | Size | Description |
---|---|---|
0x00000000 | 2 bytes | Entry Size (see Section 4.1. Entry Header Size Field) |
0x00000002 | 2 bytes | Entry Type (see Section 4.2. Entry Header Type Field) |
0x00000004 | 4 bytes | Source ID (see Section 4.3. Entry Header Source ID Field) |
0x00000008 | 8 bytes | Timestamp (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000010 | 4 bytes | Timestamp Precision (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000014 | Varies | UTF-8 Name String (see Subsection 5.1.1. Process and Device Names) |
Name strings are encoded in UTF-8, and are not guaranteed to be zero terminated. Howevever, the name strings may be followed by zero bytes to pad the entry for alignment purposes. This means that the size of the string is determined by the entry size field or the location of the first 0x00 byte, whichever comes first.
This event is used to cancel a name for a process. The kernel automatically generates this event when a process is terminated.
Offset | Size | Description |
---|---|---|
0x00000000 | 2 bytes | Entry Size (see Section 4.1. Entry Header Size Field) |
0x00000002 | 2 bytes | Entry Type (see Section 4.2. Entry Header Type Field) |
0x00000004 | 4 bytes | Source ID (see Section 4.3. Entry Header Source ID Field) |
0x00000008 | 8 bytes | Timestamp (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000010 | 4 bytes | Timestamp Precision (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000014 | 4 bytes | Termination Status (see Subsection 5.2.1. Termination Status) |
Note that process IDs are only considered valid if they have been named and the name hasn't been cancelled; and these IDs can be recycled - a process can be terminated and its name cancelled, then another process can be started and named that uses the same process ID. There should be no events that use invalid (unnamed) process IDs or device IDs (but if there are those events can be ignored and/or discarded).
The termination status is used to indicate why a process or device was cancelled. These values are split into ranges:
Range | Device Classification |
---|---|
0x00000000 to 0x7FFFFFFF | Normal termination |
0x80000000 to 0xBFFFFFFF | Abnormal termination by owner |
0xC0000000 to 0xFFFFFFFF | Abnormal termination by kernel |
The specific values within these ranges are beyond the scope of this specification; however 0x00000000, 0x80000000 and 0xC0000000 indicate "no other information provided".
This event is used explicitly by processes to add generic information to the event log.
Offset | Size | Description |
---|---|---|
0x00000000 | 2 bytes | Entry Size (see Section 4.1. Entry Header Size Field) |
0x00000002 | 2 bytes | Entry Type (see Section 4.2. Entry Header Type Field) |
0x00000004 | 4 bytes | Source ID (see Section 4.3. Entry Header Source ID Field) |
0x00000008 | 8 bytes | Timestamp (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000010 | 4 bytes | Timestamp Precision (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000014 | 4 bytes | Event ID (see Subsection 5.3.1. Event ID) |
0x00000018 | 1 byte | Severity (see Subsection 5.3.2. Event Severity) |
0x00000019 | Varies | UTF-8 Event String (see Subsection 5.3.3. Event Strings) |
For processes, the event ID field is "opaque" and contains an (unsigned 32-bit) value. All values are determined by the creator of the event, and are beyond the scope of this specification (and may not be documented at all - e.g. temporarily used by a developer for debugging).
The severity field determines how severe an event is, as described by Table 5-5. Severity Ranges
Range | Description |
---|---|
0x00 to 0x3F | Informational, for debugging only |
0x40 to 0x7F | Informational |
0x80 to 0xBF | Error condition (that doesn't prevent future functionality) |
0xC0 to 0xFF | Critical condition (that does prevent future functionality) |
Note that the severity field can be used for filtering (e.g. "only show events with severity > 0x80").
Event strings are encoded in UTF-8, and are not guaranteed to be zero terminated. Howevever, the event strings may be followed by zero bytes to pad the entry for alignment purposes. This means that the size of the string is determined by the entry size field or the location of the first 0x00 byte, whichever comes first.
Note that an event string may be absent (a zero length string) when only the opaque event ID is desired.
This event is used by the kernel to indicate that the process called the kernel API.
Offset | Size | Description |
---|---|---|
0x00000000 | 2 bytes | Entry Size (see Section 4.1. Entry Header Size Field) |
0x00000002 | 2 bytes | Entry Type (see Section 4.2. Entry Header Type Field) |
0x00000004 | 4 bytes | Source ID (see Section 4.3. Entry Header Source ID Field) |
0x00000008 | 8 bytes | Timestamp (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000010 | 4 bytes | Timestamp Precision (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000014 | Varies | Function Number List (see Subsection 5.4.1. Function Number Lists) |
Note: For performance and security reasons, the kernel may (and typically will) suppress Kernel API events unless they are specifically requested (either for a specific process, or for all processes); and may supress the function numbers when the Kernel API events themselves are not being suppressed.
The function number lists has none or more 4 byte entries. The number of entries is determined by the enty size field. If the list has no entries then the function numbers are being supressed by the kernel. Otherwise, the list contains the function numbers for all kernel API functions that the process called.
This event is used to indicate that a core has come online or has changed performance or power consumption characterstics. Unlike processes and devices, cores and CPUs are not given names (the core ID and CPU ID are used as their name).
Offset | Size | Description |
---|---|---|
0x00000000 | 2 bytes | Entry Size (see Section 4.1. Entry Header Size Field) |
0x00000002 | 2 bytes | Entry Type (see Section 4.2. Entry Header Type Field) |
0x00000004 | 4 bytes | Source ID (see Section 4.3. Entry Header Source ID Field) |
0x00000008 | 8 bytes | Timestamp (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000010 | 4 bytes | Timestamp Precision (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000014 | 2 bytes | Estimated Core Idle Power Consumption (see Subsection 5.5.1. Estimated Core Power Consumption) |
0x00000016 | 2 bytes | Estimated Core Power Consumption Difference (see Subsection 5.5.1. Estimated Core Power Consumption) |
0x00000018 | Varies | Estimated CPU Performance Table (see Subsection 5.5.2. Estimated CPU Performance Table) |
For estimated power consumption, two different quantities are used - the estimated amount of power a core will consume when it's idle (none of its CPUs are assigned to any process), and the estimated amount of additional power a core will consume when one or more of its CPUs are assigned to a process. Both fields use 2 mW units (e.g. a value of 1234 means 2468 mW).
For the estimated idle power consumption field, 0x0000 indicates "unknown" and 0xFFFF indicates "greater than or equal to 131072 mW". Values from 0x00001 to 0xFFFE represent a range from 2 mW to 131068 mW. If a core uses less than 2 mW when idle, it shall be assumed to use 2 mW instead.
The estimated power consumption differerence field stores the difference between the estimated power consumption when one or more CPUs within the core are assigned to a process and the value stored in the estimated idle power consumption field (and not the actual estimated power consumption at idle). The value 0xFFFF indicates "greater than or equal to 131072 mW".
For example; if a core consumes 200000 mW at idle and 300000 mW when running, then the estimated idle power consumption field would contain 0xFFFF (because 200000 mW is too large to represent), and the estimated power consumption differerence field would contain 0xE848 (because "(0xFFFF + 0xE848) * 2 = 300000 mW").
Note that the power consumption values do not include any power consumed by parts of the physical chip/package that can't be attributed to a specific core. For example, a physical chip might have a built in memory controller that consumes 100 mW plus 2 cores that consume 200 mW each when idle, and this event's fields will only say "200 mW for the core when idle".
The estimated CPU performance table contains 4 byte entries; where the number of entries is equal to the number of CPUs within the core. The number of entries in the table (and therefore the number of CPUs within the core) is determined from the event log entry's size (see Section 4.1. Entry Header Size Field).
The number of CPUs that aren't idle is used as an index into the estimated CPU performance table. For example, if there are 2 CPUs within a core and only one is being used then the first entry determines the estimated performance of the CPU, and if both CPUs are being used then the second entry determines the performance of either CPU.
Performance is based on how many instructions the CPU is likely to execute in a 125 uS period, multiplied by a scaling factor. For 80x86 CPUs the scaling factor is always 1. For other CPUs the scaling factor reflects any differences in the number of instructions needed to get the same amount of work done. For example, if a CPU needs twice as many instructions as an 80x86 to get the same amount of work done, the scaling factor for that CPU would be 0.5.
Note: How many instructions the CPU is likely to execute has nothing to do with theoretical maximums, and ideally should be determined from continual measurements of the actual code being run. Scaling factors should be derived from comparing "number of instructions executed" for a variety of software under the same conditions.
This event is used when a core is taken offline.
Offset | Size | Description |
---|---|---|
0x00000000 | 2 bytes | Entry Size (see Section 4.1. Entry Header Size Field) |
0x00000002 | 2 bytes | Entry Type (see Section 4.2. Entry Header Type Field) |
0x00000004 | 4 bytes | Source ID (see Section 4.3. Entry Header Source ID Field) |
0x00000008 | 8 bytes | Timestamp (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000010 | 4 bytes | Timestamp Precision (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
This event is used by the kernel to add generic information about a core to the event log.
Offset | Size | Description |
---|---|---|
0x00000000 | 2 bytes | Entry Size (see Section 4.1. Entry Header Size Field) |
0x00000002 | 2 bytes | Entry Type (see Section 4.2. Entry Header Type Field) |
0x00000004 | 4 bytes | Source ID (see Section 4.3. Entry Header Source ID Field) |
0x00000008 | 8 bytes | Timestamp (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000010 | 4 bytes | Timestamp Precision (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000014 | 4 bytes | Event ID (see Subsection 5.7.1. Core Event ID) |
0x00000018 | 1 byte | Severity (see Subsection 5.3.2. Event Severity) |
0x00000019 | Varies | UTF-8 Event String (see Subsection 5.3.3. Event Strings) |
Note: This is (intentionally) identical to Section 5.3. Type 0x0010, Generic Process Event, except for the event type, the meaning of the source ID, and standardisation of the event IDs.
For cores, the highest bit of the event ID determines if the value is standardised or opaque. If the highest bit is clear the event ID is defined in Part II, Chapter 1: Standard Core Event ID Reference. If the highest bit is set the value depends on the kernel and is beyond the scope of this specification (and may not be documented at all - e.g. temporarily used by a kernel developer for debugging).
This event is used to indicate that a CPU has come online. Unlike processes and devices, cores and CPUs are not given names (the core ID and CPU ID are used as their name).
Offset | Size | Description |
---|---|---|
0x00000000 | 2 bytes | Entry Size (see Section 4.1. Entry Header Size Field) |
0x00000002 | 2 bytes | Entry Type (see Section 4.2. Entry Header Type Field) |
0x00000004 | 4 bytes | Source ID (see Section 4.3. Entry Header Source ID Field) |
0x00000008 | 8 bytes | Timestamp (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000010 | 4 bytes | Timestamp Precision (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000014 | 4 bytes | Core ID (see Subsection 5.8.1. Core ID) |
The Core ID field determines which core the CPU belongs to.
This event is used when a CPU is taken offline.
Offset | Size | Description |
---|---|---|
0x00000000 | 2 bytes | Entry Size (see Section 4.1. Entry Header Size Field) |
0x00000002 | 2 bytes | Entry Type (see Section 4.2. Entry Header Type Field) |
0x00000004 | 4 bytes | Source ID (see Section 4.3. Entry Header Source ID Field) |
0x00000008 | 8 bytes | Timestamp (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000010 | 4 bytes | Timestamp Precision (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
This event is used when a CPU is assigned to a process, or becomes idle.
Offset | Size | Description |
---|---|---|
0x00000000 | 2 bytes | Entry Size (see Section 4.1. Entry Header Size Field) |
0x00000002 | 2 bytes | Entry Type (see Section 4.2. Entry Header Type Field) |
0x00000004 | 4 bytes | Source ID (see Section 4.3. Entry Header Source ID Field) |
0x00000008 | 8 bytes | Timestamp (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000010 | 4 bytes | Timestamp Precision (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000014 | 4 bytes | Process ID (see Subsection 5.10.1. Process ID) |
Note: The kernel may generate an Assign CPU event every time a CPU enters or leaves the kernel (for all kernel API calls and all interrupts) so that it's possible to determine how much CPU time the kernel itself is consuming. For performance the kernel may also not do this, and when a thread belonging to a process calls the kernel API there is no guarantee that the kernel won't do work on behalf of other unrelated threads/processes before returning to caller; which will cause CPU time consumed by the kernel to be misattributed to the process that previously used the CPU. Any misattribution of CPU time should be negligable (as the kernel is expected to consume very little CPU time).
If the CPU was assigned to a process, this field contains the process ID for that process. If the CPU becomes idle this field will be 0xFFFFFFFF. If the CPU was assigned to the kernel this field will be 0x00000000.
This event is used by the kernel to add generic information about a CPU to the event log.
Offset | Size | Description |
---|---|---|
0x00000000 | 2 bytes | Entry Size (see Section 4.1. Entry Header Size Field) |
0x00000002 | 2 bytes | Entry Type (see Section 4.2. Entry Header Type Field) |
0x00000004 | 4 bytes | Source ID (see Section 4.3. Entry Header Source ID Field) |
0x00000008 | 8 bytes | Timestamp (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000010 | 4 bytes | Timestamp Precision (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000014 | 4 bytes | Event ID (see Subsection 5.11.1. CPU Event ID) |
0x00000018 | 1 byte | Severity (see Subsection 5.3.2. Event Severity) |
0x00000019 | Varies | UTF-8 Event String (see Subsection 5.3.3. Event Strings) |
Note: This is (intentionally) identical to Section 5.3. Type 0x0010, Generic Process Event, except for the event type, the meaning of the source ID, and standardisation of the event IDs.
For CPUs, the highest bit of the event ID determines if the value is standardised or opaque. If the highest bit is clear the event ID is defined in Part II, Chapter 2: Standard CPU Event ID Reference. If the highest bit is set the value depends on the kernel and is beyond the scope of this specification (and may not be documented at all - e.g. temporarily used by a kernel developer for debugging).
This event is used to assign a name to a device, or to change the previous name of a device. The device driver is responsible for naming the device (e.g. when telling kernel the device is ready for use), and the first "Set Device Name" event for a device determines when the device became ready for use.
Offset | Size | Description |
---|---|---|
0x00000000 | 2 bytes | Entry Size (see Section 4.1. Entry Header Size Field) |
0x00000002 | 2 bytes | Entry Type (see Section 4.2. Entry Header Type Field) |
0x00000004 | 4 bytes | Source ID (see Section 4.3. Entry Header Source ID Field) |
0x00000008 | 8 bytes | Timestamp (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000010 | 4 bytes | Timestamp Precision (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000014 | 4 bytes | Process ID for Device Driver (see Subsection 5.12.1. Process ID for Device Driver) |
0x00000018 | Varies | UTF-8 Name String (see Subsection 5.1.1. Process and Device Names) |
This field is used to associate a process (the device driver) with the device.
This event is used to cancel a name for a device. The device driver is responsible for telling the kernel the device was cancelled (e.g. when removeable media was removed), and if a device driver is terminated (e.g. crashes) the kernel automatically generates events to cancel any device names that the device driver was responsible for.
Offset | Size | Description |
---|---|---|
0x00000000 | 2 bytes | Entry Size (see Section 4.1. Entry Header Size Field) |
0x00000002 | 2 bytes | Entry Type (see Section 4.2. Entry Header Type Field) |
0x00000004 | 4 bytes | Source ID (see Section 4.3. Entry Header Source ID Field) |
0x00000008 | 8 bytes | Timestamp (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000010 | 4 bytes | Timestamp Precision (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000014 | 4 bytes | Termination Status (see Subsection 5.2.1. Termination Status) |
Note that process IDs and device IDs are only considered valid if it has been named and the name hasn't been cancelled; and these IDs can be recycled - a process can be terminated and its name cancelled, then another process can be started and named that uses the same process ID. There should be no events that use invalid (unnamed) process IDs or device IDs (but if there are those events can be ignored and/or discarded).
This event is used to log data received from a device (e.g. received from the network, read from a storage device, etc). It should only be used for successfully received data.
Offset | Size | Description |
---|---|---|
0x00000000 | 2 bytes | Entry Size (see Section 4.1. Entry Header Size Field) |
0x00000002 | 2 bytes | Entry Type (see Section 4.2. Entry Header Type Field) |
0x00000004 | 4 bytes | Source ID (see Section 4.3. Entry Header Source ID Field) |
0x00000008 | 8 bytes | Timestamp (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000010 | 4 bytes | Timestamp Precision (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000014 | 4 bytes | Bytes received |
This event is used to log data sent from a device (e.g. sent to the network, written to a storage device, etc). It should only be used for successfully sent data.
Offset | Size | Description |
---|---|---|
0x00000000 | 2 bytes | Entry Size (see Section 4.1. Entry Header Size Field) |
0x00000002 | 2 bytes | Entry Type (see Section 4.2. Entry Header Type Field) |
0x00000004 | 4 bytes | Source ID (see Section 4.3. Entry Header Source ID Field) |
0x00000008 | 8 bytes | Timestamp (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000010 | 4 bytes | Timestamp Precision (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000014 | 4 bytes | Bytes sent |
This event is used by a device driver to add generic information about a device to the event log. Note that a device driver should use "Generic Process Event" (see Section 5.3. Type 0x0010, Generic Process Event) for things that relate to the device driver itself, and should only use this event for things that are related to the device.
Offset | Size | Description |
---|---|---|
0x00000000 | 2 bytes | Entry Size (see Section 4.1. Entry Header Size Field) |
0x00000002 | 2 bytes | Entry Type (see Section 4.2. Entry Header Type Field) |
0x00000004 | 4 bytes | Source ID (see Section 4.3. Entry Header Source ID Field) |
0x00000008 | 8 bytes | Timestamp (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000010 | 4 bytes | Timestamp Precision (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000014 | 4 bytes | Event ID (see Subsection 5.16.1. Device Event ID) |
0x00000018 | 1 byte | Severity (see Subsection 5.3.2. Event Severity) |
0x00000019 | Varies | UTF-8 Event String (see Subsection 5.3.3. Event Strings) |
Note: This is (intentionally) identical to Section 5.3. Type 0x0010, Generic Process Event, except for the event type, the meaning of the source ID, and standardisation of the event IDs.
For devices, the highest bit of the event ID determines if the value is standardised or opaque. If the highest bit is clear the event ID is defined in Part II, Chapter 3: Standard Device Event ID Reference. If the highest bit is set the value depends on the device driver and is beyond the scope of this specification (and may not be documented at all - e.g. temporarily used by a device driver developer for debugging); however use of non-standard event IDs is "highly discouraged" and device driver developers should use "Generic Process Event" (see Section 5.3. Type 0x0010, Generic Process Event) instead.
This event is used by the kernel to indicate that an IRQ was sent to the device's device driver.
Offset | Size | Description |
---|---|---|
0x00000000 | 2 bytes | Entry Size (see Section 4.1. Entry Header Size Field) |
0x00000002 | 2 bytes | Entry Type (see Section 4.2. Entry Header Type Field) |
0x00000004 | 4 bytes | Source ID (see Section 4.3. Entry Header Source ID Field) |
0x00000008 | 8 bytes | Timestamp (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000010 | 4 bytes | Timestamp Precision (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000014 | 4 bytes | IRQ Number (see Subsection 5.17.1. IRQ Numbers) |
Note: For performance reasons, the kernel may (and typically will) suppress IRQ events unless they are specifically requested (either for a specific device, or for all devices).
For devices that have multiple IRQs; this field is used to indicate which IRQ occured. For example, if a device has 16 different IRQs then this field will be a number from 0x00 to 0x10. The IRQ number has nothing to do with any lower level information (e.g. it does not indicate which interrupt vector the kernel uses for the IRQ internally, or how or if the IRQ is connected to any kind of interrupt controller in the chipset).
This event is used to retain the name of a process when the original event is discarded as part of compaction (see Chapter 6: Compaction). The timestamp used by this event indicates when the process was first created, and does not indicate when the event occured (because the event didn't occur) and doesn't indicate when compaction occured. The name is the name the process was using when compaction occured.
Offset | Size | Description |
---|---|---|
0x00000000 | 2 bytes | Entry Size (see Section 4.1. Entry Header Size Field) |
0x00000002 | 2 bytes | Entry Type (see Section 4.2. Entry Header Type Field) |
0x00000004 | 4 bytes | Source ID (see Section 4.3. Entry Header Source ID Field) |
0x00000008 | 8 bytes | Timestamp (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000010 | 4 bytes | Timestamp Precision (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000014 | Varies | UTF-8 Name String (see Subsection 5.1.1. Process and Device Names) |
This event is used to retain the information about a core when the original event is discarded as part of compaction (see Chapter 6: Compaction). The timestamp used by this event indicates when the core first came online, and does not indicate when the event occured (because the event didn't occur) and doesn't indicate when compaction occured. The other fields (estimated power and performance) are values from when compaction occured.
Offset | Size | Description |
---|---|---|
0x00000000 | 2 bytes | Entry Size (see Section 4.1. Entry Header Size Field) |
0x00000002 | 2 bytes | Entry Type (see Section 4.2. Entry Header Type Field) |
0x00000004 | 4 bytes | Source ID (see Section 4.3. Entry Header Source ID Field) |
0x00000008 | 8 bytes | Timestamp (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000010 | 4 bytes | Timestamp Precision (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000014 | 2 bytes | Estimated Core Idle Power Consumption (see Subsection 5.5.1. Estimated Core Power Consumption) |
0x00000016 | 2 bytes | Estimated Core Power Consumption Difference (see Subsection 5.5.1. Estimated Core Power Consumption) |
0x00000018 | Varies | Estimated CPU Performance Table (see Subsection 5.5.2. Estimated CPU Performance Table) |
This event is used to retain the information about a CPU when the original event is discarded as part of compaction (see Chapter 6: Compaction). The timestamp used by this event indicates when the CPU first came online, and does not indicate when the event occured (because the event didn't occur) and doesn't indicate when compaction occured.
Offset | Size | Description |
---|---|---|
0x00000000 | 2 bytes | Entry Size (see Section 4.1. Entry Header Size Field) |
0x00000002 | 2 bytes | Entry Type (see Section 4.2. Entry Header Type Field) |
0x00000004 | 4 bytes | Source ID (see Section 4.3. Entry Header Source ID Field) |
0x00000008 | 8 bytes | Timestamp (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000010 | 4 bytes | Timestamp Precision (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000014 | 4 bytes | Core ID (see Subsection 5.8.1. Core ID) |
This event is used to retain the information about a CPU when the original event is discarded as part of compaction (see Chapter 6: Compaction). The timestamp used by this event indicates when the CPU was assigned to the process, and does not indicate when the event occured (because the event didn't occur) and doesn't indicate when compaction occured.
Offset | Size | Description |
---|---|---|
0x00000000 | 2 bytes | Entry Size (see Section 4.1. Entry Header Size Field) |
0x00000002 | 2 bytes | Entry Type (see Section 4.2. Entry Header Type Field) |
0x00000004 | 4 bytes | Source ID (see Section 4.3. Entry Header Source ID Field) |
0x00000008 | 8 bytes | Timestamp (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000010 | 4 bytes | Timestamp Precision (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000014 | 4 bytes | Process ID (see Subsection 5.10.1. Process ID) |
This event is used to retain the name of a device when the original event is discarded as part of compaction (see Chapter 6: Compaction). The timestamp used by this event indicates when the device was first became ready for use; and does not indicate when the event occured (because the event didn't occur) and doesn't indicate when compaction occured. The name is the name the device was using when compaction occured.
Offset | Size | Description |
---|---|---|
0x00000000 | 2 bytes | Entry Size (see Section 4.1. Entry Header Size Field) |
0x00000002 | 2 bytes | Entry Type (see Section 4.2. Entry Header Type Field) |
0x00000004 | 4 bytes | Source ID (see Section 4.3. Entry Header Source ID Field) |
0x00000008 | 8 bytes | Timestamp (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000010 | 4 bytes | Timestamp Precision (see Section 4.4. Entry Header Timestamp and Timestamp Precision Fields) |
0x00000014 | 4 bytes | Process ID for Device Driver (see Subsection 5.12.1. Process ID for Device Driver) |
0x00000018 | Varies | UTF-8 Name String (see Subsection 5.1.1. Process and Device Names) |
The amount of memory and the amount of space that the kernel is able to use for the event log is limited - the kernel can't keep appending new information without running out of memory or space eventually. This means that the kernel must discard old information to avoid running out of memory or space.
The problem with discarding old entries is that newer entries can depend on them. For example, a newer entry might say that a CPU was assigned to a process, but information about the CPU and information about the process may have been in older entries that were discarded.
To avoid this problem compaction uses historical entries (see: Section 3.1. Historical Entries). However, for performance reasons (to avoid scanning through the entire log when compaction occurs) compaction isn't strictly reactive and has a large proactive component.
Please note that there are 2 scenarious that need to be taken into account. If software is obtaining the event log from the kernel for the first time then it will need historical entries; but if software is continually monitoring the event log (possibly including writing it to a much larger log on disk) then it can discard the historical entries.
The kernel has a circular buffer (when it reaches the end of the buffer, kernel just wraps around and continues writing to the start of the buffer). This circular buffer is split into four zones of approximately equal size. After the kernel adds an event it checks if it has moved into the next zone; and if it has it (proactively) adds historical entries for the current cores, CPUs, processes and devices. Note that because this is done proactively, the information is actually current rather than historical - it becomes historical later. Kernel is expected to keep information needed to create the historical entries available in various (unrelated) structures. The kernel also keeps track of the address of the first historical entry in each zone.
Before the kernel adds a new entry to the event log, it checks to ensure that there is enough free space. If there isn't enough space the kernel uses address of the first historical entry in the next zone to determine the new address of the oldest entry in the circular buffer; which frees up (approximately) a zone for reuse.
The kernel should limit the maximum number of processes to ensure that the total size of historical entries can not exceed the size of one zone (and should ensure that the total size of historical entries is much smaller than the size of a zone to avoid excessive overhead caused by doing compaction too frequently). If the total size of historical entries does exceed the size of a zone, then the kernel has to free up multiple zones to ensure that historical entries can be created. If the total size of the historical entries is larger than 3 zones all previous information is lost every time compaction occurs; and if the total size of the historical entries is larger than all 4 zones it's impossible for kernel to function correctly.
Note: This is only a reference algorithm. The kernel is free to extend the essential idea or use an alternative approach. This includes using "per CPU" event logs (to improve scalability) and merging them into a "master event log" if/when needed.
So that software can effectively monitor the kernel's event log, the kernel shall provide support for subscribing to compaction notifications, and provide support to sending "compaction occured" messages to threads that have subscribed after compaction occurs. The subscription and notification is beyond the scope of this specification.
The event log is designed so that the events can be viewed in multiple different ways. The following are some of the possible ways that the event log can be viewed.
By using the generic events (see Section 5.3. Type 0x0010, Generic Process Event, Section 5.7. Type 0x2010, Generic Core Event, Section 5.11. Type 0x4010, Generic CPU Event and Section 5.16. Type 0x6010, Generic Device Event) only, and ignoring generic events that have no string; a traditional text log can be generated. This can be further filtered by severity.
The event IDs could also be shown in these logs (and standardised event IDs from cores, CPUs and devices can be given a description).
By using one of the generic events only (see Section 5.3. Type 0x0010, Generic Process Event, Section 5.7. Type 0x2010, Generic Core Event, Section 5.11. Type 0x4010, Generic CPU Event or Section 5.16. Type 0x6010, Generic Device Event), and ignoring generic events that have no string; a traditional text log can be generated for a specific process, a specific device, etc. This can be further filtered by severity.
The event IDs could also be shown in these logs (and standardised event IDs from cores, CPUs and devices can be given a description).
By using events related to CPUs (see Section 5.8. Type 0x4000, CPU Online, Section 5.9. Type 0x4001, CPU Offline and Section 5.10. Type 0x4002, Assign CPU) only, a graph of CPU utilisation can be generated. This can be one graph for all CPUs, one graph per core (using the "core ID" field of the "CPU Online" events), or one graph for each CPU.
By using device input events and device ouput events (see Section 5.14. Type 0x6002, Device Input Event and Section 5.15. Type 0x6003, Device Output Event), a graph of overall IO utilisation can be generated. By using the "source ID" this can be filtered by device type (e.g. "all bytes sent/received by all networking", "all data read/written by all storage devices", etc). By using the device name events (see Section 5.12. Type 0x6000, Set Device Name) this can be split into one graph per device.
Note that "timestamp bucketing" can be applied to get a bar graphs or line graphs representing bandwidth consumption, where granularity depends on the "bucketing". For example, with "1 second buckets" (where all bytes sent/received within that second are added together in the bucket) you'd add have a graph of total bytes sent/received per second; and with "1 millisecond buckets" you'd have a graph of total bytes sent/received per millisecond.
Information about when the kernel sent IRQs to the device driver (see Section 5.17. Type 0x6011, IRQ Event) can also be included; to show (e.g.) the latency between the IRQ being received and the device driver saying data was sent or received.
By using events related to CPUs (see Section 5.8. Type 0x4000, CPU Online, Section 5.9. Type 0x4001, CPU Offline and Section 5.10. Type 0x4002, Assign CPU) and "Core Online" events (see Section 5.5. Type 0x2000, Core Online), a graph of CPU performance, or CPU power consumption, can be generated. It is also possible to combine both to create a CPU efficiency graph (e.g. "performance per watt").
By using "Assign CPU" events (see Section 5.10. Type 0x4002, Assign CPU) only, a graph of how much CPU time a single process has used can be generated. By also using information from "Core Online" events (see Section 5.5. Type 0x2000, Core Online) and tracking the number of CPUs that are assigned or idle; a graph of how much CPU performance or CPU power consumption a process has used can be generated.
This can also be one graph for each process. By using the "Set Process Name" events (see Section 5.1. Type 0x0000, Set Process Name) these graphs can be named.
By super-imposing information from generic events (see Section 5.3. Type 0x0010, Generic Process Event) on top of a graph of a process' CPU performance and/or CPU power consumption; it would be possible to show all information for a process at the same time. For example; with markers showing when the generic events occured, and possibly with pop-up dialog boxes containing the generic event details, etc.
By using the "Process ID for Device Driver" field from Set Device Name events (see Section 5.12. Type 0x6000, Set Device Name) to associate device/s with their device driver; a device IO graph/s (see Section 7.4. Device IO Utilisation Graphs) for a device driver's device/s can be super-imposed on top of data from a process explorer graph (see Section 7.7. Process Explorer) for the device driver.
The standard event IDs used for cores are described by Table 1-1. Standard Core Event IDs. All event IDs not defined in this table are reserved.
Value | Description |
---|---|
0x00000000 | Unspecfied event ID (used when only a string is needed for the event) |
The standard event IDs used for CPUs are described by Table 2-1. Standard CPU Event IDs. All event IDs not defined in this table are reserved.
Value | Description |
---|---|
0x00000000 | Unspecfied event ID (used when only a string is needed for the event) |
The standard event IDs used for devices are described by Table 3-1. Device Event IDs. All event IDs not defined in this table are reserved.
Value | Description |
---|---|
0x00000000 | Unspecfied event ID (used when only a string is needed for the event) |