1. KMD用户使用手册¶
1.1. 简介¶
KMD是燧原硬件产品的Linux内核态驱动。本文档主要介绍KMD的安装和使用方法。
1.2. 前提¶
- 燧原KMD只支持64位系统,且必须在BIOS中打开如下设置(不同BIOS的描述可能有所不同)。
Enable 4G decoding in BIOS
1.3. KMD安装¶
驱动安装包有以下几个。
- enflame-xxx.run
GCU的基础驱动模块,需要首先安装,其它模块都依赖它。安装时会在目标机上即时编译生成enflame.ko、安装efsmi/ef-debugdump等基础工具。
- enflame_peer_mem-xxx.run
分布式上基于RDMA网卡的加速模块,依赖ib_core等第三方驱动模块。
- enflame_virt-xxx.run
GCU的虚拟化模块,GCU虚拟化场景下才需要。
驱动包的安装参数:
sudo ./enflame-xxx.run [--no-auto-load] [--mdev-host | --with-vgcu] [--with-dkms | --no-dkms]
--no-auto-load :开机不自动加载kmd。默认开机自动加载。
--mdev-host | --with-vgcu :以mdev_host(VM monitor)或vgcu模式。默认为asic模式。
--with-dkms | --no-dkms :是否使用dkms加载。默认为不使用。
Attention
run包仅支持asic平台,不支持仿真平台。
Attention
在mdev_host模式下,需要再执行”sudo ./enflame_virt-xxx.run”,额外加载虚拟化驱动run安装包。虚拟化驱动以Cluster为单位空分设备,每个mdev设备节点只能使用1个cluster的资源,然后,使用Qemu透传给不同的虚拟机用户使用。其中T20支持4个mdev,I20支持2个mdev。
Attention
在vgcu模式下,T20只支持按空分方式划分,每个vgcu设备节点只能使用1个cluster的资源,用来透传给不同的docker使用。I20同时支持空分和时分两种vgcu模式,其中空分方案支持2个vgcu,时分方案支持4个vgcu,缺省情况为空分方案。
参考 修改KMD的模块参数,使用不同的模块参数来设置vgcu数量。
#空分切换为时分的命令如下,然后再安装run包。
echo 'options enflame enable_usr_parameter="vgcu_num=4"' > /etc/modprobe.d/gcu_test.conf
#时分切换为空分的命令如下,然后再安装run包。
echo 'options enflame enable_usr_parameter="vgcu_num=2"' > /etc/modprobe.d/gcu_test.conf
1.4. KMD模块签名¶
部分机器上Linux内核中使能了驱动模块签名,即SSL signature功能,编译出的ko不能直接加载,必须由用户签名后才能安装。
1.5. 修改KMD的模块参数¶
在安装使用KMD时,可能需要临时修改一些模块参数,比如reset_enable等,可按以下步骤操作。
sudo ./enflame.*.run –xxx #常规安装run包,非必须
sudo rmmod enflame_peermem #卸载已安装的模块
sudo rmmod enflame #卸载主模块
cp -f /etc/modprobe.d/gcu.conf ./gcu_test.conf #拷贝一份临时配置文件,如果源文件不存的话,可忽略
echo ‘options enflame enable_usr_parameter=”reset_enable=0”’ >> gcu_test.conf #关闭reset功能
echo ‘options enflame enable_usr_parameter=”enable_ssm_rt_fw=0”’ >> gcu_test.conf #关闭ssm rfw功能
echo ‘options enflame enable_usr_parameter=”enable_sip_timeout_interval_ms=0”’ >> gcu_test.conf #关闭sip timeout功能
echo ‘options enflame enable_usr_parameter=”enable_ssm_rt_fw=0,reset_enable=0”’ >> gcu_test.conf #关闭ssm rfw功能和reset功能
sudo modprobe enflame -C ./gcu_test.conf #以指定配置文件的方式重新加载驱动
lsmod | grep enflame #确认驱动加载成功
cat /sys/module/enflame/parameters/reset_enable #验证模块参数是否生效
cat /sys/module/enflame/parameters/enable_sip_timeout_interval_ms #验证是否修改成功
以上是一次性修改,如果需要长期生效,可直接修改/etc/modprobe.d/gcu.conf。
1.6. 卸载kmd¶
临时卸载
lsmod | grep enflame ; sudo rmmod enflame
永久卸载
sudo ./enflame-xxx.run --uninstall
1.7. 常用调试功能¶
查看当前KMD的版本¶
cat /sys/module/enflame/version
查看当前KMD的模块参数¶
cat /sys/module/enflame/parameters/*
查看所有GCU设备的PCI设备号¶
sudo update-pciids ; lspci -nD | grep -e 1ea0 -e 1e36
查看GCU上各个firmware的版本¶
cat /sys/module/enflame/drivers/pci:enflame/0000:01:00.0/fw_informations
或
cat /sys/class/enflame/gcu0/device/fw_informations
查看KMD日志¶
dmesg # 当前的kernel log
cat /var/log/kern.log # 最近几天的kernel log
zcat /var/log/kern.log.*.gz # 更久以前的kernel log
防火墙相关¶
与ecc类似,防火墙也是一个与硬件绑定的功能,加载驱动时,会判断新FW和GCU上当前的防火墙状态,两者一致时才会根据防火墙状态加载对应的驱动,完成设备初始化。
芯片支持范围
仅i20支持防火墙功能。
安全寄存器列表
安全寄存器指被防火墙保护的寄存器,其地址范围可通过下述命令查看。
cat /sys/kernel/debug/enflame/0/dump/dump_reg_group
被防火墙拦截寄存器读写
位于安全寄存器地址空间的寄存器,读操作会得到0xFFFFFFFF的结果,写操作将被防火墙忽略。
KMD standby相关¶
做错误定位时涉及到KMD、FIRMWARE、TOOLS,为了快速缩小问题范围,可以开启该功能以确定是否为驱动Bug.
禁用/允许IOCTL
禁用IOCTL后,除whitelist外任何工具或UMD调用KMD IOCTL的命令会失败返回
sudo echo 1 > /sys/class/enflame/gcu0/device/standby/disable_ioctl
sudo echo 0 > /sys/class/enflame/gcu0/device/standby/disable_ioctl
添加/删除whitelist
在禁用IOCTL后,允许在whitelist中的工具或UMD调用KMD IOCTL
sudo echo "add:efvs" > /sys/class/enflame/gcu0/device/standby/whitelist
sudo echo "delete:efvs" > /sys/class/enflame/gcu0/device/standby/whitelist
suspend/resume KMD中的线程(gcu_sched_func,gcu_poll_task_func)
使用该接口会让KMD中的线程(gcu_sched_func,gcu_poll_task_func)进入睡眠状态
sudo echo 1 > /sys/class/enflame/gcu0/device/standby/suspend_thread
sudo echo 0 > /sys/class/enflame/gcu0/device/standby/suspend_thread
Attention
该接口不会停用gcu_ih_process_work_func线程。如果需要停用该线程,请在驱动加载时,添加参数irq_poll_interval=0
使用举例
sudo echo "add:efvs" > /sys/class/enflame/gcu0/device/standby/whitelist
sudo echo 1 > /sys/class/enflame/gcu0/device/standby/disable_ioctl
sudo echo 1 > /sys/class/enflame/gcu0/device/standby/suspend_thread
bypass kmd and debug
sudo echo 0 > /sys/class/enflame/gcu0/device/standby/disable_ioctl
sudo echo 0 > /sys/class/enflame/gcu0/device/standby/suspend_thread
sudo echo "delete:efvs" > /sys/class/enflame/gcu0/device/standby/whitelist
power stock相关¶
某些情况下,用户希望手动干预KMD预设的power stock值,相关接口如下
sysfs接口
使用sysfs可以在加载驱动后,动态管理power stock功能,在各种安装方式下都可以使用
enable_power_stock,查询/修改RPM开启状态,1 表示power stock功能开启,0 表示关闭
sudo cat /sys/class/enflame/gcu0/device/power_stock/enable_power_stock sudo echo 1 > /sys/class/enflame/gcu0/device/power_stock/enable_power_stock
运行时低功耗(RPM)相关¶
某些情况下,用户希望手动干预KMD预设的低功耗管理功能,相关接口如下
sysfs接口
使用sysfs可以在加载驱动后,动态管理RPM功能,在各种安装方式下都可以使用
查询/修改RPM开启状态,start 表示RPM功能开启,stop表示RPM关闭
sudo cat /sys/class/enflame/gcu0/device/rpm/switch sudo echo "start" > /sys/class/enflame/gcu0/device/rpm/switch
查询/修改设备参数,idle多久后会进入低功耗状态,单位ms,默认值120000
sudo cat /sys/class/enflame/gcu0/device/rpm/rpm_delay sudo echo 100000 > /sys/class/enflame/gcu0/device/rpm/rpm_delay
查询设备是否在低功耗状态,suspended低功耗状态,active正常工作状态
sudo cat /sys/class/enflame/gcu0/device/rpm/status
查询使用设备的进程数量,数量为0表示没有进程使用该设备
sudo cat /sys/class/enflame/gcu0/device/rpm/usage_count
查询/修改不进入usage_count计数的白名单
sudo cat /sys/class/enflame/gcu0/device/rpm/whitelist sudo echo add:name0 > /sys/class/enflame/gcu0/device/rpm/whitelist sudo echo delete:name0 > /sys/class/enflame/gcu0/device/rpm/whitelist
查询设备自加载驱动以来总共的active时间
sudo cat /sys/class/enflame/gcu0/device/rpm/active_time
查询设备自加载驱动以来总共的suspended时间
sudo cat /sys/class/enflame/gcu0/device/rpm/suspended_time
查询设备自加载驱动以来总共的suspend次数
sudo cat /sys/class/enflame/gcu0/device/rpm/suspend_count
查询设备自加载驱动以来总共的wake up次数
sudo cat /sys/class/enflame/gcu0/device/rpm/wakeup_count
查询最后一个使用该设备的进程结束后,距离现在多久,单位ms
sudo cat /sys/class/enflame/gcu0/device/rpm/last_busy
替换run包中固件¶
当需要更换run包中的firmware二进制文件时,可以参考下述方法。
在Windows上更新run包里的固件
在windows上,用7z打开run包。
进入固件所在目录,比如ef_blob/firmwares/enflame_ucode_bin/Dorado/I20。
删除指定的固件,例如hcvg_signed.bin,再拖入新的固件文件,关闭窗口生成新的run包。
安装新的run包。
与原生run不同,安装改过文件的run包时,必须指定”忽略MD5检查”,否则安装失败。
sudo SETUP_NOCHECK=1 ./enflame-1.21rc6-hcvg428.run --with-ssm --no-dkms --no-auto-load
检查firmware版本是否符合预期,使用如下命令:
cat /sys/bus/pci/devices/*/fw_informations
在Linux上更新run包里的固件
1.准备要替换的FW,比如HCVG:
提取ZX_HCVG_FW_4_6_0.tar.gz里的iram.bin,保存为hcvg_iram.ucode。
提取ZX_HCVG_FW_4_6_0.tar.gz里的dram.bin,保存为hcvg_dram.ucode。
提取ZX_HCVG_FW_4_6_0.tar.gz里的hcvg_signed.bin,保存为 hcvg_signed.bin。
2.设置以下变量:
OLD_PKG=enflame-x86_64-20220506-1891-g3848234 NEW_PKG=$OLD_PKG.tmp1 ENFLAME_TOPS_DIR=~/Projects/tops NEW_FW_DIR=~/Projects/hcvg_bins VENDOR_NAME=enflame
3.解压run包:
sudo rm -rf $NEW_PKG $NEW_PKG.run ./$OLD_PKG.run --keep --target $NEW_PKG --noexec --noexec-cleanup --nochown
4.替换FW:
rm -f $NEW_PKG/ef_blob/firmwares/enflame_ucode_bin/Dorado/I20/hcvg_iram.ucode rm -f $NEW_PKG/ef_blob/firmwares/enflame_ucode_bin/Dorado/I20/hcvg_dram.ucode rm -f $NEW_PKG/ef_blob/firmwares/enflame_ucode_bin/Dorado/I20/hcvg_signed.bin cp ./hcvg_iram.ucode $NEW_PKG/ef_blob/firmwares/enflame_ucode_bin/Dorado/I20/ cp ./hcvg_dram.ucode $NEW_PKG/ef_blob/firmwares/enflame_ucode_bin/Dorado/I20/ cp ./hcvg_signed.bin $NEW_PKG/ef_blob/firmwares/enflame_ucode_bin/Dorado/I20/
5.重新制作新的run包:
$ENFLAME_TOPS_DIR/kmd/release/makeself.sh "$NEW_PKG" "$NEW_PKG.run" "$VENDOR_NAME linux Software Package" "./install_hook.sh" "KMD_PROJ=0xff" "VENDOR_NAME=${VENDOR_NAME}"
6.运行新的run包,检查FW版本:
sudo rmmod enflame sudo ./$NEW_PKG.run --no-dkms --no-auto-load cat /sys/bus/pci/devices/*/fw_informations
1.8. FAQ¶
KMD编译失败¶
KMD编译失败,出现类似如下log:
此时,请先在host机器上安装对应的kernel header,再次编译KMD即可。
sudo apt-get install linux-headers-`uname -r`
模块正在使用而无法卸载¶
查找正在使用gcu驱动的内核模块
lsmod | grep enflame
下图表示enflame模块正在被enflame_test模块使用,需先 rmmod enflame_test。
查找正在使用gcu驱动的进程
X=(); for a in $(mount | cut -d' ' -f3); do test -e "$a" || X+=("-e$a"); done ; lsof "${X[@]}" -f -- /dev/gcu*
ps -aux | grep gcu
kill -9 <进程ID>
Attention
如果出现进程杀不掉,则可能是docker使用方式不对
enflame_peer_mem驱动加载失败¶
enflame_peer_mem驱动加载失败,kernel.log显示如下:
原因:openibd服务异常导致的问题。
检查openibd状态
/etc/init.d/openibd status
重启openibd服务
/etc/init.d/openibd restart
openibd服务重启后,再次加载enflame_peer_mem驱动即可。
KMD device id与PCI bdf对应关系¶
# 以0000:01:00.0为例
cat /sys/bus/pci/devices/0000\:01\:00.0/device_id
确定对应关系的方法如下图:
注意:device_id是kmd的逻辑设备号,每次加载kmd后可能与上次不同。
KMD ioctl版本号使用说明¶
获取ioctl版本号的方法:
通过kmd提供的sys 文件节点:’/sys/module/enflame/drivers/pci:enflame/gcu_ioctl_version’
Attention
获取kmd版本号:’cat /sys/module/enflame/version’
2. KMD的ioctl版本号格式为:major.minor.patch 含义分别为:
major: 主版本号,当兼容性发生变化时,会修改此段
minor: 次版本号,当有额外的ioctl命令增加时,会修改此段
patch: 修订版本号,当kmd修复bug时,会修改此段
1.9. 相关参考¶
reset种类¶
cold reset: reset from PWROK PAD
cat /sys/bus/pci/devices/xxx/power/control
warm reset: Button reset from BRST# PAD or PCIE PERST# from PCIE slot
echo 1 > /sys/bus/pci/devices/xxx/remove sleep 1 echo 1 > /sys/bus/pci/devices/xxx/rescan
Attention
rescan会在相应的卡上重新加载kmd驱动
PCIe hot/link-down reset:与warm reset类似,会复位除PCIe controller外的其它所有IP。而PCIe controller会被内部复位。
#直接操作 bridge port dev=0000:01:00.0 port=$(basename $(dirname $(readlink "/sys/bus/pci/devices/$dev"))) [ -e "/sys/bus/pci/devices/$port" ] && { bc=$(setpci -s $port BRIDGE_CONTROL) setpci -s $port BRIDGE_CONTROL=$(printf "%04x" $((0x$bc | 0x40))) sleep 0.01 setpci -s $port BRIDGE_CONTROL=$bc sleep 0.5 }
PCIe FLR:向PCIe cfg space的FLR位写1,PCIe controller将触发SSM MCU中断,SSM来执行FLR reset sequence。
echo 1 > /sys/bus/pci/devices/xxx/reset
Attention
Leo/Pavo不支持FLR,向reset写1时,会fallback至hot reset。Dorado FLR是不带NOC的FLR。
BLR:Driver直接给SSM发带参数的命令,SSM来执行指定单个block的reset,包括 “All IPs”/Cluster/VG/HCVG/VDEC。
Reset GCU的几种方法¶
Docker内,使用如下命令重新加载指定的驱动。
echo 1 > /sys/bus/pci/rescan
Docker内。
efsmi -F -r -i [ID]
Docker或Host内,hot reset某个设备,如gcu0(0000:01:00.0)。
echo 1 > /sys/class/enflame/gcu0/device/gcu_reload 或者 echo 1 > /sys/bus/pci/devices/0000:01:00.0/gcu_reload
Host内,参考 修改KMD的模块参数,重新加载KMD,且只使能指定的卡。
gcu_whitelist_str=00:01.0