Open BarsMonster opened 2 years ago
Any updates on this?
Any updates on this?
Still reproduces in Windows Version 10.0.22621.1778 / Kernel 6.1.21.2-microsoft-standard-WSL2
AFAIK, this is not a WSL specfic issue but a flaw resides in the core of Windows. I believe you were experiencing it because the drive is an NVMe drive.
Unlike Linux, Windows still retain a SCSI-NVMe translation layer for NVMe drives. When an NVMe drive is exposed / passsd-through to a Hyper-V VM (hence WSL), it's actually the translation layer being exposed, which is why you'll see /dev/sdX
instead of /dev/nvmeXnY
.
It is actually the same case for SATA drives. However, the SATL is "generated"/"emulated" by different code, and its code is fine.
The problematic field/bit in the SNTL resides in its reponse for the SCSI READ CAPACITY (16) command. It should have the LBPME bit set for drives support TRIM, yet it doesn't.
You can see a few place in the SCSI disk driver where it will continue to perform TRIM-related probing/configuration only if the LBPME bit is set: https://github.com/microsoft/WSL2-Linux-Kernel/blob/linux-msft-wsl-5.15.y/drivers/scsi/sd.c
I've reported this through Windows Feedback a few years ago, but never got any response.
P.S. If you are attaching a USB/UAS drive, then it's the problem of the bridge chip, which is where the SATL/SNTL implemented in such cases. I have yet to see any bridge chip have the LBPME bit set. The main reason is probably because Windows does not care about the bit, while Linux dev insist the importance of checking the bit as per the SCSI specs mandate. (I had a discussion with them on the linux-scsi mailing list.)
FYI, you can "enable" it manually through the provisioning_mode
sysfs file (use find
to find it). Just write unmap
to it. (But yeah it gets reset whenever the WSL shuts down. So you may want to find a way to automatically change it every time.)
@tomty89 Thanks for this very detailed explanation!
In this case drives are Samsung 850 Pro - which are SATA drives. I will read more about provisioning_mode, thanks for the hint!
Hmm, that's weird then. Maybe it's a different problem in your case? I assume they are directly attached to a SATA port (instead of some USB enclosure/adapter)?
Would be great if you can install sg3-utils
and share the outputs of sg_readcap -l /dev/sdX
and sg_vpd -a /dev/sdX
.
@tomty89 Here it goes. Apparently it reports that TRIM is supported, but lsblk -D insists that it's not. Disks are connected to SATA ports on the motherboard (X570 chipset).
VPD:
Supported VPD pages VPD page:
Supported VPD pages [sv]
Unit serial number [sn]
Device identification [di]
Extended inquiry data [ei]
ATA information (SAT) [ai]
Block limits (SBC) [bl]
Block device characteristics (SBC) [bdc]
Logical block provisioning (SBC) [lbpv]
Unit serial number VPD page:
Unit serial number: [...................]
Device Identification VPD page:
Addressed logical unit:
designator type: NAA, code set: Binary
0x500253c87000ce87
extended INQUIRY data VPD page:
ACTIVATE_MICROCODE=0 SPT=0 GRD_CHK=0 APP_CHK=0 REF_CHK=0
UASK_SUP=0 GROUP_SUP=0 PRIOR_SUP=0 HEADSUP=0 ORDSUP=0 SIMPSUP=0
WU_SUP=0 [CRD_SUP=0] NV_SUP=0 V_SUP=1
NO_PI_CHK=0 P_I_I_SUP=0 LUICLR=0
LU_COLL_TYPE=0 R_SUP=0 RTD_SUP=0 HSSRELEF=1 [CBCS=0]
Multi I_T nexus microcode download=0
Extended self-test completion minutes=0
POA_SUP=0 HRA_SUP=0 VSA_SUP=0 DMS_VALID=0
Maximum supported sense data length=0
IBS=0 IAS=0 SAC=0 NRD1=0 NRD0=0
Maximum inquiry change logs=0
Maximum mode page change logs=0
DM_MD_4=0 DM_MD_5=0 DM_MD_6=0 DM_MD_7=0
DM_MD_D=0 DM_MD_E=0 DM_MD_F=0
ATA information VPD page:
SAT Vendor identification: Samsung
SAT Product identification: SSD 850 PRO 2TB
SAT Product revision level: EXM0
Device signature indicates PATA transport
Command code: 0xec
ATA command IDENTIFY DEVICE response summary:
model: Samsung SSD 850 PRO 2TB
serial number: [...................]
firmware revision: EXM04B6Q
Block limits VPD page (SBC):
Write same non-zero (WSNZ): 0
Maximum compare and write length: 0 blocks [Command not implemented]
Optimal transfer length granularity: 0 blocks [not reported]
Maximum transfer length: 0 blocks [not reported]
Optimal transfer length: 0 blocks [not reported]
Maximum prefetch transfer length: 0 blocks [ignored]
Maximum unmap LBA count: 33553920
Maximum unmap block descriptor count: 512
Optimal unmap granularity: 0 blocks [not reported]
Unmap granularity alignment valid: false
Unmap granularity alignment: 0 [invalid]
Maximum write same length: 0 blocks [not reported]
Maximum atomic transfer length: 0 blocks [not reported]
Atomic alignment: 0 [unaligned atomic writes permitted]
Atomic transfer length granularity: 0 [no granularity requirement
Maximum atomic transfer length with atomic boundary: 0 blocks [not reported]
Maximum atomic boundary size: 0 blocks [can only write atomic 1 block]
Block device characteristics VPD page (SBC):
Non-rotating medium (e.g. solid state)
Product type: Not specified
WABEREQ=0
WACEREQ=0
Nominal form factor: 2.5 inch
ZONED=0
RBWZ=0
BOCS=0
FUAB=0
VBULS=0
DEPOPULATION_TIME=0 (seconds)
Logical block provisioning VPD page (SBC):
Unmap command supported (LBPU): 1
Write same (16) with unmap bit supported (LBPWS): 0
Write same (10) with unmap bit supported (LBPWS10): 0
Logical block provisioning read zeros (LBPRZ): 0
Anchored LBAs supported (ANC_SUP): 0
Threshold exponent: 0 [threshold sets not supported]
Descriptor present (DP): 0
Minimum percentage: 0 [not reported]
Provisioning type: 0 (not known or fully provisioned)
Threshold percentage: 0 [percentages not supported]
readcap:
Read Capacity results:
Protection: prot_en=0, p_type=0, p_i_exponent=0
Logical block provisioning: lbpme=0, lbprz=0
Last LBA=4000797359 (0xee7752af), Number of logical blocks=4000797360
Logical block length=512 bytes
Logical blocks per physical block exponent=0
Lowest aligned LBA=0
Hence:
Device size: 2048408248320 bytes, 1953514.3 MiB, 2048.41 GB, 2.05 TB
Logical block provisioning: lbpme=0, lbprz=0
Meh, looks like Microsoft changed their SATL code and now the problem exists for SATA drives as well.
Device signature indicates PATA transport
This line makes me wonder if your SATA controller is not in AHCI mode (in the BIOS/UEFI setting). It might also because you are using a vendor AHCI driver (i.e., from Intel or AMD) instead of the Microsoft builtin one.
(Either way though, I doubt that you would want to change the setting / driver, since it tends to break Windows booting.)
@tomty89 In my case SATA drives are for data storage (actually, I run mdadm MDADM RAID-6 on SSD), so I will check that. Windows boots from NVMe.
Just a little warning, I heard that Intel does something weird on some platforms for NVMe drives. While I don't really understand the details, I feel like maybe you don't want to be too confident that messing with the SATA controller mode or even driver wouldn't breaks booting from NVMe drive. (I don't want to indirectly get you into troubles, heh.)
@tomty89 AHCI was already enabled, and SATA drives & SATA controllers were on Microsoft driver. Only 2 AHCI SATA controllers are present in device manager.
Logical block provisioning: lbpme=0, lbprz=0
Meh, looks like Microsoft changed their SATL code and now the problem exists for SATA drives as well.
I suppose this is the case then. Right now I don't have any machine with Windows and SATA for me to double confirm it. The reason I found this issue is because I was think maybe I can report the problem in the SNTL on this repo to get someone in Microsoft notified. I guess we can only hope that it would happen someday :-(
Kinda surprised that they broke their SATL as well.
(Btw, if you run the same command on one of the virtual drives, you'll see they have lbpme=1
.)
AFAIK, this is not a WSL specfic issue but a flaw resides in the core of Windows. I believe you were experiencing it because the drive is an NVMe drive.
Unlike Linux, Windows still retain a SCSI-NVMe translation layer for NVMe drives. When an NVMe drive is exposed / passsd-through to a Hyper-V VM (hence WSL), it's actually the translation layer being exposed, which is why you'll see
/dev/sdX
instead of/dev/nvmeXnY
.It is actually the same case for SATA drives. However, the SATL is "generated"/"emulated" by different code, and its code is fine.
The problematic field/bit in the SNTL resides in its reponse for the SCSI READ CAPACITY (16) command. It should have the LBPME bit set for drives support TRIM, yet it doesn't.
You can see a few place in the SCSI disk driver where it will continue to perform TRIM-related probing/configuration only if the LBPME bit is set: https://github.com/microsoft/WSL2-Linux-Kernel/blob/linux-msft-wsl-5.15.y/drivers/scsi/sd.c
I've reported this through Windows Feedback a few years ago, but never got any response.
P.S. If you are attaching a USB/UAS drive, then it's the problem of the bridge chip, which is where the SATL/SNTL implemented in such cases. I have yet to see any bridge chip have the LBPME bit set. The main reason is probably because Windows does not care about the bit, while Linux dev insist the importance of checking the bit as per the SCSI specs mandate. (I had a discussion with them on the linux-scsi mailing list.)
FYI, you can "enable" it manually through the
provisioning_mode
sysfs file (usefind
to find it). Just writeunmap
to it. (But yeah it gets reset whenever the WSL shuts down. So you may want to find a way to automatically change it every time.)
Thank you so much @tomty89! My mounted drive is indeed nvme but reported as /dev/sdX
in wsl. The manual method you mentioned worked for me. Was thinking of installing a small linux distr as part of a dual-boot system just to execute trim and your method saved all the hassle!
Version
Microsoft Windows [Version 10.0.22621.674]
WSL Version
Kernel Version
5.15.68.1
Distro Version
Ubuntu 22.04
Other Software
No response
Repro Steps
Expected Behavior
lsblk -D reports DISC-MAX >0B for mounted disk, which means TRIM is supported.
Actual Behavior
lsblk -D reports DISC-MAX as 0B for mounted disk, which means TRIM is not supported.
Using SSD disks without trim reduces it's lifespan, performance and reliability.
Diagnostic Logs
No response