diff --git a/sw/nic/gpuagent/api/include/aga_gpu.hpp b/sw/nic/gpuagent/api/include/aga_gpu.hpp index 9c4d3ca2..3e38df3c 100644 --- a/sw/nic/gpuagent/api/include/aga_gpu.hpp +++ b/sw/nic/gpuagent/api/include/aga_gpu.hpp @@ -817,6 +817,10 @@ typedef struct aga_gpu_stats_s { aga_gpu_xgmi_link_stats_t xgmi_link_stats[AGA_GPU_MAX_XGMI_LINKS]; /// GPU violation statistics aga_gpu_violation_stats_t violation_stats; + /// UBB node power (in Watts), MI350X+ + uint64_t ubb_power; + /// UBB node power threshold/cap (in Watts), MI350X+ + uint64_t ubb_power_cap; } aga_gpu_stats_t; /// GPU info diff --git a/sw/nic/gpuagent/api/smi/amdsmi/smi_api.cc b/sw/nic/gpuagent/api/smi/amdsmi/smi_api.cc index 78b28108..9ba1df1e 100644 --- a/sw/nic/gpuagent/api/smi/amdsmi/smi_api.cc +++ b/sw/nic/gpuagent/api/smi/amdsmi/smi_api.cc @@ -1263,6 +1263,9 @@ smi_gpu_fill_stats (aga_gpu_handle_t gpu_handle, aga_gpu_stats_t *stats) { amdsmi_status_t amdsmi_ret; + amdsmi_npm_info_t npm_info = {}; + amdsmi_power_info_t power_info = {}; + amdsmi_node_handle node_handle = {}; uint64_t sent, received, max_pkt_size; amdsmi_gpu_metrics_t metrics_info = {}; amdsmi_gpu_metrics_t cached_metrics = {}; @@ -1276,6 +1279,18 @@ smi_gpu_fill_stats (aga_gpu_handle_t gpu_handle, // fill VRAM usage smi_fill_vram_usage_(gpu_handle, &stats->vram_usage); + // UBB node power + cap (MI350X+); decodes to 0 where unsupported + amdsmi_ret = amdsmi_get_power_info(gpu_handle, &power_info); + if (likely(amdsmi_ret == AMDSMI_STATUS_SUCCESS)) { + stats->ubb_power = power_info.ubb_power; + } + amdsmi_ret = amdsmi_get_node_handle(gpu_handle, &node_handle); + if (likely(amdsmi_ret == AMDSMI_STATUS_SUCCESS)) { + amdsmi_ret = amdsmi_get_npm_info(node_handle, &npm_info); + if (likely(amdsmi_ret == AMDSMI_STATUS_SUCCESS)) { + stats->ubb_power_cap = npm_info.ubb_power_threshold; + } + } // fill additional statistics from gpu metrics { std::lock_guard lock(g_gpu_metrics_mutex); diff --git a/sw/nic/gpuagent/api/smi/gimamdsmi/amd_smi_mock_impl.cc b/sw/nic/gpuagent/api/smi/gimamdsmi/amd_smi_mock_impl.cc index 631bbd9d..5cba535d 100644 --- a/sw/nic/gpuagent/api/smi/gimamdsmi/amd_smi_mock_impl.cc +++ b/sw/nic/gpuagent/api/smi/gimamdsmi/amd_smi_mock_impl.cc @@ -17,19 +17,17 @@ //---------------------------------------------------------------------------- /// /// \file -/// smi layer mock API definitions using amd-smi apis +/// smi layer mock API definitions using gim amd-smi apis /// //---------------------------------------------------------------------------- -#include "time.h" +#include #include "nic/sdk/include/sdk/base.hpp" +#include "nic/gpuagent/core/trace.hpp" #include "nic/gpuagent/api/smi/smi.hpp" #include "nic/gpuagent/api/smi/smi_api_mock_impl.hpp" #include "nic/gpuagent/api/smi/gimamdsmi/smi_utils.hpp" -/// global array of GPU handles -static aga_gpu_handle_t g_gpu_handles[AGA_MAX_GPU]; - namespace aga { aga_gpu_handle_t @@ -88,32 +86,16 @@ gpu_get_unique_id (uint32_t gpu_idx) void * event_get (void) { - static amdsmi_evt_notification_data_t event_ntfn_data; static uint8_t dev = 0; + static amdsmi_evt_notification_data_t event_ntfn_data; event_ntfn_data.processor_handle = g_gpu_handles[dev % AGA_MOCK_NUM_GPU]; - switch (dev%5) { - case 0: - event_ntfn_data.event = AMDSMI_EVT_NOTIF_RING_HANG; - break; - case 1: - event_ntfn_data.event = AMDSMI_EVT_NOTIF_GPU_POST_RESET; - break; - case 2: - event_ntfn_data.event = AMDSMI_EVT_NOTIF_GPU_PRE_RESET; - break; - case 3: - event_ntfn_data.event = AMDSMI_EVT_NOTIF_THERMAL_THROTTLE; - break; - case 4: - event_ntfn_data.event = AMDSMI_EVT_NOTIF_VMFAULT; - break; - default: - break; - } + // events range from 1 to AMDSMI_EVT_NOTIF_LAST + event_ntfn_data.event = + amdsmi_evt_notification_type_t((dev%AMDSMI_EVT_NOTIF_LAST) + 1); strncpy(event_ntfn_data.message, "test event", - MAX_EVENT_NOTIFICATION_MSG_SIZE); - dev++; + AMDSMI_MAX_STRING_LENGTH); + ++dev; return &event_ntfn_data; } diff --git a/sw/nic/gpuagent/api/smi/gimamdsmi/smi_api.cc b/sw/nic/gpuagent/api/smi/gimamdsmi/smi_api.cc index aacf5898..643d8fcd 100644 --- a/sw/nic/gpuagent/api/smi/gimamdsmi/smi_api.cc +++ b/sw/nic/gpuagent/api/smi/gimamdsmi/smi_api.cc @@ -24,6 +24,8 @@ #include #include #include +#include +#include extern "C" { #include "nic/third-party/rocm/gim_amd_smi_lib/include/amd_smi/amdsmi.h" } @@ -45,6 +47,8 @@ namespace aga { #define AMDSMI_UINT32_INVALID_VAL 0xffffffff #define AMDSMI_UINT64_INVALID_VAL 0xffffffffffffffff #define CPER_BUF_SIZE (4 * 1024 * 1024) // 4 MB +// max metric records a single gpu_metrics stream can carry (per amdsmi.h) +#define AGA_GIM_MAX_METRICS AMDSMI_MAX_NUM_METRICS /// \brief per-request session guard that ALSO refreshes the GPU handle /// from its stable gpu_key (UUID). In lazy_init mode, opens a @@ -620,6 +624,40 @@ smi_fill_pcie_status_ (aga_gpu_handle_t gpu_handle, return SDK_RET_OK; } +static sdk_ret_t +smi_get_gpu_metrics_stream (aga_gpu_handle_t gpu_handle, + amdsmi_metric_t *metrics_list, + uint32_t *metrics_count) +{ + amdsmi_status_t amdsmi_ret; + uint32_t count = AGA_GIM_MAX_METRICS; + + *metrics_count = 0; + amdsmi_ret = amdsmi_get_gpu_metrics(gpu_handle, &count, nullptr); + if (amdsmi_ret == AMDSMI_STATUS_INVAL) { + // GIM 8.7 fork rejects the null-buffer probe; fetch into the max buffer + count = AGA_GIM_MAX_METRICS; + } else if (amdsmi_ret != AMDSMI_STATUS_SUCCESS) { + AGA_TRACE_ERR("Failed to get gpu_metrics count for GPU {}, err {}", + gpu_handle, amdsmi_ret); + return amdsmi_ret_to_sdk_ret(amdsmi_ret); + } + if (count == 0) { + return SDK_RET_OK; + } + if (count > AGA_GIM_MAX_METRICS) { + count = AGA_GIM_MAX_METRICS; + } + amdsmi_ret = amdsmi_get_gpu_metrics(gpu_handle, &count, metrics_list); + if (unlikely(amdsmi_ret != AMDSMI_STATUS_SUCCESS)) { + AGA_TRACE_ERR("Failed to get gpu_metrics for GPU {}, err {}", + gpu_handle, amdsmi_ret); + return amdsmi_ret_to_sdk_ret(amdsmi_ret); + } + *metrics_count = count; + return SDK_RET_OK; +} + /// \brief fill VRAM status /// \param[in] gpu_handle GPU handle /// \param[out] status operational status to be filled @@ -630,6 +668,8 @@ smi_fill_vram_status_ (aga_gpu_handle_t gpu_handle, { amdsmi_vram_info_t info; amdsmi_status_t amdsmi_ret; + uint32_t metrics_count = 0; + amdsmi_metric_t metrics_list[AGA_GIM_MAX_METRICS]; aga_gpu_vram_status_t *vram_status = &status->vram_status; amdsmi_ret = amdsmi_get_gpu_vram_info(gpu_handle, &info); @@ -644,6 +684,17 @@ smi_fill_vram_status_ (aga_gpu_handle_t gpu_handle, AGA_MAX_STR_LEN); vram_status->size = info.vram_size; } + // max memory bandwidth (row 7) only comes via the gpu_metrics stream + vram_status->max_bandwidth = AMDSMI_UINT64_INVALID_VAL; + if (smi_get_gpu_metrics_stream(gpu_handle, metrics_list, + &metrics_count) == SDK_RET_OK) { + for (uint32_t i = 0; i < metrics_count; i++) { + if (metrics_list[i].name == AMDSMI_METRIC_NAME_MAX_DRAM_BANDWIDTH) { + vram_status->max_bandwidth = metrics_list[i].val; + break; + } + } + } return SDK_RET_OK; } @@ -869,7 +920,18 @@ sdk_ret_t smi_gpu_get_bad_page_count (void *gpu_obj, uint32_t *num_bad_pages) { - return SDK_RET_INVALID_OP; + amdsmi_status_t amdsmi_ret; + gpu_entry *gpu = (gpu_entry *)gpu_obj; + + // GIM 8.7 reports retired pages via the eeprom table; query count first + amdsmi_ret = amdsmi_get_gpu_bad_page_info(gpu->handle(), + num_bad_pages, NULL); + if (unlikely(amdsmi_ret != AMDSMI_STATUS_SUCCESS)) { + AGA_TRACE_ERR("Failed to get bad page information for GPU {}, err {}", + gpu->handle(), amdsmi_ret); + return amdsmi_ret_to_sdk_ret(amdsmi_ret); + } + return SDK_RET_OK; } /// \brief function to get GPU bad page records @@ -882,7 +944,137 @@ smi_gpu_get_bad_page_records (void *gpu_obj, uint32_t num_bad_pages, aga_gpu_bad_page_record_t *records) { - return SDK_RET_INVALID_OP; + amdsmi_status_t amdsmi_ret; + gpu_entry *gpu = (gpu_entry *)gpu_obj; + amdsmi_eeprom_table_record_t *bad_pages; + + bad_pages = + (amdsmi_eeprom_table_record_t *)malloc( + num_bad_pages * sizeof(amdsmi_eeprom_table_record_t)); + if (!bad_pages) { + AGA_TRACE_ERR("Failed to allocate memory for bad page information " + "for GPU {}", gpu->key().str()); + return SDK_RET_OOM; + } + amdsmi_ret = amdsmi_get_gpu_bad_page_info(gpu->handle(), &num_bad_pages, + bad_pages); + if (unlikely(amdsmi_ret != AMDSMI_STATUS_SUCCESS)) { + AGA_TRACE_ERR("Failed to get bad page information for GPU {}, err {}", + gpu->handle(), amdsmi_ret); + free(bad_pages); + return amdsmi_ret_to_sdk_ret(amdsmi_ret); + } + for (uint32_t i = 0; i < num_bad_pages; i++) { + records[i].key = gpu->key(); + // GIM eeprom record exposes only the retired page address; page + // size/status are not carried on the 8.7 host path + records[i].page_address = bad_pages[i].retired_page; + records[i].page_size = 0; + records[i].page_status = AGA_GPU_PAGE_STATUS_RESERVED; + } + free(bad_pages); + return SDK_RET_OK; +} + +/// \brief walk amdsmi_get_gpu_metrics() stream to populate VCN/JPEG/GFX +/// per-engine activity plus throttle/violation residency telemetry +/// \param[in] gpu_handle GPU handle +/// \param[out] stats stats struct whose usage/violation fields are filled +/// \return SDK_RET_OK or error code +static sdk_ret_t +smi_walk_gpu_metrics (aga_gpu_handle_t gpu_handle, aga_gpu_stats_t *stats) +{ + bool is_inst; + uint32_t idx; + sdk_ret_t ret; + uint32_t metrics_count = 0; + amdsmi_metric_t metrics_list[AGA_GIM_MAX_METRICS]; + aga_gpu_violation_stats_t *vs = &stats->violation_stats; + + // absent metrics stay at the 0xff sentinel so DME suppresses them + memset(vs, 0xff, sizeof(*vs)); + + ret = smi_get_gpu_metrics_stream(gpu_handle, metrics_list, &metrics_count); + if (ret != SDK_RET_OK) { + return ret; + } + + for (uint32_t i = 0; i < metrics_count; i++) { + auto &m = metrics_list[i]; + is_inst = (m.flags & AMDSMI_METRIC_TYPE_INST); + idx = m.res_instance; + + AGA_TRACE_VERBOSE("GPU {} metric name {} value {} flags {} instance {}", + gpu_handle, (int)m.name, (unsigned long)m.val, + m.flags, idx); + + switch (m.name) { + case AMDSMI_METRIC_NAME_USAGE_VCN: + if (idx < AGA_GPU_MAX_VCN) { + if (is_inst) + stats->usage.vcn_busy[idx] = (uint16_t)m.val; + else + stats->usage.vcn_activity[idx] = (uint16_t)m.val; + } + break; + case AMDSMI_METRIC_NAME_USAGE_JPEG: + if (is_inst) { + if (idx < AGA_GPU_MAX_JPEG_ENG) + stats->usage.jpeg_busy[idx] = (uint16_t)m.val; + } else { + if (idx < AGA_GPU_MAX_JPEG) + stats->usage.jpeg_activity[idx] = (uint16_t)m.val; + } + break; + case AMDSMI_METRIC_NAME_USAGE_GFX: + if (is_inst && idx < AGA_GPU_MAX_XCC) + stats->usage.gfx_busy_inst[idx] = (uint32_t)m.val; + break; + case AMDSMI_METRIC_NAME_USAGE_MM: + break; + // throttle/violation residency (rows 10-20). the GIM stream exposes + // accumulated counters only; per_* percentages are not available and + // are left at the sentinel (never derived) so DME suppresses them. + case AMDSMI_METRIC_NAME_METRIC_ACC_COUNTER: + vs->current_accumulated_counter = m.val; + break; + case AMDSMI_METRIC_NAME_THROTTLE_SOCKET_ACTIVE: + vs->socket_thermal_residency_accumulated = m.val; + break; + case AMDSMI_METRIC_NAME_THROTTLE_VR_ACTIVE: + vs->vr_thermal_residency_accumulated = m.val; + break; + case AMDSMI_METRIC_NAME_THROTTLE_MEM_ACTIVE: + vs->hbm_thermal_residency_accumulated = m.val; + break; + case AMDSMI_METRIC_NAME_THROTTLE_PROCHOT_ACTIVE: + vs->processor_hot_residency_accumulated = m.val; + break; + case AMDSMI_METRIC_NAME_THROTTLE_PPT_ACTIVE: + vs->ppt_residency_accumulated = m.val; + break; + case AMDSMI_METRIC_NAME_GFX_CLK_BELOW_HOST_LIMIT_PPT: + if (idx < AGA_GPU_MAX_XCC) + vs->gfx_clk_below_host_limit_power_accumulated[idx] = m.val; + break; + case AMDSMI_METRIC_NAME_GFX_CLK_BELOW_HOST_LIMIT_THM: + if (idx < AGA_GPU_MAX_XCC) + vs->gfx_clk_below_host_limit_thermal_accumulated[idx] = m.val; + break; + case AMDSMI_METRIC_NAME_GFX_CLK_BELOW_HOST_LIMIT_TOTAL: + if (idx < AGA_GPU_MAX_XCC) + vs->gfx_clk_below_host_limit_total_accumulated[idx] = m.val; + break; + case AMDSMI_METRIC_NAME_GFX_CLK_LOW_UTILIZATION: + if (idx < AGA_GPU_MAX_XCC) + vs->gfx_low_utilization_accumulated[idx] = m.val; + break; + default: + break; + } + } + + return SDK_RET_OK; } sdk_ret_t @@ -896,8 +1088,10 @@ smi_gpu_fill_stats (aga_gpu_handle_t gpu_handle_in, sdk_ret_t ret; int64_t temperature; amdsmi_status_t amdsmi_ret; + amdsmi_npm_info_t npm_info = {}; amdsmi_pcie_info_t pcie_info = {}; amdsmi_power_info_t power_info = {}; + amdsmi_node_handle node_handle = {}; amdsmi_engine_usage_t usage_info = {}; AGA_SMI_SESSION_GUARD(gpu_key, gpu_handle_in); @@ -913,6 +1107,14 @@ smi_gpu_fill_stats (aga_gpu_handle_t gpu_handle_in, stats->voltage.gfx_voltage = power_info.gfx_voltage; stats->voltage.memory_voltage = power_info.mem_voltage; } + // UBB node power cap = node-level power limit (npm); 0 where unsupported + amdsmi_ret = amdsmi_get_node_handle(gpu_handle, &node_handle); + if (likely(amdsmi_ret == AMDSMI_STATUS_SUCCESS)) { + amdsmi_ret = amdsmi_get_npm_info(node_handle, &npm_info); + if (likely(amdsmi_ret == AMDSMI_STATUS_SUCCESS)) { + stats->ubb_power_cap = npm_info.limit; + } + } // fill the GPU usage amdsmi_ret = amdsmi_get_gpu_activity(gpu_handle, &usage_info); if (unlikely(amdsmi_ret != AMDSMI_STATUS_SUCCESS)) { @@ -923,6 +1125,8 @@ smi_gpu_fill_stats (aga_gpu_handle_t gpu_handle_in, stats->usage.mm_activity = usage_info.mm_activity; stats->usage.gfx_activity = usage_info.gfx_activity; } + // fill VCN/JPEG/instantaneous activity from gpu_metrics stream + smi_walk_gpu_metrics(gpu_handle, stats); // fill the PCIe stats amdsmi_ret = amdsmi_get_pcie_info(gpu_handle, &pcie_info); if (unlikely(amdsmi_ret != AMDSMI_STATUS_SUCCESS)) { diff --git a/sw/nic/gpuagent/protos/gpu.proto b/sw/nic/gpuagent/protos/gpu.proto index b0310dc9..86c9cbc3 100644 --- a/sw/nic/gpuagent/protos/gpu.proto +++ b/sw/nic/gpuagent/protos/gpu.proto @@ -795,6 +795,10 @@ message GPUStats { uint64 IHDeferredErrors = 87; // MPIO deferred errors uint64 MPIODeferredErrors = 88; + // UBB node power (in Watts), MI350X+ + uint64 UbbPower = 89; + // UBB node power threshold (in Watts), MI350X+ + uint64 UbbPowerCap = 90; } // GPU captures config, operational status and stat of GPU object diff --git a/sw/nic/gpuagent/svc/gpu_to_proto.hpp b/sw/nic/gpuagent/svc/gpu_to_proto.hpp index e8b88708..329ae3a5 100644 --- a/sw/nic/gpuagent/svc/gpu_to_proto.hpp +++ b/sw/nic/gpuagent/svc/gpu_to_proto.hpp @@ -691,6 +691,8 @@ aga_gpu_api_stats_to_proto (GPUStats *proto_stats, &stats->vram_usage); proto_stats->set_energyconsumed(stats->energy_consumed); proto_stats->set_powerusage(stats->power_usage); + proto_stats->set_ubbpower(stats->ubb_power); + proto_stats->set_ubbpowercap(stats->ubb_power_cap); proto_stats->set_totalcorrectableerrors(stats->total_correctable_errors); proto_stats->set_totaluncorrectableerrors( stats->total_uncorrectable_errors); diff --git a/sw/nic/third-party/rocm/gim_amd_smi_lib/include/amd_smi/amdsmi.h b/sw/nic/third-party/rocm/gim_amd_smi_lib/include/amd_smi/amdsmi.h index 40cbbddf..72fcb384 100644 --- a/sw/nic/third-party/rocm/gim_amd_smi_lib/include/amd_smi/amdsmi.h +++ b/sw/nic/third-party/rocm/gim_amd_smi_lib/include/amd_smi/amdsmi.h @@ -28,11 +28,15 @@ * @brief AMD System Management Interface API */ -#ifndef __KERNEL__ +#ifdef __cplusplus +#include +extern "C" { +#else #include +#endif + #include #include -#endif /** * @brief Initialization flags @@ -47,8 +51,9 @@ typedef enum { AMDSMI_INIT_AMD_GPUS = (1 << 1), //!< Initialize AMD GPUS AMDSMI_INIT_NON_AMD_CPUS = (1 << 2), //!< Initialize Non-AMD CPUS AMDSMI_INIT_NON_AMD_GPUS = (1 << 3), //!< Initialize Non-AMD GPUS - AMDSMI_INIT_AMD_APUS = (AMDSMI_INIT_AMD_CPUS | AMDSMI_INIT_AMD_GPUS) /**< Initialize AMD CPUS and GPUS + AMDSMI_INIT_AMD_APUS = (AMDSMI_INIT_AMD_CPUS | AMDSMI_INIT_AMD_GPUS), /**< Initialize AMD CPUS and GPUS (Default option) */ + AMDSMI_INIT_AMD_NICS = (1 << 4) //!< Initialize AMD NICS } amdsmi_init_flags_t; /** @@ -59,6 +64,24 @@ typedef enum { typedef void *amdsmi_processor_handle; typedef void *amdsmi_socket_handle; +/** + * @brief Processor types detectable by AMD SMI + * + * @cond @tag{gpu_bm_linux} @tag{host} @tag{cpu_bm} @tag{guest_windows} @endcond + */ +typedef enum { + AMDSMI_PROCESSOR_TYPE_UNKNOWN = 0, //!< Unknown processor type + AMDSMI_PROCESSOR_TYPE_AMD_GPU, //!< AMD Graphics processor type + AMDSMI_PROCESSOR_TYPE_AMD_CPU, //!< AMD CPU processor type, a physical component that holds the CPU + AMDSMI_PROCESSOR_TYPE_NON_AMD_GPU, //!< Non-AMD Graphics processor type + AMDSMI_PROCESSOR_TYPE_NON_AMD_CPU, //!< Non-AMD CPU processor type + AMDSMI_PROCESSOR_TYPE_AMD_CPU_CORE, //!< AMD CPU-Core processor type, individual processing units within the CPU + AMDSMI_PROCESSOR_TYPE_AMD_APU, //!< AMD Accelerated processor type, GPU and CPU on a single die + AMDSMI_PROCESSOR_TYPE_AMD_NIC, //!< AMD Network Interface Card processor type + AMDSMI_PROCESSOR_TYPE_BRCM_NIC, //!< Broadcom Network Interface Card processor type + AMDSMI_PROCESSOR_TYPE_BRCM_SWITCH //!< Broadcom Switch processor type +} processor_type_t; + /** * @brief Error codes returned by amdsmi functions * @@ -121,26 +144,6 @@ typedef enum { AMDSMI_STATUS_UNKNOWN_ERROR = 0xFFFFFFFF, //!< An unknown error occurred } amdsmi_status_t; -/** - * @brief Processor types detectable by AMD SMI - * - * AMDSMI_PROCESSOR_TYPE_AMD_CPU - CPU Socket is a physical component that holds the CPU. - * AMDSMI_PROCESSOR_TYPE_AMD_CPU_CORE - CPU Cores are number of individual processing units within the CPU. - * AMDSMI_PROCESSOR_TYPE_AMD_APU - Combination of AMDSMI_PROCESSOR_TYPE_AMD_CPU and integrated GPU on single die - * AMDSMI_PROCESSOR_TYPE_AMD_NIC - Network Interface Card - * @cond @tag{gpu_bm_linux} @tag{host} @tag{cpu_bm} @tag{guest_windows} @endcond - */ -typedef enum { - AMDSMI_PROCESSOR_TYPE_UNKNOWN = 0, //!< Unknown processor type - AMDSMI_PROCESSOR_TYPE_AMD_GPU, //!< AMD Graphics processor type - AMDSMI_PROCESSOR_TYPE_AMD_CPU, //!< AMD CPU processor type - AMDSMI_PROCESSOR_TYPE_NON_AMD_GPU, //!< Non-AMD Graphics processor type - AMDSMI_PROCESSOR_TYPE_NON_AMD_CPU, //!< Non-AMD CPU processor type - AMDSMI_PROCESSOR_TYPE_AMD_CPU_CORE, //!< AMD CPU-Core processor type - AMDSMI_PROCESSOR_TYPE_AMD_APU, //!< AMD Accelerated processor type (GPU and CPU) - AMDSMI_PROCESSOR_TYPE_AMD_NIC //!< AMD Network Interface Card processor type -} processor_type_t; - /** * @brief Common defines * @@ -186,6 +189,7 @@ typedef enum { #define AMDSMI_MAX_TA_WHITE_LIST_ELEMENTS 8 //!< Maximum number of TA (Trusted Application) white list elements #define AMDSMI_MAX_ERR_RECORDS 10 //!< Maximum number of error records that can be stored #define AMDSMI_MAX_PROFILE_COUNT 16 //!< Maximum number of profiles supported +#define AMDSMI_MAX_NUM_FREQUENCIES 33 //!< Guaranteed maximum possible number of supported frequencies /** * @brief String format @@ -261,6 +265,7 @@ typedef enum { AMDSMI_VRAM_TYPE_DDR2 = 10, //!< Double Data Rate, Generation 2 AMDSMI_VRAM_TYPE_DDR3 = 11, //!< Double Data Rate, Generation 3 AMDSMI_VRAM_TYPE_DDR4 = 12, //!< Double Data Rate, Generation 4 + AMDSMI_VRAM_TYPE_DDR5 = 13, //!< Double Data Rate, Generation 5 // GDDR AMDSMI_VRAM_TYPE_GDDR1 = 17, //!< Graphics Double Data Rate, Generation 1 AMDSMI_VRAM_TYPE_GDDR2 = 18, //!< Graphics Double Data Rate, Generation 2 @@ -269,7 +274,10 @@ typedef enum { AMDSMI_VRAM_TYPE_GDDR5 = 21, //!< Graphics Double Data Rate, Generation 5 AMDSMI_VRAM_TYPE_GDDR6 = 22, //!< Graphics Double Data Rate, Generation 6 AMDSMI_VRAM_TYPE_GDDR7 = 23, //!< Graphics Double Data Rate, Generation 7 - AMDSMI_VRAM_TYPE__MAX = AMDSMI_VRAM_TYPE_GDDR7 + // LPDDR + AMDSMI_VRAM_TYPE_LPDDR4 = 30, //!< Low Power Double Data Rate, Generation 4 + AMDSMI_VRAM_TYPE_LPDDR5 = 31, //!< Low Power Double Data Rate, Generation 5 + AMDSMI_VRAM_TYPE__MAX = AMDSMI_VRAM_TYPE_LPDDR5 } amdsmi_vram_type_t; /** @@ -648,6 +656,8 @@ typedef enum { AMDSMI_PTL_DATA_FORMAT_BF16 = 0x2, //!< Brain Float 16-bit format AMDSMI_PTL_DATA_FORMAT_F32 = 0x3, //!< Float 32-bit format AMDSMI_PTL_DATA_FORMAT_F64 = 0x4, //!< Float 64-bit format + AMDSMI_PTL_DATA_FORMAT_F8 = 0x5, //!< Float 8-bit format + AMDSMI_PTL_DATA_FORMAT_VECTOR = 0x6, //!< Vector format AMDSMI_PTL_DATA_FORMAT_INVALID = 0xFFFFFFFF //!< Invalid format } amdsmi_ptl_data_format_t; @@ -659,15 +669,15 @@ typedef enum { typedef union { struct bdf_ { uint64_t function_number : 3; - uint64_t device_number : 5; - uint64_t bus_number : 8; - uint64_t domain_number : 48; + uint64_t device_number : 5; + uint64_t bus_number : 8; + uint64_t domain_number : 48; } bdf; struct { uint64_t function_number : 3; - uint64_t device_number : 5; - uint64_t bus_number : 8; - uint64_t domain_number : 48; + uint64_t device_number : 5; + uint64_t bus_number : 8; + uint64_t domain_number : 48; }; uint64_t as_uint; } amdsmi_bdf_t; @@ -701,6 +711,33 @@ typedef struct { uint64_t reserved[32]; } amdsmi_pcie_info_t; +/** + * @brief This structure holds information about clock frequencies. + * + * @cond @tag{gpu_bm_linux} @tag{host} @endcond + */ +typedef struct { + bool has_deep_sleep; //!< Deep Sleep frequency is only supported by some GPUs + uint32_t num_supported; //!< The number of supported frequencies + uint32_t current; //!< The current frequency index in MHz + uint64_t frequency[AMDSMI_MAX_NUM_FREQUENCIES]; /**< List of frequencies in MHz. + Only the first num_supported frequencies are valid */ +} amdsmi_frequencies_t; + +/** + * @brief This structure holds information about the possible PCIe + * bandwidths. Specifically, the possible transfer rates and their + * associated numbers of lanes are stored here. + * + * Only the first num_supported bandwidths are valid. + * + * @cond @tag{gpu_bm_linux} @tag{host} @endcond + */ +typedef struct { + amdsmi_frequencies_t transfer_rate; //!< Transfer rates (T/s) that are possible + uint32_t lanes[AMDSMI_MAX_NUM_FREQUENCIES]; //!< List of lanes for corresponding transfer rate. +} amdsmi_pcie_bandwidth_t; + /** * @brief Link Metrics * @@ -735,6 +772,16 @@ typedef struct { uint64_t reserved[3]; } amdsmi_power_cap_info_t; +/** + * @brief Power Cap Package Power Tracking (PPT) type + * + * @cond @tag{gpu_bm_linux} @tag{host} @endcond + */ +typedef enum { + AMDSMI_POWER_CAP_TYPE_PPT0, //!< PPT0 power cap; lower limit, filtered input + AMDSMI_POWER_CAP_TYPE_PPT1, //!< PPT1 power cap; higher limit, raw input +} amdsmi_power_cap_type_t; + /** * @brief VBios Information * @@ -762,20 +809,23 @@ typedef struct { uint64_t device_id; //!< The device ID of a GPU uint32_t rev_id; //!< The revision ID of a GPU char asic_serial[AMDSMI_MAX_STRING_LENGTH]; - uint32_t oam_id; //!< 0xFFFFFFFF if not supported + uint32_t oam_id; //!< Corresponds to socket number, 0xFFFFFFFF if not supported uint32_t num_of_compute_units; //!< 0xFFFFFFFF if not supported uint64_t target_graphics_version; //!< 0xFFFFFFFFFFFFFFFF if not supported - uint32_t subsystem_id; //!> The subsystem ID - uint32_t reserved[21]; + uint32_t subsystem_id; //!< The subsystem ID + uint64_t flags; //!< Chip flags + uint32_t reserved[18]; } amdsmi_asic_info_t; /** * @brief Power Information * + * @note Unsupported struct members are set to UINT32_MAX + * * @cond @tag{gpu_bm_linux} @tag{host} @tag{guest_windows} @endcond */ typedef struct { - uint64_t socket_power; //!< Socket power in W {@linux_bm}, uW {@host} + uint64_t socket_power; //!< Current power usage in W {@linux_bm}, uW {@host} uint32_t current_socket_power; //!< Current socket power in W {@linux_bm}, Linux only, Mi 300+ Series cards uint32_t average_socket_power; //!< Average socket power in W {@linux_bm}, Linux only, Navi + Mi 200 and earlier Series cards uint64_t gfx_voltage; //!< GFX voltage measurement in mV {@linux_bm} or V {@host} @@ -859,7 +909,7 @@ typedef struct { * @cond @tag{gpu_bm_linux} @tag{host} @endcond */ typedef union { - struct nps_flags_{ + struct nps_flags_ { uint32_t nps1_cap :1; //!< bool 1 = true; 0 = false uint32_t nps2_cap :1; //!< bool 1 = true; 0 = false uint32_t nps4_cap :1; //!< bool 1 = true; 0 = false @@ -879,7 +929,7 @@ typedef struct { amdsmi_nps_caps_t partition_caps; amdsmi_memory_partition_type_t mp_mode; uint32_t num_numa_ranges; - struct numa_range_{ + struct numa_range_ { amdsmi_vram_type_t memory_type; uint64_t start; uint64_t end; @@ -993,7 +1043,7 @@ typedef struct { */ typedef struct { uint8_t num_fw_info; - struct { + struct fw_info_list_ { amdsmi_fw_block_t fw_id; uint64_t fw_version; uint64_t reserved[2]; @@ -1027,22 +1077,21 @@ typedef struct { /** * @brief This structure holds ras feature information. * - * @cond @tag{gpu_bm_linux} @platform{guest_windows} @tag{host} @endcond + * @cond @tag{gpu_bm_linux} @tag{guest_windows} @tag{host} @endcond */ typedef struct { - struct { - uint32_t dram_ecc : 1; - uint32_t sram_ecc : 1; - uint32_t poisoning : 1; - uint32_t rsvd : 29; - } ras_info; - bool needs_reboot; uint32_t ras_eeprom_version; /**< PARITY error(bit 0), Single Bit correctable (bit1), Double bit error detection (bit2), Poison (bit 3). */ uint32_t ecc_correction_schema_flag; /**< ecc_correction_schema mask. PARITY error(bit 0), Single Bit correctable (bit1), Double bit error detection (bit2), Poison (bit 3) */ - uint32_t reserved[4]; + struct ras_info_ { + uint32_t dram_ecc : 1; + uint32_t sram_ecc : 1; + uint32_t poisoning : 1; + uint32_t rsvd : 29; + } ras_info; + bool needs_reboot; } amdsmi_ras_feature_t; /** @@ -1097,7 +1146,7 @@ typedef struct { typedef struct { uint8_t major_version; uint8_t minor_version; - union { + union policy_data_ { amdsmi_gpu_ras_policy_v4_0_t v4_0; uint64_t info[5]; //!< total size of the EEPROM that can be used by the policy is 40bytes } policy_data; @@ -1866,6 +1915,7 @@ typedef enum { AMDSMI_METRIC_CATEGORY_SYS_ACC_COUNTER, AMDSMI_METRIC_CATEGORY_SYS_BASEBOARD_TEMP, AMDSMI_METRIC_CATEGORY_SYS_GPUBOARD_TEMP, + AMDSMI_METRIC_CATEGORY_SYS_BASEBOARD_POWER, AMDSMI_METRIC_CATEGORY_UNKNOWN } amdsmi_metric_category_t; @@ -1912,6 +1962,8 @@ typedef enum { AMDSMI_METRIC_NAME_THROTTLE_SOCKET_ACTIVE, AMDSMI_METRIC_NAME_THROTTLE_VR_ACTIVE, AMDSMI_METRIC_NAME_THROTTLE_MEM_ACTIVE, + AMDSMI_METRIC_NAME_THROTTLE_PROCHOT_ACTIVE, + AMDSMI_METRIC_NAME_THROTTLE_PPT_ACTIVE, AMDSMI_METRIC_NAME_PCIE_BANDWIDTH, AMDSMI_METRIC_NAME_PCIE_L0_TO_RECOVERY_COUNT, @@ -1999,6 +2051,8 @@ typedef enum { AMDSMI_METRIC_NAME_VR_TEMP_VDDCR_11_HBM_D, AMDSMI_METRIC_NAME_VR_TEMP_VDD_USR, AMDSMI_METRIC_NAME_VR_TEMP_VDDIO_11_E32, + AMDSMI_METRIC_NAME_SYSTEM_POWER_UBB_POWER, + AMDSMI_METRIC_NAME_SYSTEM_POWER_UBB_POWER_THRESHOLD, AMDSMI_METRIC_NAME_UNKNOWN } amdsmi_metric_name_t; @@ -2459,6 +2513,19 @@ typedef struct { #define AMDSMI_MAX_NIC_RDMA_DEV 32 //!< Maximum number of NIC RDMA devices #define AMDSMI_MAX_NIC_FW 16 //!< Maximum number of NIC firmwares +/** + * @brief NIC Link Types. This enum is used to identify the link type between + * NIC and GPU processors based on their PCIe and NUMA connectivity. + * + * @cond @tag{gpu_bm_linux} @tag{host} @endcond + */ +typedef enum { + AMDSMI_NIC_LINK_TYPE_UNKNOWN, //!< unknown type. + AMDSMI_NIC_LINK_TYPE_PCIE, //!< two processors connect via same PCIe + AMDSMI_NIC_LINK_TYPE_NUMA, //!< two processors connect via different PCIe switches but on the same CPU + AMDSMI_NIC_LINK_TYPE_X_NUMA, //!< two processors connect via different PCIe switches but on different CPUs + } amdsmi_nic_link_type_t; + /** * @brief Structure for NIC statistic name-value pairs * @@ -2630,6 +2697,7 @@ typedef struct { uint8_t num_rdma_dev; amdsmi_nic_rdma_dev_info_t rdma_dev_info[AMDSMI_MAX_NIC_RDMA_DEV]; } amdsmi_nic_rdma_devices_info_t; + /*****************************************************************************/ /** @defgroup tagInitShutdown Initialization and Shutdown * @{ @@ -2685,45 +2753,59 @@ amdsmi_status_t amdsmi_shut_down(void); */ /** - * @brief Get the processor type of the processor_handle + * @brief Returns a list of processor handles of the specified type in the system. * * @ingroup tagProcDiscovery * - * @platform{gpu_bm_linux} @platform{host} @platform{cpu_bm} @platform{guest_1vf} - * @platform{guest_mvf} @platform{guest_windows} + * @platform{host} @platform{gpu_bm_linux} @platform{cpu_bm} * - * @details This function retrieves the processor type. A processor_handle must be provided - * for that processor. + * @details This function retrieves processor list as per the processor type + * from the total processor handles list. + * The @p list of processor_handles and processor type must be provided. * - * @param[in] processor_handle a processor handle + * @note This function fills the user-provided buffer with processor handles of the given type + * (e.g., GPU, NIC). The processor handles returned are used to instantiate the rest of processor + * queries in the library. If the buffer is not large enough, the call will fail. * - * @param[out] processor_type a pointer to ::processor_type_t to which the processor type - * will be written. If this parameter is nullptr, this function will return - * ::AMDSMI_STATUS_INVAL. + * @param[in] socket_handle The socket to query. + * + * @param[in] processor_type The type of processor to query (see ::processor_type_t). + * + * @param[out] processor_handles Reference to list of processor handles returned by + * the library. Buffer must be allocated by user. + * + * @param[in,out] processor_count As input, the size of the provided buffer. + * As output, number of processor handles in the buffer. + * Parameter must be allocated by user. * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_get_processor_type(amdsmi_processor_handle processor_handle, - processor_type_t *processor_type); +amdsmi_status_t amdsmi_get_processor_handles_by_type(amdsmi_socket_handle socket_handle, + processor_type_t processor_type, + amdsmi_processor_handle *processor_handles, + uint32_t *processor_count); /** - * @brief Returns the processor handle from the given processor index + * @brief Get the processor type of the processor_handle * * @ingroup tagProcDiscovery * * @platform{gpu_bm_linux} @platform{host} @platform{cpu_bm} @platform{guest_1vf} * @platform{guest_mvf} @platform{guest_windows} * - * @param[in] processor_index Function processor_index to query + * @details This function retrieves the processor type. A processor_handle must be provided + * for that processor. * - * @note On the @platform{host} this function currently supports only AMD GPU indexes. + * @param[in] processor_handle a processor handle * - * @param[out] processor_handle Reference to the processor handle. - * Must be allocated by user. + * @param[out] processor_type a pointer to ::processor_type_t to which the processor type + * will be written. If this parameter is nullptr, this function will return + * ::AMDSMI_STATUS_INVAL. * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_get_processor_handle_from_index(uint32_t processor_index, amdsmi_processor_handle *processor_handle); +amdsmi_status_t amdsmi_get_processor_type(amdsmi_processor_handle processor_handle, + processor_type_t *processor_type); /** * @brief Get the list of socket handles in the system. @@ -2758,23 +2840,6 @@ amdsmi_status_t amdsmi_get_processor_handle_from_index(uint32_t processor_index, */ amdsmi_status_t amdsmi_get_socket_handles(uint32_t *socket_count, amdsmi_socket_handle *socket_handles); -/** - * @brief Returns the index of the given processor handle - * - * @ingroup tagProcDiscovery - * - * @platform{gpu_bm_linux} @platform{host} @platform{cpu_bm} @platform{guest_1vf} - * @platform{guest_mvf} @platform{guest_windows} - * - * @param[in] processor_handle Processor handle for which to query - * - * @param[out] processor_index Pointer to integer to store the processor index. Must be - * allocated by user. - * - * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail - */ -amdsmi_status_t amdsmi_get_index_from_processor_handle(amdsmi_processor_handle processor_handle, uint32_t *processor_index); - /** * @brief Get the list of the processor handles associated to a socket. * @@ -2789,7 +2854,7 @@ amdsmi_status_t amdsmi_get_index_from_processor_handle(amdsmi_processor_handle p * Currently, only AMD GPUs are supported. * * @note Sockets are not supported on the @platform{host}. - * + * * @note On the @platform{host} this function currently supports only AMD GPUs. To enumerate other devices, * such as AMD NICs, use amdsmi_get_processor_handles_by_type(). * @@ -2868,7 +2933,7 @@ amdsmi_status_t amdsmi_get_processor_handle_from_bdf(amdsmi_bdf_t bdf, amdsmi_pr * @platform{gpu_bm_linux} @platform{host} @platform{guest_1vf} @platform{guest_mvf} * @platform{guest_windows} * - * @param[in] processor_handle Device which to query + * @param[in] processor_handle Device which to query * * @param[out] bdf Reference to BDF. Must be allocated by user. * @@ -2876,38 +2941,6 @@ amdsmi_status_t amdsmi_get_processor_handle_from_bdf(amdsmi_bdf_t bdf, amdsmi_pr */ amdsmi_status_t amdsmi_get_gpu_device_bdf(amdsmi_processor_handle processor_handle, amdsmi_bdf_t *bdf); -/** - * @brief Returns BDF of the given device - * - * @ingroup tagProcDiscovery - * - * @platform{gpu_bm_linux} @platform{host} @platform{guest_1vf} @platform{guest_mvf} - * @platform{guest_windows} - * - * @param[in] processor_handle Device which to query - * - * @param[out] bdf Reference to BDF. Must be allocated by user. - * - * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail - */ -amdsmi_status_t amdsmi_get_processor_bdf(amdsmi_processor_handle processor_handle, amdsmi_bdf_t *bdf); - -/** - * @brief Returns the processor handle from the given UUID - * - * @ingroup tagProcDiscovery - * - * @platform{gpu_bm_linux} @platform{host} @platform{guest_windows} - * - * @param[in] uuid Function UUID to query. - * - * @param[out] processor_handle Reference to the processor handle. - * Must be allocated by user. - * - * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail - */ -amdsmi_status_t amdsmi_get_processor_handle_from_uuid(const char *uuid, amdsmi_processor_handle *processor_handle); - /** * @brief Returns the UUID of the device * @@ -2934,7 +2967,7 @@ amdsmi_status_t amdsmi_get_gpu_device_uuid(amdsmi_processor_handle processor_han * * @ingroup tagProcDiscovery * - * @platform{gpu_bm_linux} @platform{guest_1vf} @platform{host} @platform{guest_windows} + * @platform{gpu_bm_linux} @platform{host} @platform{guest_windows} * * @details The virtualization mode is detected and returned as an enum. * @@ -2987,16 +3020,82 @@ amdsmi_status_t amdsmi_get_cpu_affinity_with_scope(amdsmi_processor_handle proce * @p processor_handle must be provided for the processor. * Currently, only AMD GPUs are supported. * - * @param[in] processor_handle A pointer to a ::amdsmi_processor_handle values - * will be written. + * @param[in] processor_handle A pointer to a ::amdsmi_processor_handle, this + * is required to be OAM ID 0 otherwise the API will fail. OAM ID is sourced + * from amdsmi_get_gpu_asic_info API. * - * @param[out] amdsmi_node_handle* A pointer to a block of memory where amdsmi_node_handle + * @param[out] node_handle A pointer to a block of memory where amdsmi_node_handle * will be written. * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ amdsmi_status_t amdsmi_get_node_handle(amdsmi_processor_handle processor_handle, amdsmi_node_handle *node_handle); +/** + * @brief Returns the index of the given processor handle + * + * @ingroup tagProcDiscovery + * + * @platform{host} @platform{guest_1vf} @platform{guest_mvf} @platform{guest_windows} + * + * @param[in] processor_handle Processor handle for which to query + * + * @param[out] processor_index Pointer to integer to store the processor index. Must be + * allocated by user. + * + * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail + */ +amdsmi_status_t amdsmi_get_index_from_processor_handle(amdsmi_processor_handle processor_handle, uint32_t *processor_index); + +/** + * @brief Returns the processor handle from the given processor index + * + * @ingroup tagProcDiscovery + * + * @platform{host} @platform{guest_1vf} @platform{guest_mvf} @platform{guest_windows} + * + * @param[in] processor_index Function processor_index to query + * + * @note On the @platform{host} this function currently supports only AMD GPU indexes. + * + * @param[out] processor_handle Reference to the processor handle. + * Must be allocated by user. + * + * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail + */ +amdsmi_status_t amdsmi_get_processor_handle_from_index(uint32_t processor_index, amdsmi_processor_handle *processor_handle); + +/** + * @brief Returns BDF of the given device + * + * @ingroup tagProcDiscovery + * + * @platform{host} @platform{guest_1vf} @platform{guest_mvf} @platform{guest_windows} + * + * @param[in] processor_handle Device which to query + * + * @param[out] bdf Reference to BDF. Must be allocated by user. + * + * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail + */ +amdsmi_status_t amdsmi_get_processor_bdf(amdsmi_processor_handle processor_handle, amdsmi_bdf_t *bdf); + +/** + * @brief Returns the processor handle from the given UUID + * + * @ingroup tagProcDiscovery + * + * @platform{host} @platform{guest_windows} + * + * @param[in] uuid Function UUID to query. + * + * @param[out] processor_handle Reference to the processor handle. + * Must be allocated by user. + * + * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail + */ +amdsmi_status_t amdsmi_get_processor_handle_from_uuid(const char *uuid, amdsmi_processor_handle *processor_handle); + /** * @brief Returns VF handle from the given BDF * @@ -3082,46 +3181,58 @@ amdsmi_status_t amdsmi_get_vf_bdf(amdsmi_vf_handle_t vf_handle, amdsmi_bdf_t *bd amdsmi_status_t amdsmi_get_vf_uuid(amdsmi_vf_handle_t processor_handle, unsigned int *uuid_length, char *uuid); /** - * @brief Returns BDF of the given NIC device + * @brief Get the list of the NIC processor handles associated to a socket. * * @ingroup tagProcDiscovery * - * @platform{gpu_bm_linux} @platform{host} @platform{guest_1vf} @platform{guest_mvf} - * @platform{guest_windows} + * @platform{gpu_bm_linux} @platform{host} * - * @param[in] processor_handle Device which to query + * @details This function retrieves the processor handles of a socket. The + * @p socket_handle must be provided for the processor. * - * @param[out] bdf Reference to BDF. Must be allocated by user. + * @note Sockets are not supported on the @platform{host}. + * + * The number of processor count is returned through @p processor_count + * if @p processor_handles is NULL. Then the number of @p processor_count can be pass + * as input to retrieval all processors on the socket to @p processor_handles. + * + * @param[in] socket_handle The socket to query + * + * @param[in,out] processor_count As input, the value passed + * through this parameter is the number of ::amdsmi_processor_handle's that + * may be safely written to the memory pointed to by @p processor_handles. This is the + * limit on how many processor handles will be written to @p processor_handles. On return, @p + * processor_count will contain the number of processor handles written to @p processor_handles, + * or the number of processor handles that could have been written if enough memory had been + * provided. + * If @p processor_handles is NULL, as output, @p processor_count will contain + * how many processors are available to read for the socket. + * + * @param[in,out] processor_handles A pointer to a block of memory to which the + * ::amdsmi_processor_handle values will be written. This value may be NULL. + * In this case, this function can be used to query how many processors are + * available to read. * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_get_nic_device_bdf(amdsmi_processor_handle processor_handle, amdsmi_bdf_t *bdf); +amdsmi_status_t amdsmi_get_nic_processor_handles(amdsmi_socket_handle socket_handle, + uint32_t *processor_count, + amdsmi_processor_handle *processor_handles); + /** - * @brief Returns a list of processor handles of the specified type in the system. - * - * @platform{host} @platform{gpu_bm_linux} @platform{cpu_bm} - * - * @note This function fills the user-provided buffer with processor handles of the given type - * (e.g., GPU, NIC). The processor handles returned are used to instantiate the rest of processor - * queries in the library. If the buffer is not large enough, the call will fail. + * @brief Returns BDF of the given NIC device * - * @param[in] socket_handle The socket to query. + * @ingroup tagProcDiscovery * - * @param[in] processor_type The type of processor to query (see ::processor_type_t). + * @platform{gpu_bm_linux} @platform{host} * - * @param[out] processor_handles Reference to list of processor handles returned by - * the library. Buffer must be allocated by user. + * @param[in] processor_handle Device which to query * - * @param[in,out] processor_count As input, the size of the provided buffer. - * As output, number of processor handles in the buffer. - * Parameter must be allocated by user. + * @param[out] bdf Reference to BDF. Must be allocated by user. * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_get_processor_handles_by_type(amdsmi_socket_handle socket_handle, - processor_type_t processor_type, - amdsmi_processor_handle* processor_handles, - uint32_t* processor_count); +amdsmi_status_t amdsmi_get_nic_device_bdf(amdsmi_processor_handle processor_handle, amdsmi_bdf_t *bdf); /** @} End tagProcDiscovery */ @@ -3162,8 +3273,8 @@ amdsmi_status_t amdsmi_get_lib_version(amdsmi_version_t *version); * * @ingroup tagErrorQuery * - * @platform{gpu_bm_linux} @platform{host} @platform{cpu_bm} @platform{guest_1vf} @platform{guest_mvf} - * @platform{guest_windows} + * @platform{gpu_bm_linux} @platform{host} @platform{cpu_bm} + * @platform{guest_1vf} @platform{guest_mvf} @platform{guest_windows} * * @details Set the provided pointer to a const char *, @p status_string, to * a string containing a description of the provided error code @p status. @@ -3235,6 +3346,9 @@ amdsmi_status_t amdsmi_get_gpu_driver_model(amdsmi_processor_handle processor_ha * the vendor ID, the subvendor ID, the device ID, * the revision ID and the serial number. * + * @note The processor_handle that contains amdsmi_asic_info_t member oam_id = 0 + * corresponds to the socket that contains baseboard information. + * * @param[in] processor_handle Device which to query * * @param[out] info Reference to static asic information structure. @@ -3282,6 +3396,29 @@ amdsmi_get_power_cap_info(amdsmi_processor_handle processor_handle, uint32_t sen */ amdsmi_status_t amdsmi_get_pcie_info(amdsmi_processor_handle processor_handle, amdsmi_pcie_info_t *info); +/** + * @brief Get the list of possible PCIe bandwidths that are available. It is not + * supported on virtual machine guest + * + * @ingroup tagAsicBoardInfo + * + * @platform{gpu_bm_linux} @platform{host} + * + * @details Given a processor handle @p processor_handle and a pointer to a to an + * ::amdsmi_pcie_bandwidth_t structure @p bandwidth, this function will fill in + * @p bandwidth with the possible T/s values and associated number of lanes, + * and indication of the current selection. + * + * @param[in] processor_handle a processor handle + * + * @param[in,out] bandwidth a pointer to a caller provided + * ::amdsmi_pcie_bandwidth_t structure to which the frequency information will be + * written + * + * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail + */ +amdsmi_status_t amdsmi_get_gpu_pci_bandwidth(amdsmi_processor_handle processor_handle, amdsmi_pcie_bandwidth_t *bandwidth); + /** * @brief Returns vram info * @@ -3434,6 +3571,7 @@ amdsmi_status_t amdsmi_get_gpu_activity(amdsmi_processor_handle processor_handle * @platform{gpu_bm_linux} @platform{host} @platform{guest_windows} * * @note amdsmi_power_info_t::socket_power metric can rarely spike above the socket power limit in some cases + * @note unsupported struct members are set to UINT32_MAX * * @param[in] processor_handle PF of a processor for which to query * @@ -3520,6 +3658,9 @@ amdsmi_status_t amdsmi_get_temp_metric(amdsmi_processor_handle processor_handle, * * @platform{host} * + * @note System baseboard data can be retrieved from the processor_handle + * whose amdsmi_asic_info_t member oam_id = 0. + * * @param[in] processor_handle PF of a processor for which to query * * @param[inout] metrics_size As input, the size of the provided buffer. @@ -3583,7 +3724,8 @@ amdsmi_status_t amdsmi_get_gpu_metrics(amdsmi_processor_handle processor_handle, * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ amdsmi_status_t -amdsmi_set_gpu_memory_partition_mode(amdsmi_processor_handle processor_handle, amdsmi_memory_partition_type_t mode); +amdsmi_set_gpu_memory_partition_mode(amdsmi_processor_handle processor_handle, + amdsmi_memory_partition_type_t mode); /** @} End tagMemoryPartition */ @@ -4018,6 +4160,30 @@ amdsmi_status_t amdsmi_set_xgmi_plpd(amdsmi_processor_handle processor_handle, amdsmi_status_t amdsmi_set_power_cap(amdsmi_processor_handle processor_handle, uint32_t sensor_ind, uint64_t cap); +/** + * @brief Query the supported power cap sensors and their types for a device. + * + * @ingroup tagPowerControl + * + * @platform{gpu_bm_linux} @platform{host} + * + * @details This function returns the list of supported power cap sensors for the given device, + * including their sensor indices and types (e.g., PPT0, PPT1). + * + * @param[in] processor_handle A processor handle. + * @param[out] sensor_count Pointer to a uint32_t that will be set to the number of supported sensors. + * @param[out] sensor_inds Pointer to an array of uint32_t to be filled with sensor indices. + * The array must be allocated by the caller with enough space. + * @param[out] sensor_types Pointer to an array of amdsmi_power_cap_type_t to be filled with sensor types. + * The array must be allocated by the caller with enough space. + * + * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail. + */ +amdsmi_status_t amdsmi_get_supported_power_cap(amdsmi_processor_handle processor_handle, + uint32_t *sensor_count, + uint32_t *sensor_inds, + amdsmi_power_cap_type_t *sensor_types); + /** @} End tagPowerControl */ /*****************************************************************************/ @@ -4134,33 +4300,6 @@ amdsmi_get_gpu_total_ecc_count(amdsmi_processor_handle processor_handle, amdsmi_ * @{ */ -/** - * @brief Get the bad page threshold for a device - * - * @ingroup tagRasInfo - * - * @platform{gpu_bm_linux} @platform{host} - * - * @details Given a processor handle @p processor_handle and a pointer to a uint32_t @p threshold, - * this function will retrieve the bad page threshold value associated - * with device @p processor_handle and store the value at location pointed to by - * @p threshold. - * - * @note This function requires the admin/sudo privileges on @platform{gpu_bm_linux} - * - * @param[in] processor_handle a processor handle - * - * @param[in,out] threshold pointer to location where bad page threshold value will - * be written. - * If this parameter is nullptr, this function will return - * ::AMDSMI_STATUS_INVAL if the function is supported with the provided, - * arguments and ::AMDSMI_STATUS_NOT_SUPPORTED if it is not supported with the - * provided arguments. - * - * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail - */ -amdsmi_status_t amdsmi_get_bad_page_threshold(amdsmi_processor_handle processor_handle, uint32_t *threshold); - /** * @brief Retrieve CPER entries cached in the driver. * @@ -4245,19 +4384,41 @@ amdsmi_status_t amdsmi_get_afids_from_cper(char *cper_buffer, uint32_t buf_size, */ amdsmi_status_t amdsmi_get_gpu_ras_feature_info(amdsmi_processor_handle processor_handle, amdsmi_ras_feature_t *ras_feature); +/** + * @brief Returns the bad page info. + * + * @ingroup tagRasInfo + * + * @platform{host} + * + * @param[in] processor_handle PF of a processor to query. + * + * @param[in] array_length Length of the array where the library will + * copy the data. + * + * @param[out] bad_page_count Number of bad page records. + * + * @param[out] info Reference to the eeprom table record structure. + * Must be allocated by user. + * + * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail + */ +amdsmi_status_t amdsmi_get_gpu_bad_page_info(amdsmi_processor_handle processor_handle, uint32_t *bad_page_size, + amdsmi_eeprom_table_record_t *bad_pages); + /** * @brief Get the RAS policy info for a device * * @ingroup tagRasInfo * - * @platform{gpu_bm_linux} @platform{host} + * @platform{host} * * @details Given a processor handle @p processor_handle, this function will retrieve * the RAS policy information for the device. * * @param[in] processor_handle PF of a processor for which to query * - * @param[out] policy_info RAS policy info for the device. Must be allocated by user. + * @param[out] info RAS policy info for the device. Must be allocated by user. * * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ @@ -4265,26 +4426,31 @@ amdsmi_status_t amdsmi_get_gpu_ras_policy_info(amdsmi_processor_handle processor amdsmi_gpu_ras_policy_info_t *info); /** - * @brief Returns the bad page info. + * @brief Get the bad page threshold for a device * - * @ingroup tagRasInfo + * @ingroup tagRasInfo * - * @platform{host} + * @platform{host} * - * @param[in] processor_handle PF of a processor to query. + * @details Given a processor handle @p processor_handle and a pointer to a uint32_t @p threshold, + * this function will retrieve the bad page threshold value associated + * with device @p processor_handle and store the value at location pointed to by + * @p threshold. * - * @param[in] array_length Length of the array where the library will - * copy the data. + * @note This function requires the admin/sudo privileges on @platform{gpu_bm_linux} * - * @param[out] bad_page_count Number of bad page records. + * @param[in] processor_handle a processor handle * - * @param[out] info Reference to the eeprom table record structure. - * Must be allocated by user. + * @param[in,out] threshold pointer to location where bad page threshold value will + * be written. + * If this parameter is nullptr, this function will return + * ::AMDSMI_STATUS_INVAL if the function is supported with the provided, + * arguments and ::AMDSMI_STATUS_NOT_SUPPORTED if it is not supported with the + * provided arguments. * - * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail + * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail */ -amdsmi_status_t amdsmi_get_gpu_bad_page_info(amdsmi_processor_handle processor_handle, uint32_t *bad_page_size, - amdsmi_eeprom_table_record_t *bad_pages); +amdsmi_status_t amdsmi_get_bad_page_threshold(amdsmi_processor_handle processor_handle, uint32_t *threshold); /** @} End tagRasInfo */ @@ -4296,7 +4462,8 @@ amdsmi_status_t amdsmi_get_gpu_bad_page_info(amdsmi_processor_handle processor_h */ /** - * @brief Triggers a chain that resets all GPUs. It is not supported on virtual machine guest + * @brief Triggers a chain that resets all GPUs. + * It is not supported on virtual machine guest * * @ingroup tagClkPowerPerfQuery * @@ -4399,10 +4566,10 @@ amdsmi_status_t amdsmi_set_gpu_ptl_state(amdsmi_processor_handle processor_handl * @details This function retrieves the current PTL formats * for the specified processor. PTL prevents the product to never deliver more * than a specified TOPS/second. If function returns 0 for both formats, - * PTL was never enabled before on that system. + * PTL was never enabled before on that system * * @param[in] processor_handle Device which to query -* + * * @param[out] data_format1 Pointer to first preferred data format that receives peak performance * * @param[out] data_format2 Pointer to second preferred data format that receives peak performance @@ -4431,7 +4598,7 @@ amdsmi_get_gpu_ptl_formats(amdsmi_processor_handle processor_handle, * @param[in] processor_handle Device to configure * * @param[in] data_format1 First preferred data format (must be from the limited set: - * I8, F16, BF16, F32, F64) + * I8, F16, BF16, F32, F64, F8, Vector) * * @param[in] data_format2 Second preferred data format (must be from the limited set: * I8, F16, BF16, F32, F64, and different from data_format1) @@ -4439,7 +4606,7 @@ amdsmi_get_gpu_ptl_formats(amdsmi_processor_handle processor_handle, * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, * ::AMDSMI_STATUS_NOT_SUPPORTED if PTL is not supported on this device, * non-zero on other failures - **/ + */ amdsmi_status_t amdsmi_set_gpu_ptl_formats(amdsmi_processor_handle processor_handle, amdsmi_ptl_data_format_t data_format1, @@ -4911,7 +5078,30 @@ amdsmi_status_t amdsmi_get_nic_vendor_statistics(amdsmi_processor_handle process amdsmi_status_t amdsmi_get_nic_rdma_port_statistics(amdsmi_processor_handle processor_handle, uint32_t rdma_port_index, uint32_t *num_stats, amdsmi_nic_stat_t *stats); +/** + * @brief Retrieve the link topology type information between nic and processor + * + * @ingroup tagNicInfo + * + * @platform{host} @platform{gpu_bm_linux} + * + * @param[in] nic_handle NIC for which to query + * + * @param[in] processor_handle PF of a processor for which to query + * + * @param[out] type reference of the link topology type enum. + * Must be allocated by user. + * + * @return ::amdsmi_status_t | ::AMDSMI_STATUS_SUCCESS on success, non-zero on fail + */ +amdsmi_status_t amdsmi_topo_get_nic_link_type(amdsmi_processor_handle nic_handle, + amdsmi_processor_handle processor_handle, amdsmi_nic_link_type_t *type); + /** @} End tagNicInfo */ +#ifdef __cplusplus +} +#endif + #endif // __AMDSMI_H__ diff --git a/sw/nic/third-party/rocm/gim_amd_smi_lib/version.txt b/sw/nic/third-party/rocm/gim_amd_smi_lib/version.txt index fc7a3917..33d19ece 100644 --- a/sw/nic/third-party/rocm/gim_amd_smi_lib/version.txt +++ b/sw/nic/third-party/rocm/gim_amd_smi_lib/version.txt @@ -1 +1 @@ -mainline/8.7.0.K +9.0.0.K diff --git a/sw/nic/third-party/rocm/gim_amd_smi_lib/x86_64/lib/libgim_amd_smi.so b/sw/nic/third-party/rocm/gim_amd_smi_lib/x86_64/lib/libgim_amd_smi.so index 1973fc8c..a4c1b26f 100755 Binary files a/sw/nic/third-party/rocm/gim_amd_smi_lib/x86_64/lib/libgim_amd_smi.so and b/sw/nic/third-party/rocm/gim_amd_smi_lib/x86_64/lib/libgim_amd_smi.so differ