![NVMe PCIe 磁盘电源循环](https://linux22.com/image/6141/NVMe%20PCIe%20%E7%A3%81%E7%9B%98%E7%94%B5%E6%BA%90%E5%BE%AA%E7%8E%AF.png)
我想测试连接到主板 PCIe 插槽的 NVMe SSD。测试过程是一种将工作负载写入SSD的特定算法,同时SSD暴露于辐射(例如中子)。
我运行的是 Fedora 22,内核为 4.4.6。
我当前的软件可以成功地与 SATA SSD 配合使用。由于 SSD 可能会因辐射而变得无响应,因此有时必须重新启动它才能恢复操作。这可以通过外部控制电源来实现。
现在,我想移植我的软件来测试 NVMe SSD PCIe。我修改了一个PCIe扩展器来外部给SSD施加电压;派生电源线(+12V 和 3.3V)与 PCIe 连接器电源线隔离。通过此设置,在打开外部电源的情况下启动时,SSD 可以被很好地识别并正常工作。
只要NVMe SSD上电,移除设备并重新扫描PCI总线即可,即:
echo 1 > /sys/bus/pci/devices/0000\:01\:00.0/remove
其次是:
echo 1 > /sys/bus/pci/rescan
作品。但是,如果我在移除设备后关闭电源然后再打开电源,PCI 总线rescan
将无法工作(并且 中不会出现任何消息dmesg
)。
如果我“残酷地”关闭SSD电源(使用我控制的电源)而不移除下面的SSD sysfs
,我会得到以下信息:
[ 192.688934] nvme 0000:01:00.0: Failed status: ffffffff, reset controller
[ 192.689274] Trying to free nonexistent resource <000000000000e000-000000000000e0ff>
[ 192.699900] nvme 0000:01:00.0: Refused to change power state, currently in D3
[ 192.699946] Trying to free nonexistent resource <000000000000e000-000000000000e0ff>
[ 192.699953] nvme 0000:01:00.0: Device failed to resume
显然,重新扫描 PCI 总线没有任何作用。
问题:在不重新启动测试站的情况下实现 SSD 电源循环需要什么?从类似的线程中,我了解到这个问题并非微不足道,因此我会对各种解决方案(或提示)感到满意,包括:
- 添加内核启动参数
- 命令的使用
setpci
(提示?) - 使用额外的逻辑,例如修改 PCIe 扩展器上的线路以“欺骗”PCIe 总线
- 内核源代码的修改(提示?)
答案1
这不太可能成功地让设备再次工作,但可能会让设备足够响应以响应删除。当设备正常时,保存所有 pci 配置寄存器,并在重新启动电源后恢复它们。您可以通过找到控制器插槽来实现这一点
$ lspci | grep SATA
00:1f.2 SATA controller: Intel Corporation 7 Series Chipset Family 6-port SATA Controller [AHCI mode] (rev 04)
然后列出寄存器名称并将每个寄存器名称传递给 setpci (您不需要是 root):
$ setpci --dumpregs |
awk -v slot='00:1f.2' 'NR>1 && !/ E?CAP/{
reg = tolower($NF)
printf "%s=",reg
system("setpci -s " slot " " reg)
}'
这会让你的线条像
vendor_id=8086
device_id=1e03
command=0407
status=02b0
base_address_0=0000f0b1
base_address_1=0000f0a1
base_address_2=0000f091
base_address_3=0000f081
base_address_4=0000f061
base_address_5=f7c06000
显然,其中一些寄存器是只读的,或者具有只读位。这个想法是调用sudo setpci -s "$slot"
每一行,忽略这方面。
上面仅处理基本的 pci 配置寄存器。但是,您还需要保存和恢复一些功能寄存器。这将需要更多的努力,具体取决于寄存器。您还需要成为 root 才能阅读它们。例如,
sudo setpci -s 00:1f.2 CAP_MSI+0.l CAP_MSI+4.l CAP_MSI+8.l
将打印 MSI 功能寄存器:
00017005
fee0200c
000041b1
将这些值与显示的值进行比较
sudo lspci -s "$slot" -vvv
...
Capabilities: [80] MSI: Enable+ Count=1/1 Maskable- 64bit-
Address: fee0200c Data: 41b1