patina_performance 22.0.1

Performance measurement infrastructure.
Documentation

Patina Performance Component

The Patina performance component maintains the infrastructure to report firmware performance information.

Responsibilities

  • Initialize the FBPT and seed it with any measurements passed in performance data HOBs from prior boot phases.
  • Track the current performance measurement mask and load-image count so event producers can filter their output.
  • Publish performance properties through a configuration table and expose the measurement protocol (EdkiiPerformanceMeasurement) for C drivers that need to log performance data.
  • Optionally merge Management Mode (MM) performance records when an MM communication region is available.
  • Publish the FBPT so the operating system can consume it later.

Configuration

By default (e.g. Performance::new()), performance measurements are disabled. Performance measurements can then be enabled by one of two ways:

  1. Usage of the Performance::with_measurements(...) method to specify the bitmask of Measurement values that should be recorded.
  2. Production of the PerformanceConfigHob prior to Patina DXE Core execution.

If both methods are used, the configuration via PerformanceConfigHob takes priority.

use patina_dxe_core::*;
use patina_performance::component::*;

struct ExampleComponent;

impl ComponentInfo for ExampleComponent {
  fn components(mut add: Add<Component>) {
    // Performance measurements are disabled by default, but can be overridden by a performance config HOB.
    add.component(Performance::new());

    // Performance measurements are enabled by default, but can be overridden by a performance config HOB.
    add.component(Performance::new().with_measurements(
       Measurement::DriverBindingStart
        | Measurement::DriverBindingStop
        | Measurement::DriverBindingSupport
        | Measurement::LoadImage
        | Measurement::StartImage
    ));
  }  
}

API

Macro name in EDK II Function name in Patina component Description
PERF_START_IMAGE_BEGIN PERF_START_IMAGE_END perf_image_start_beginperf_image_start_end Measure the performance of start image in core.
PERF_LOAD_IMAGE_BEGINPERF_LOAD_IMAGE_END perf_load_image_beginperf_load_image_end Measure the performance of load image in core.
PERF_DRIVER_BINDING_SUPPORT_BEGIN PERF_DRIVER_BINDING_SUPPORT_END perf_driver_binding_support_beginperf_driver_binding_support_end Measure the performance of driver binding support in core.
PERF_DRIVER_BINDING_START_BEGINPERF_DRIVER_BINDING_START_END perf_driver_binding_start_beginperf_driver_binding_start_end Measure the performance of driver binding start in core.
PERF_DRIVER_BINDING_STOP_BEGINPERF_DRIVER_BINDING_STOP_END perf_driver_binding_stop_beginperf_driver_binding_stop_end Measure the performance of driver binding stop in core.
PERF_EVENT perf_event Measure the time from power-on to this function execution.
PERF_EVENT_SIGNAL_BEGINPERF_EVENT_SIGNAL_END perf_event_signal_beginperf_event_signal_end Measure the performance of event signal behavior in any module.
PERF_CALLBACK_BEGINPERF_CALLBACK_END perf_callback_beginperf_callback_end Measure the performance of a callback function in any module.
PERF_FUNCTION_BEGINPERF_FUNCTION_END perf_function_beginperf_function_end Measure the performance of a general function in any module.
PERF_INMODULE_BEGINPERF_INMODULE_END perf_in_module_beginperf_in_module_end Measure the performance of a behavior within one module.
PERF_CROSSMODULE_BEGINPERF_CROSSMODULE_END perf_cross_module_beginperf_cross_module_end Measure the performance of a behavior in different modules.
PERF_STARTPERF_START_EXPERF_ENDPERF_END_EX perf_startperf_start_experf_endperf_end_ex Make a performance measurement.

Logging Performance Measurements

The method to record performance measurements varies according to whether it is performed from within the core or an external component.

Example of measurement from within the core:

# extern crate mu_rust_helpers;
# extern crate patina;
use patina::performance::{
   logging::perf_function_begin,
   measurement::create_performance_measurement,
};
use mu_rust_helpers::guid::CALLER_ID;

perf_function_begin("foo", &CALLER_ID, create_performance_measurement);

Performance Component Overview

The Performance Component provides an API for logging performance measurements during firmware execution. This API includes:

  • Utility functions to log specific events.
  • A function to create performance measurements.

If the measurement is initiated from the core, use the create_performance_measurement function within the utility function. Otherwise, use the function returned by the EdkiiPerformanceMeasurement protocol.


Initialization and Setup

Upon initialization, the component performs the following steps:

  1. Initialize the Firmware Performance Data Table (FBPT)

    • Sets up the FBPT data structure to store performance records.
  2. Populate FBPT with Pre-DXE Data

    • Retrieves performance data from Hand-Off Blocks (HOBs) generated during the pre-DXE phase and adds them to the FBPT.
  3. Install the EdkiiPerformanceMeasurement Protocol

    • Enables external modules to log performance data using the component API.
  4. Register Events

    • One event collects performance records logged in Management Mode (MM).
    • Another event publishes the FBPT to allocate the table in reserved memory at the end of the DXE phase.
  5. Install Performance Properties

    • Exposes performance-related properties through a configuration table for use by other components.

Scope and Limitations

This component only publishes the FBPT, as it specifically manages the additional record fields within it. Other tables, such as the Firmware Performance Data Table (FPDT), are published by separate components.