1. 加载流程
BMC首先会加载NVMe背板的Connector,命名上会包含背板的UID,在BusinessConnector下有RefMgmtConnector,背板会加载Connector_ComVPDConnect对象 Connector_ComVPDConnect对象中有"Bom": “14140224”、“Id”: “VPD"以及"AuxId”: “0” 框架会根据Bom、Id和AuxId进一步加载14140244_VPD_0. sr文件。例如Connector_ComVPDConnect_1在位是通过Scanner_Drive1PCIePresence和Scanner_Drive1PCIeType共同决定,在openubmc目录下展示了这两个值的来源于Smc_EnclSMC chip的读取
"Scanner_Drive1PCIePresence": {
"Chip": "#/Smc_EnclSMC",
"Offset": 335545601,
"Size": 2,
"Mask": 1,
"Type": 0,
"Period": 2000,
"Debounce": "None",
"Value": 0
},
"Scanner_Drive1PCIeType": {
"Chip": "#/Smc_EnclSMC",
"Offset": 335545601,
"Size": 2,
"Mask": 2,
"Type": 0,
"Period": 2000,
"Debounce": "None",
"Value": 0
},
在14140224_VPD_0.sr中,这里面有VirtualVPDConnect;在RefConnector中有定义对应的Connector_ComVPD,对应lua中c_vpd_connect
---@class c_vpd_connect: c_object
---@field Slot integer
---@field RefVPDChip c_object
---@field RefConnector c_object
local c_vpd_connect = c_object('VirtualVPDConnect') -- VirtualVPDConnect类
在Connector_ComVPD有Bom、Id、AuxId;AuxId对应的是nvme盘所支持的协议,在更新Connector的时候会重新确认当前盘支持哪种协议,然后更新当前的AuxId
function c_vpd_connect:update_connector()
if not self.RefConnector then
return
end
local ok, aux_id = pcall(function()
return self:verify_vpd_protocol()
end)
log:notice('connector get protocol is %s', aux_id)
self.RefConnector.AuxId = ok and tostring(aux_id) or '255'
-- 确保AuxId比Presence先更新
while ok do
if self.RefConnector.AuxId == tostring(aux_id) then
self.RefConnector.Presence = 1
break
end
-- 避免长时间占用阻塞协程切换
skynet.sleep(100)
end
end
更新完以后,框架进一步加载Bom + Id +AuxId组合sr文件;例如支持nvme-mi协议,则加载14140224_PROTOCOL_0.sr;在14140224_PROTOCOL_0.sr中有对应的nvme对象;对应nvme_object.lua中的c_nvme
---@class c_nvme: c_object
---@field Slot integer
---@field PredictedMediaLifeLeftPercent integer
---@field Revision string
---@field MediaType integer
---@field Protocol integer
---@field Failure integer
---@field PredictiveFailure integer
---@field TemperatureCelsius integer
---@field VPDChip c_object
---@field SSDChip c_object
---@field RefComponent c_object
local c_nvme = c_object('Nvme') -- Nvme 类,主键是 Slot 字段
在14140224_PROTOCOL_0.sr中定义的三种Chip;分别是Chip_Virtual_SSD(VPDChip)、Chip_SSD和Chip_Temp;分别对应nvme盘产品规格书上的8位地址;根据厂商给出Data sheet偏移,读取nvme相应属性。
2. 散热
Nvme盘目标调速由14140224_PROTOCOL_0.sr中的CoolingRequirement实现,曲线调速由CoolingPolicy实现
目标调速
"CoolingRequirement_1_60": {
"RequirementId": "${Slot} |> expr((60 << 8) | $1)",
"MonitoringStatus": "<=/Scanner_Temp.Value |> expr($1 >= 255 ? 1 : 0)",
"MonitoringValue": "<=/Scanner_Temp.Value",
"FailedValue": 80,
"TargetTemperatureCelsius": 69,
"MaxAllowedTemperatureCelsius": 75,
"TargetTemperatureRangeCelsius": [],
"ThresholdValue": [],
"AlarmSpeed": []
}
RequirementId:全局唯一,建议使用槽位号等能确保多次分发sr都是唯一值的属性;如果存在id相同,则后配置的CoolingRequirement无法调速
MonitoringStatus:温度状态,用于异常调速,0正常其他值异常;当为异常值时,会使用FailedValue温度值进行异常调速
MonitoringValue:温度值,关联硬件,不允许关联传感器reading值
TargetTemperatureCelsius:目标调速值,默认模式是节能模式;如果涉及三种模式调速(节能模式、高性能模式、低噪音模式),SmartCoolingTargetTemperature可进行三种模式目标温度调速
MaxAllowedTemperatureCelsius:目标调速满转温度
环温曲线调速
"CoolingPolicy_1_15": {
"PolicyIdx": 15,
"ExpCondVal": "EnergySaving",
"ActualCondVal": "<=/CoolingConfig_1.SmartCoolingMode",
"Hysteresis": 1,
"TemperatureRangeLow": [-127,20,21,22,],
"TemperatureRangeHigh": [20,21,22,127],
"SpeedRangeLow": [20,30,50,100],
"SpeedRangeHigh": [20,30,50,100],
"FanType": ["02314EWC 8080+","02314BLG 8038+"],
"HDDBackPlaneName": [
"BC83HBBA"
]
},
PolicyIdx:Id全局唯一
ExpCondVal:期望条件,CoolingPolicy生效前提是实际条件与期望条件一致
ActualCondVal:实际条件
Hysteresis:迟滞量
TemperatureRangeLow:环温调速曲线,同V2
TemperatureRangeHigh:环温调速曲线,同V2
SpeedRangeLow:环温调速曲线,同V2
SpeedRangeHigh:环温调速曲线,同V2
FanType:风扇类型,满足其中之一生效
HDDBackPlaneName:硬盘背板名称,环境有该背板之一时生效
调速分区
CoolingArea用于关联CoolingPolicy和CoolingRequirement等调速,用于一个温度点调速需要哪些风扇,也说明一个温度点关联哪些环温曲线;一般来说CoolingArea与
CoolingRequirement一一对应
"CoolingArea_1_6": {
"AreaId": 6,
"RequirementIdx": 6,
"PolicyIdxGroup": [6,20,25,30,34,40],
"FanIdxGroup": [1,2,3,4]
},
AreaId:Id全局唯一
RequirementIdx:关联温度点,一般与CoolingRequirement的RequirementId关联
PolicyIdxGroup:关联温度点,一般与环温调速CoolingPolicy的PolicyIdx关联
FanIdxGroup:温度点关联风扇id,必须是整数,从小到大排序
3. 基线
适配基线主要包含:北向接口资产信息的获取,一般重要的属性包含健康状态、厂商、型号、序列号、固件版本、温度、容量以及剩余磨损率等。
其他项:nvme盘告警事件包含VPDChip读取失败、固件版本读取失败、高温告警事件、温度获取失败事件等,具体可以参考14140224_PROTOCOL_0.sr
4. 遇到问题
当时适配大普盘时,BMC Web无法获取nvme盘的温度和固件版本等属性信息,经走读代码,初步判断代码所用Chip和偏移位并未配错,同步在BMC后台是mdbctl读取固件版本时出现链路不通。
% call Chip_SSD_01010C0103 bmc.kepler.Chip.BlockIO Read 0 0x0b 8
kepler.hwproxy.IOError: table: 0xffff287f1200
同步对比V2配置的SSD Chip类对象,偏移位与V3配置相同;发现V2上能正常读取
% testchip ssdChip-d02 0 1 0x0b 20
0x52 0x53 0x36 0x55 0x30 0x31 0x41 0x32 0x34 0x43 0x30 0x31 0x48 0x53 0x43 0x30 0x20 0x20 0x20 0x20
所用华为5.5版本非稳定版本,该Chip链路未正常配置,华为工程师沟通,温度和固件版本获取与上电状态有关;华为硬件怀疑CPLD版本过旧可能导致Chip通信失败,尝试更新Nvme背板CPLD后,Chip通信成功
% call Chip_SSD_01010C0403 bmc.kepler.Chip.BlockIO Read 0 11 20
[83,72,50,53,48,49,48,54,55,57,54,32,32,32,32,32,32,32,32,32]
注:Chip是通过I2C/Smbus通信,线路是Nvme背板CPLD映射的虚拟线路,像nvme定位灯功能是通过向nvme背板发送SMC命令实现