需要明确的是,我预计会有麻烦。该计算机是旧的 HP Z820(当然不支持 NVMe 的 BIOS),具有最新的 2018 BIOS 更新。该棒是一种新的(-ish?)西部数据(Sandisk)型号:
西数黑色 500GB NVMe 固态硬盘 - M.2 2280 - WDS500G2X0C
安装在 PCIe 3.0 x4 卡上:
Mailiya M.2 PCIe 转 PCIe 3.0 x4 适配器
我不想从 NVMe 启动,只是用于存储。Linux 确实可以看到驱动器(通过 lsblk 和 lspci)并且可以读取……但不能写入。
这是 Ubuntu 18.04.2 LTS,内核版本为:
Linux brutus 4.15.0-46-generic #49-Ubuntu SMP 2 月 6 日星期三 09:33:07 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
(也在 18.10 进行了测试。)
提取了该版本以及当前 5.0 Linux 的 Linux 源代码(来自 Github 上的 torvalds/linux)。Ubuntu LTS 和当前版本之间的驱动程序/nvme 存在显着差异,最新(!)更新为昨天(2019 年 3 月 16 日“cd drivers/nvme ; git log”)。
就像我一开始说的,期待麻烦。:)
应该提到的是,我对 Linux 设备驱动程序有点熟悉,编写过一个中等复杂度的驱动程序。
尝试编译当前的 Linux 5.0 源代码和“rmmod nvme ; insmod nvme” - 这不起作用(毫不奇怪)。尝试将 5.0 nvme 驱动程序复制到 4.15 树中并编译 - 但这不起作用(也不足为奇,但是嘿,必须尝试一下)。
下一个练习是启动当前的 Linux 5.0 内核。但不妨将其公开,以防其他人更进一步。
读取工作正常,但比预期慢:
# hdparm -t --direct /dev/nvme0n1
/dev/nvme0n1:
Timing O_DIRECT disk reads: 4840 MB in 3.00 seconds = 1612.83 MB/sec
# dd bs=1M count=8192 if=/dev/nvme0n1 of=/dev/null
8192+0 records in
8192+0 records out
8589934592 bytes (8.6 GB, 8.0 GiB) copied, 4.57285 s, 1.9 GB/s
Run Code Online (Sandbox Code Playgroud)
写入严重失败:
# dd bs=1M count=2 if=/dev/zero of=/dev/nvme0n1
(hangs)
Run Code Online (Sandbox Code Playgroud)
来自journalctl:
Mar 17 18:49:23 brutus kernel: nvme nvme0: async event result 00010300
Mar 17 18:49:23 brutus kernel: print_req_error: I/O error, dev nvme0n1, sector 0
Mar 17 18:49:23 brutus kernel: buffer_io_error: 118 callbacks suppressed
Mar 17 18:49:23 brutus kernel: Buffer I/O error on dev nvme0n1, logical block 0, lost async page write
[snip]
Mar 17 18:49:23 brutus kernel: print_req_error: I/O error, dev nvme0n1, sector 1024
Mar 17 18:49:23 brutus kernel: print_req_error: I/O error, dev nvme0n1, sector 3072
Run Code Online (Sandbox Code Playgroud)
使用“nvme”命令行工具进行了一些探索,但只是猜测:
# nvme list -o json
{
"Devices" : [
{
"DevicePath" : "/dev/nvme0n1",
"Firmware" : "101140WD",
"Index" : 0,
"ModelNumber" : "WDS500G2X0C-00L350",
"ProductName" : "Unknown Device",
"SerialNumber" : "184570802442",
"UsedBytes" : 500107862016,
"MaximiumLBA" : 976773168,
"PhysicalSize" : 500107862016,
"SectorSize" : 512
}
]
Run Code Online (Sandbox Code Playgroud)
仅供参考 - lspci 输出:
03:00.0 Non-Volatile memory controller: Sandisk Corp Device 5002 (prog-if 02 [NVM Express])
Subsystem: Sandisk Corp Device 5002
Physical Slot: 1
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 64 bytes
Interrupt: pin A routed to IRQ 37
NUMA node: 0
Region 0: Memory at de500000 (64-bit, non-prefetchable) [size=16K]
Region 4: Memory at de504000 (64-bit, non-prefetchable) [size=256]
Capabilities: [80] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [90] MSI: Enable- Count=1/32 Maskable- 64bit+
Address: 0000000000000000 Data: 0000
Capabilities: [b0] MSI-X: Enable+ Count=65 Masked-
Vector table: BAR=0 offset=00002000
PBA: BAR=4 offset=00000000
Capabilities: [c0] Express (v2) Endpoint, MSI 00
DevCap: MaxPayload 512 bytes, PhantFunc 0, Latency L0s <1us, L1 unlimited
ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset+ SlotPowerLimit 0.000W
DevCtl: Report errors: Correctable+ Non-Fatal+ Fatal+ Unsupported+
RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop+ FLReset-
MaxPayload 256 bytes, MaxReadReq 1024 bytes
DevSta: CorrErr+ UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend-
LnkCap: Port #0, Speed 8GT/s, Width x4, ASPM L1, Exit Latency L0s <256ns, L1 <8us
ClockPM+ Surprise- LLActRep- BwNot- ASPMOptComp+
LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- CommClk+
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
LnkSta: Speed 8GT/s, Width x4, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
DevCap2: Completion Timeout: Range B, TimeoutDis+, LTR+, OBFF Not Supported
DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-, LTR-, OBFF Disabled
LnkCtl2: Target Link Speed: 8GT/s, EnterCompliance- SpeedDis-
Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
Compliance De-emphasis: -6dB
LnkSta2: Current De-emphasis Level: -3.5dB, EqualizationComplete+, EqualizationPhase1+
EqualizationPhase2+, EqualizationPhase3+, LinkEqualizationRequest-
Capabilities: [100 v2] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
AERCap: First Error Pointer: 00, GenCap+ CGenEn- ChkCap+ ChkEn-
Capabilities: [150 v1] Device Serial Number 00-00-00-00-00-00-00-00
Capabilities: [1b8 v1] Latency Tolerance Reporting
Max snoop latency: 0ns
Max no snoop latency: 0ns
Capabilities: [300 v1] #19
Capabilities: [900 v1] L1 PM Substates
L1SubCap: PCI-PM_L1.2- PCI-PM_L1.1- ASPM_L1.2+ ASPM_L1.1- L1_PM_Substates+
PortCommonModeRestoreTime=255us PortTPowerOnTime=10us
L1SubCtl1: PCI-PM_L1.2- PCI-PM_L1.1- ASPM_L1.2- ASPM_L1.1-
T_CommonMode=0us LTR1.2_Threshold=0ns
L1SubCtl2: T_PwrOn=10us
Kernel driver in use: nvme
Kernel modules: nvme
Run Code Online (Sandbox Code Playgroud)
呵呵。信用到期。:)
preston@brutus:~/sources/linux/drivers/nvme$ git log . | grep -i 'wdc.com\|@sandisk' | sed -e 's/^.*: //' | sort -uf
Adam Manzanares <adam.manzanares@wdc.com>
Bart Van Assche <bart.vanassche@sandisk.com>
Bart Van Assche <bart.vanassche@wdc.com>
Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
Jeff Lien <jeff.lien@wdc.com>
Run Code Online (Sandbox Code Playgroud)
还使用当前(2019.03.17)Linux 内核进行了测试:
root@brutus:~# uname -a
Linux brutus 5.1.0-rc1 #1 SMP Mon Mar 18 01:03:14 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
root@brutus:~# pvcreate /dev/nvme0n1
/dev/nvme0n1: write failed after 0 of 4096 at 4096: Input/output error
Failed to wipe new metadata area at the start of the /dev/nvme0n1
Failed to add metadata area for new physical volume /dev/nvme0n1
Failed to setup physical volume "/dev/nvme0n1".
Run Code Online (Sandbox Code Playgroud)
来自期刊:
Mar 18 02:05:10 brutus kernel: print_req_error: I/O error, dev nvme0n1, sector 8 flags 8801
Mar 18 02:09:06 brutus kernel: print_req_error: I/O error, dev nvme0n1, sector 8 flags 8801
Mar 18 02:09:36 brutus kernel: print_req_error: I/O error, dev nvme0n1, sector 8 flags 8801
Run Code Online (Sandbox Code Playgroud)
所以......看起来还不能在任何版本的 Linux 上工作。
小智 1
我不知道你是否仍然遇到这些问题,但我至少会发布这个以防其他人遇到它。
我有这个相同的驱动器,并将其用作运行 18.04 的主驱动器。我已经使用了 Windows 固件实用程序,但到目前为止还没有看到任何更新。我还测试了 19.04 的实时环境,它与 18.04 和 18.10 遇到的冻结/安装失败相同,因此问题似乎仍然存在。
问题似乎是驱动器在进入低功耗状态时变得不稳定,因此修复方法是通过内核启动参数禁用低功耗模式。几个月前我就这么做了,从那以后 18.04 就出现了零问题。此方法应该也适用于新版本(18.10/19.04),但遗憾的是它尚未修复。
在 GRUB 启动菜单中,按e编辑启动参数。nvme_core.default_ps_max_latency_us=5500在安静启动结束时
添加Ctrl-x要启动,安装程序应在分区步骤中检测到该磁盘。
安装完成后,shift开机按再次进入GRUB,添加相同的内核参数nvme_core.default_ps_max_latency_us=5500,Ctrl-x即可启动。你会看到Ubuntu启动成功,编辑,再次/etc/default/grub添加参数,执行。这样每次开机都会自动在grub中包含这个参数,无需再手动编辑。nvme_core.default_ps_max_latency_us=5500sudo update-grub
https://community.wd.com/t/linux-support-for-wd-black-nvme-2018/225446/9
小智 1
使用列出驱动器支持的电源状态smartctl -a /dev/nvme0。
支持的电源状态
St Op 最大活动空闲 RL RT WL WT Ent_Lat Ex_Lat
找到Ex_Lat您想要允许驱动器进入的最低功耗状态的值。如果您遇到问题,您可能希望允许倒数第二个电源状态,但不是最后一个。假设倒数第二个电源状态的Ex_Lat值为10000(与 WDS500G2X0C 上相同)。
您可以添加nvme_core.default_ps_max_latency_us=10000为内核参数。
如果您采用了 grub 路线并且更新/etc/default/grub不起作用,您可能需要更新/etc/default/grub.d/.
您可以通过运行来检查系统启动时使用的参数cat /proc/cmdline,并查看它是否包含您的更改。
| 归档时间: |
|
| 查看次数: |
4551 次 |
| 最近记录: |