算力部件相关FAQ
更新时间: 2025/08/18
在Gitcode上查看源码

【Q】CPU、内存信息是怎样加载的?

概述

  • CPU的静态信息包括家族、型号、ID、序列号、部件号等,内存的静态信息包括容量、位宽、厂商、序列号等,这些静态信息来自BIOS上报的SMBIOS信息

  • SMBIOS信息的上报通常发生在BIOS完成对系统硬件的基本检测和初始化之后,在操作系统加载之前

SMBIOS协议简介

  • SMBIOS协议官方网站

  • SMBIOS是DMTF制定的开放标准,用于规范主板及系统厂商如何存储和管理产品信息。通过统一格式让厂商在BIOS中记录硬件信息,便于管理软件获取硬件配置数据

  • 当前openUBMC支持对Processor Information(4)/Cache Informaiton(7)/Physical Memory Array(16)/Memory Device(17)部分字段解析上报

详细流程

  • 1、BIOS通过IPMI命令ReadFileFromBmc从BMC读取内存丝印信息,包含Memory对象的CpuId、LogicalChannelId、DimmId等属性

  • 2、BIOS将丝印信息填充到SMBIOS表格中,通过IPMI命令WriteSmbiosData上报给BMC,写成SMBIOS_CONF文件

  • 3、bios组件读取这个文件并解析,最终将CPU、内存信息更新到资源协作路径上。内存信息通过丝印信息来匹配Memory对象,CPU信息通过LogicalLd来匹配CPU对象

通过SMBIOS获取的信息

CPU对象 SMBIOS字段映射表

SMBIOS字段资源树属性转换逻辑
processor_manufacturerManufacturer直接赋值
processor_familyFamily通过 g_proc_models 表映射为家族名称
processor_family_2Familyprocessor_family 为 0xFE 时使用此字段
max_speedMaxSpeedMHz直接赋值(MHz)
current_speedCurrentSpeedMHz直接赋值(MHz)
external_clockBaseSpeedMHz直接赋值(MHz)
processor_versionModel直接赋值
part_numberPartNumber非 "To be filled by O.E.M." 时赋值,否则设为 "Unknown"
part_numberInventoryPartNumber同上
processor_idProcessorID直接赋值
processor_idProcessorIDString通过 get_processor_id() 函数转换
processor_typeProcessorType转为字符串
serial_numberSN非 "To be filled by O.E.M." 时赋值,否则设为 "Unknown"
serial_numberSerialNumber同 SN
processor_manufacturerInventoryManufacturer同 Manufacturer
processor_versionInventoryModel同 Model
socket_designationSocketDesignation直接赋值
core_countTotalCores直接赋值,为 0xFF 时使用 core_count_2
core_count_2TotalCorescore_count 为 0xFF 时使用
core_countTotalEnabledCores通过 get_enabled_cores() 函数计算
thread_countTotalThreads直接赋值,为 0xFF 时使用 thread_count_2
thread_count_2TotalThreadsthread_count 为 0xFF 时使用
processor_characteristicsCharacteristics直接赋值
thread_enabledTotalEnabledThreads直接赋值,失败时默认为0

CPU特殊值处理

场景转换逻辑
part_number 为 "To be filled by O.E.M."→ "Unknown"
serial_number 为 "To be filled by O.E.M."→ "Unknown"
processor_family 为 0xFE使用 processor_family_2 字段
core_count 为 0xFF使用 core_count_2 字段
thread_count 为 0xFF使用 thread_count_2 字段

内存对象 SMBIOS字段映射表

SMBIOS字段资源树属性转换逻辑
speedAllowedSpeedsMHz直接赋值(MT/s)
(通过 get_base_module_type)BaseModuleType类型转换函数
sizeCapacityMiB小于 0x7fff 时直接赋值
extended_sizeCapacityMiBsize >= 0x7fff 时使用此字段
data_widthDataWidthBits直接赋值(bit)
firmware_versionFirmwareRevision通过 get_firm_ware_revision() 转换
manufacturerManufacturer直接赋值
(通过 get_memory_device_type)MemoryDeviceType类型转换函数
memory_subsystem_controller_manufacturer_idMemorySubsystemControllerManufacturerID转为字符串
memory_subsystem_controller_product_idMemorySubsystemControllerProductID转为字符串
type_detailMemoryType通过 :tostring() 方法转换
configured_memory_speedOperatingSpeedMhz直接赋值(MT/s)
part_numberPartNumber通过 trim() 去除首尾空格
part_numberOriginalPartNumber同上
attributesRankCount通过 :rank() 方法获取
serial_numberSerialNumber"NO DIMM" 时设为 "N/A",否则直接赋值
(通过 get_memory_presence)Presence根据厂商信息判断,详见下方说明
minimum_voltageMinVoltageMillivolt直接赋值(mV)
(通过 get_manufacturing_date)ManufacturingDate日期格式转换
(通过 get_bom_num)BOMBOM号转换
(通过 get_manufacturer_id)ManufacturerID厂商ID转换
(通过 get_memory_type)Technology内存技术类型转换

内存Presence计算逻辑

内存的 Presence 属性由 get_memory_presence(smbios_entry) 函数计算,核心逻辑如下:

lua
(Memory.Manufacturer ~= 'NO DIMM' and Memory.Manufacturer ~= 'empty') and 1 or 0

即:当厂商信息既不是 "NO DIMM" 也不是 "empty" 时,Presence 设为 1(存在),否则设为 0(不存在)。

内存特殊值处理

场景转换逻辑
serial_number 为 "NO DIMM"→ "N/A"
size >= 0x7fff使用 extended_size 字段(支持64GB以上内存)
Presence == 0(不在位)清空 Inventory* 系列属性

内存Inventory属性(Presence=1时)

当内存 Presence 为 1 时,以下属性会被填充:

属性值来源
AssetType固定为 "Memory"
InventoryManufacturerManufacturer
InventorySerialNumberSerialNumber
InventoryPartNumberPartNumber
AssetNamePosition + DimmName 拼接
FirmwareVersion固定为 "N/A"
PCBVersion固定为 "N/A"
AssetTag固定为 "N/A"
ManufactureDate固定为 "N/A"
SlotDimmName
Model固定为 "N/A"

当 Presence 为 0 时,上述 Inventory 属性会被清空。


上述SMBIOS文件可以在一键收集中找到,路径为 dump_info\AppDump\bios\1\SMBIOS_CONF,具体解析方式可参考 /bios/include/bios/smbios/memory_decoder.lua/bios/include/bios/smbios/processor_decoder.lua

【Q】内存占用率获取不到

当下内存的占用率可以通过多种途径查询,仅列出最便捷的几种查询方法

1、通过web首页的系统监控页第三栏内存查看
2、通过redfish URL `https://device_ip/redfish/v1/Systems/1/MemorySummary/MemoryMetrics` 查询 `MemoryMetrics` 资源下的 `BandwidthPercent` 属性
3、通过命令 `mdbctl lsprop MemoryMetrics_1_010101` 查询资源协作接口 `bmc.kepler.Systems.Memory.MemoryMetrics` 下的 `BandwidthPercent` 属性

当下内存的占用率获取依赖bma服务,该服务的使用方式可以参考社区文档:HOST代理管理常见问题指南

当内存占用率获取不到时,你首先可以查看如下信息

busctl --user introspect bmc.kepler.host_agent /bmc/kepler/Systems/1/Sms
bmc.kepler.Systems.Sms              (查看该接口下的 Registered 属性)
Registered
bmc.kepler.Systems.Sms.SmsStatus    (查看该接口下的 State 属性)
State

busctl --user introspect bmc.kepler.host_agent /bmc/kepler/Systems/1/Sms/1/ComputerSystem/Systems/1/Summary
bmc.kepler.sms.redfish.Memory       (查看该接口下的 MemUsage 属性)
MemUsage

查看命令回显的 Registered 是否为 true,State 是否为 0,MemUsage 的值是否为小于100的非负数。若上述条件均为是,则可以认为bma正常运行且获取到了内存占用率。现在对于compute组件进行相应的排查,查看是否有如下形式notice级别的日志打印

[system1]sms registered is true
[system1]sms status is 0

如果未出现上述形式的日志打印,可以尝试升级openubmc版本至20251230之后的版本。

【Q】CPU占用率获取不到

CPU占用率的来源相比于内存占用率多了从bma获取的方式,因此在内存占用率获取异常时,CPU占用率是有可能正常获取到的。当下cpu占用率的查看方式同样有多种,此处列出最便捷的几种方式,以供参考

1、通过web首页的系统监控页第二栏CPU查看
2、通过redfish URL `https://device_ip/redfish/v1/Systems/1/ProcessorSummary/ProcessorMetrics` 查询 `ProcessorMetrics` 资源下的 `BandwidthPercent` 属性
3、通过命令 `mdbctl lsprop CPUMetrics_1_010101` 查询资源协作接口 `bmc.kepler.Systems.Processor.ProcessorMetrics` 下的 `BandwidthPercent` 属性

对于CPU占用率获取不到主要分为一下两种情况进行分析 1.内存占用率获取成功,CPU占用率获取失败 2.内存占用率获取失败,CPU占用率获取失败 对于第一种情况,请通过如下命令查看

busctl --user introspect bmc.kepler.host_agent /bmc/kepler/Systems/1/Sms/1/ComputerSystem/Systems/1/Summary
bmc.kepler.sms.redfish.Processor        (查看该接口下的 TotalCPUUsage 属性)
TotalCPUUsage

TotalCPUUsage为255,可以明确在bma侧继续定位。若不为255,可以寻找compute组件的负责人进行后续的定位,目前无相关场景经验。

对于第二种情况,首先打开compute组件的debug级别日志开关,并查找相关日志进行定位。

mdbctl
attach compute
dloglevel debug
dlogtype local
update cpu usage fail, cc =

若出现日志打印update cpu usage successfully, usage = 255,可以初步定位为带内返回数据有误。建议评估影响后尝试重启os。 若出现日志打印update cpu usage fail, cc = %d,依据具体的返回compcode以明确对应问题。这一情况也可以初步定位为带内异常,建议评估影响后尝试重启os。 若上述日志打印均未出现,请尝试回退BIOS版本,查看能否正常查询。

对于第二种情况,上述措施均致力于修复通过imu查询cpu占用率失败问题,实际更建议通过bma查询cpu占用率信息。

【Q】上电时出现内存对象SN变更告警

内存SN变更时会出现如下打印:

2026-02-03 20:11:24.024117 frudata NOTICE: sn_replace.lua(62): BoardSerialNumber changed from 80AD01240697D99125 to 8A91502511B008497D
2026-02-03 20:11:24.065079 frudata NOTICE: sn_replace.lua(62): BoardSerialNumber changed from 80AD01240697D7EEEC to 8A91502511B0084973

若以上打印出现前,未进行内存的更换,则为误告警。内存对象的SN来源于BIOS基于BMC发送的丝印文件提供的SMBIOS文件。若出现以上情况,可以判定为BIOS上报的SNBIOS文件中的SN发生了变动。首先确认我们发送给带内的丝印文件是否有误,丝印文件位于一键收集日志的 dump_info\AppDump\bios\1\silkconfig.json 下,其中一个内存的丝印文件如下,并标注了其对应的内存对象的属性

{
    "DimmId": 1,                 内存对象 bmc.kepler.Systems.Memory 接口下的 DimmId 属性
    "LogicalChannelId": 5,       内存对象 bmc.kepler.Systems.Memory 接口下的 LogicalChannelId 属性
    "PhysicalChannelId": 3,      内存对象 bmc.kepler.Systems.Memory 接口下的 ChannelId 属性
    "SocketId": 0,               内存对象 bmc.kepler.Systems.Memory 接口下的 CpuId 属性
    "Silk": "DIMM031"            内存对象 bmc.kepler.Systems.Memory 接口下的 DimmName 属性
}

通过查询日志文件 dump_info\AppDump\compute\mdb_info.log,可以发现不存在符合该条件的内存,即可判定为发送的丝印文件有误。一般而言丝印文件的传输是由BIOS在带内os起来后,主动要求BMC发送的,因此当BIOS在请求丝印文件时,若相关信息没有上树,则会出现发送的丝印文件错误的情况。更具体的流程可以参考这篇社区文档:丝印上报总结分享,该文档讲解得非常详细。

【Q】内存不加载

内存的加载流程整体分为两部分

  1. 硬件自发现的对象分发
  2. 依据丝印文件中的信息将对应内存对象 bmc.kepler.Systems.Memory 接口下的 Presence 置为 0/1

第一部分的相关流程,社区中有详细的文档介绍,此处不重复介绍。第二部分则依赖于BIOS提供的SMBIOS文件。具体的计算方式如下:

(Memory.Manufacturer ~= 'NO DIMM' and Memory.Manufacturer ~= 'empty') and 1 or 0

其中 Memory.Manufacturer 为该内存对象 bmc.kepler.Systems.Memory接口下的 Manufacturer 属性。

【Q】NPU卡支持哪些属性?如何获取?

NPU卡通过标准SMBUS协议与MCU通信,获取各类属性信息。以下是各属性分类的详细说明:

属性名称命令字(opcode)查询间隔响应转换方法数据类型
McuFirmwareVersion0x000530sstring.format('%s.%s.%s', string.unpack('BBB', data))版本字符串
FirmwareVersion0x060730s直接返回字符串版本字符串
PowerWatts0x00042sbs.new([[<<power:16>>]]):unpack(data, true).power整型(瓦特)
DeviceTemperature0x001D2s按传感器名称映射为 AiCoreTemp/HBMTemp/NimBusTemp/VRDChipTemp温度对象
ChipTemperature0x00032sbs.new([[<<chip_temp:16>>]]):unpack(data, true).chip_temp整型(摄氏度)
MemoryCapacityKiB未在配置中定义30s每个芯片容量累加后除以1024转为MB整型(MiB)
MemoryBandWidth未在配置中定义30s直接返回整型
SerialNumber通过Elabel获取按需来自Elabel的BoardSerialNumber字符串
BoardID0x0F10sbs.new([[<<board_id:16>>]]):unpack(data, true).board_id整型
PcbVersion0x1010sstring.format('.%c', val + 64) (A-Z)字符型
SN通过SerialNumber获取按需与SerialNumber同步字符串
ErrorCode0x0002按需解析为错误码数组,0x00表示无错误数组
NPUFaultCode0x060D按需4字节一组拼接为16进制字符串数组
ChipFaultDescription-按需ErrorCode + NPUFaultCode 组合字符串
Capabilities0x0030s解析为opcode列表(命令支持列表)
McuType0x90按需高低位拼接为vendor_id整型
McuTime0x21按需时间戳同步时间戳
CurEccErrCount0x1F30s{cur_single_err_count, cur_double_err_count}对象
AggregateAndIsolatedCount0x68130s{single_total_count, double_total_count, single_isl_count, double_isl_count}对象
RecordedIsolatedPagesCount0x68A30srecorded_isolated_count整型
ErrorLog0x000C按需直接返回原始数据二进制数据
OperateLog0x26按需直接返回原始数据二进制数据
MaintenanceLog0x27按需直接返回原始数据二进制数据

电子标签(Elabel)列表

属性名称参数(arg)说明
ChassisType0x10机箱类型
ChassisPartNumber0x11机箱型号
ChassisSerialNumber0x12机箱序列号
MfgDate0x20生产日期(6字符时间戳)
BoardManufacturer0x21板卡制造商
BoardProductName0x22板卡产品名称
BoardSerialNumber0x23板卡序列号
BoardPartNumber0x24板卡型号
BoardFRUFileID0x25板卡FRU文件ID
ManufacturerName0x30制造商名称
ProductName0x31产品名称
ProductPartNumber0x32产品型号
ProductVersion0x33产品版本
ProductSerialNumber0x34产品序列号
AssetTag0x35资产标签
ProductFRUFileID0x36产品FRU文件ID
SystemManufacturerName0x60系统制造商名称
SystemProductName0x61系统产品名称
SystemVersion0x62系统版本
SystemSerialNumber0x63系统序列号

DeviceTemperature 传感器映射表

MCU传感器名称映射属性名
AICOREAiCoreTemp
HBMHBMTemp
PREDEVNimBusTemp
VRDMAXVRDChipTemp

读取异常时的特殊值

常量说明
NA_READING0x4000设备不在位或读不到值
INVALID_READING0x8000读取失败

Elabel获取方式: 通过 opcode 0x0015,根据 arg 参数区分不同属性 说明: MemoryCapacityKiB 为按芯片遍历获取,所有芯片容量累加后除以1024转为 MiB。 说明: SerialNumber 来自电子标签(Elabel)中的 BoardSerialNumber 字段。SN 属性通过 update_sn_by_std_smbus 方法获取并同步到资源树。 说明: ChipFaultDescription 由 ErrorCode 和 NPUFaultCode 组合而成,用于描述芯片故障信息。

【Q】不同型号NPU卡的配置差异

不同型号的NPU卡在传感器映射、芯片数量等方面存在差异:

表 传感器映射差异

型号传感器名称映射属性名
Atlas 300I A2AICORE, HBM, PREDEV, VRDMAXAiCoreTemp, HBMTemp, NimBusTemp, VRDChipTemp
Atlas 300I ProLM75B_TE, LM75A_TE, AICOREInletTemperatureCelsius, OutletTemperatureCelsius, Core0TemperatureCelsius
Atlas 300I DuoT_LM75B, T_LM75A, T_CORE_M, T_CORE_SInletTemperatureCelsius, OutletTemperatureCelsius, Core0TemperatureCelsius, Core1TemperatureCelsius

表 芯片数量差异

型号芯片数量
Atlas 300I A21
Atlas 300I Pro1
Atlas 300I Duo2

【Q】NPU卡常见问题排查

问题可能原因解决方案
返回NA_READING (0x4000)设备不在位或通信异常检查PCIe连接和MCU通信
返回INVALID_READING (0x8000)读取超时或协议错误检查网络延迟和MCU状态

【Q】CPU信息获取方式

CPU的动态信息使用IPMI命令向IMU查询,compute组件负责定期采集并更新到资源树。以下是各属性对应的查询间隔、数据转换规则和资源树属性。

CPU查询命令汇总表

资源树接口属性查询间隔数据转换特殊值
bmc.kepler.Systems.ProcessorTemperatureCelsius5stonumber(string.format('%d.%d', TempHi, TempLo))0x8000(失败)、0x4000(不在位)
bmc.kepler.Systems.ProcessorPowerWatt20s直接返回整数值(瓦特)0x0000(连续失败10次)
bmc.kepler.Systems.ProcessorPowerWatts20s直接返回整数值(瓦特)-
bmc.kepler.Systems.ProcessorMaxMemoryTSensorTemperatureCelsius5s取所有TSensor温度中的最大值0x3FFF(查询失败)、0x7FFF(查询成功但温度值读取失败)、0x4000(不在位)
bmc.kepler.Systems.ProcessorMaxMemoryTemperatureCelsius5s取所有DIMM温度中的最大值0x8000(失败)、0x4000(不在位)
bmc.kepler.Systems.ProcessorMaxMemoryTemperatureName5s返回最高温度对应的DIMM名称"N/A"
bmc.kepler.Systems.Processor.ProcessorMetricsConsumedPowerWatt20s所有CPU功耗累加值(瓦特)-
bmc.kepler.Systems.Processor.ProcessorMetricsBandwidthPercent20s小数位为0取整数值,否则整数位+1;超100%返回0xFF0xFF

【Q】内存信息获取方式

内存的动态信息通过IMU使用IPMI命令获取,与CPU共享相同的命令通道。以下是各属性对应的查询间隔、数据转换规则和资源树属性。

内存查询命令汇总表

资源树接口属性查询间隔数据转换特殊值
bmc.kepler.Systems.MemoryTemperatureCelsius5s遍历DIMM温度,保留小数0x8000(失败)、0x4000(不在位)
bmc.kepler.Systems.MemoryLogicTemperatureCelsius5s取所有Logic区温度中的最大值0x8000(失败)、0x4000(不在位)
bmc.kepler.Systems.MemoryDRAMTemperatureCelsius5s取所有DRAM区温度中的最大值0x8000(失败)、0x4000(不在位)
bmc.kepler.Systems.Memory.MemoryMetricsConsumedPowerWatt20s直接返回整数值(瓦特)0xFFFFFFFF(失败)
bmc.kepler.Systems.Memory.MemoryMetricsBandwidthPercent20s直接返回整数值(百分比)0xFF
bmc.kepler.Systems.Memory.MemoryMetricsSystemMemoryBuffersGiB20s直接返回整数值(GiB)0
bmc.kepler.Systems.Memory.MemoryMetricsSystemMemoryCachedGiB20s直接返回整数值(GiB)0
bmc.kepler.Systems.Memory.MemoryMetricsTotalSystemMemoryGiB20s直接返回整数值(GiB)0