惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

大猫的无限游戏
大猫的无限游戏
Webroot Blog
Webroot Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
T
Threat Research - Cisco Blogs
V2EX - 技术
V2EX - 技术
L
LINUX DO - 热门话题
Google DeepMind News
Google DeepMind News
Recorded Future
Recorded Future
S
Schneier on Security
I
InfoQ
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
The GitHub Blog
The GitHub Blog
S
Security @ Cisco Blogs
O
OpenAI News
W
WeLiveSecurity
Vercel News
Vercel News
阮一峰的网络日志
阮一峰的网络日志
Simon Willison's Weblog
Simon Willison's Weblog
人人都是产品经理
人人都是产品经理
Cloudbric
Cloudbric
The Last Watchdog
The Last Watchdog
The Hacker News
The Hacker News
Google Online Security Blog
Google Online Security Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
GbyAI
GbyAI
NISL@THU
NISL@THU
T
Tailwind CSS Blog
V
Visual Studio Blog
PCI Perspectives
PCI Perspectives
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Jina AI
Jina AI
D
DataBreaches.Net
B
Blog RSS Feed
N
News and Events Feed by Topic
N
News and Events Feed by Topic
H
Heimdal Security Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
腾讯CDC
Latest news
Latest news
V
Vulnerabilities – Threatpost
Hacker News: Ask HN
Hacker News: Ask HN
WordPress大学
WordPress大学
V
V2EX
aimingoo的专栏
aimingoo的专栏
博客园 - 司徒正美
Apple Machine Learning Research
Apple Machine Learning Research
D
Darknet – Hacking Tools, Hacker News & Cyber Security
The Register - Security
The Register - Security
Help Net Security
Help Net Security

C0reFast记事本

一个virtio-blk设备IO大小的问题 使用单台高配服务器(部署你的业务) 一个Solidigm P41 Plus的冷数据问题 测试ARP/ND双发效果的小工具 硬件Bonding卸载场景下的ARP/ND双发 “无限”套娃,在WSL的Docker中使用YOLOv11做目标检测 在三条指令内实现闰年判断 一个中断关闭时间太长导致的网络延迟问题 一个Linux新老内核对于硬件中断的统计差异 IPIP隧道导致的DPDK收包RSS队列不均匀问题 在KVM虚拟机中开启TSC作为时钟源 x86平台的TSC(TIME-STAMP COUNTER) 一个UFO引发的惨案 在RHEL系统中快速抓取火焰图 反序列化AWS/阿里云样式的基于Query的API请求 DIY一个8盘位全闪NAS 分享一个记录LSI RAID卡芯片和各个OEM对应卡型号列表的神贴 SPDK的“Reduce”块压缩算法 实现一个Kubernetes的身份认证代理服务
在移动硬盘盒上启用SSD的Trim功能
陈孚 · 2022-10-05 · via C0reFast记事本

最近折腾了一小段时间的PCDN,家里刚好有一个闲置的JetsonNano和一块闲置的SSD,刚好可以跑跑PCDN,每天挣个宽带钱。具体跑的哪家,就不说了,说说在这过程中遇到的一个小问题:一般来说,PCDN或者类似的业务,对磁盘的写入压力还是比较大的,虽然可能平均的写入带宽并不高,但是也架不住每天读写的时间相当长,虽然我这块SSD是闲置的,但好歹是个传家宝,不管怎么说,还是有那么点点心疼的,肯定是不太希望哪天这SSD被写坏了。

在这种场景下,尽可能延长SSD的写入寿命就很重要了,而方法之一呢,就是想办法把SSD的Trim命令给用上。

用上Trim命令之前,可以先简单了解一下背后的逻辑,具体的可以参考Wiki,简单来说呢,因为SSD依赖垃圾回收机制来平衡NAND的磨损,但是呢具体到一整个LBA空间,只有文件系统知道哪些数据块是有效数据,所以就需要通过Trim命令,建立文件系统空闲空间和SSD底层数据块的关联,从而让SSD的主控更好的进行垃圾回收操作,一般来说,合理的使用Trim,可以有效的提高SSD的性能和寿命。当然了,Trim命令是ATA指令集里的,也就是SATA接口SSD才会有,对于SCSI以及SAS接口SSD,还有NVMe SSD来说,也有相应的UNMAPDeallocate指令,作用都是一样的。

一般来说,在Linux下,一个设备是否支持Trim操作,可以通过lsblk --discard进行查看,当输出中的DISC-GRANDISC-MAX列不为0时,说明这个设备是支持Trim操作的:

jetson-nano:chenfu:# lsblk --discard
NAME        DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
sda                0        0B       0B         0
mmcblk1            0        4M      76M         0
└─mmcblk1p1        0        4M      76M         0

比如在我这个JetsonNano上,可以看到我外接的这块SSD硬盘,对应sda设备是不支持Trim的,但是mmcblk1这个设备,也就是装系统用的一个小的MicroSD卡是支持的。

那么问题来了,针对上面的输出,sda这块盘是不支持Trim的,那怎么样才能让他支持呢?

首先需要明确的是,因为这块盘是我通过一块USB移动硬盘盒转接到板子上的,也就意味着这块硬盘并没有用原生的SATA接口(当然这块开发版本身也不支持SATA接口)。而对于移动硬盘盒而言,将SATA口转换成USB口,会需要一个桥接芯片进行协议的转换,那么桥接芯片是否支持Trim命令的转换,就显得非常重要了。对于一些老的移动硬盘盒,大多使用的是Mass Storage Class Bulk-Only Transport (BOT)这个协议,但是对于一些比较新的桥接芯片,基本都会支持一个新的叫做USB Attached SCSI Protocol (UASP) 的新协议。所以我也查了一些资料,同样也是结合产品页的一些宣传,买了一个支持UAS协议的移动硬盘盒,根据评论看,这个硬盘盒是支持Trim的,但是大部分用户似乎都是在Windows下进行测试的,在Linux下是否真的支持,是否需要新版本内核或者驱动的支持还不知道。

等硬盘盒到手,插上之后系统lsusb看了一下:

jetson-nano:~:% lsusb
Bus 002 Device 002: ID 174c:225c ASMedia Technology Inc. Ugreen Storage Device

VendorId是0x174c,也就是ASMedia公司的桥接芯片,但是225c这个ProductId并没有在USB ID数据库里查到,不过从数据库里看0x1153这个ProductId对应ASM1153这款芯片来说,那225c应该是对应着ASM225CM这个芯片?从目前的资料看,这个芯片理论上是支持Trim的,至少可以通过刷新固件来解决支持的问题。

然而系统识别出sda之后,lsblk --discard依然提示不支持Trim。

于是又搜索了一些资料,终于在Arch的SSD Wiki里找到了一些信息:

其实现在一些USB转SATA芯片(如VL715、VL716等)以及在外接NVMe硬盘盒(如IB-1817M-C31)中使用的USB转PCIe芯片(如 智微(JMicron) JMS583 )支持类似TRIM的命令。这些命令可通过 USB Attached SCSI 驱动程序(在Linux下称为”uas”)发送。然而内核可能不会自动检测到并启用这一功能。

会不会是因为芯片是支持的,但是系统默认没有开启呢?于是按Wiki里的说法,使用sg_readcap -l /dev/sda命令读取设备的标志位:

jetson-nano:chenfu:# sg_readcap -l /dev/sda
Read Capacity results:
   Protection: prot_en=0, p_type=0, p_i_exponent=0
   Logical block provisioning: lbpme=0, lbprz=0
   Last LBA=937703087 (0x37e436af), Number of logical blocks=937703088
   Logical block length=512 bytes
   Logical blocks per physical block exponent=0
   Lowest aligned LBA=0
Hence:
   Device size: 480103981056 bytes, 457862.8 MiB, 480.10 GB

发现Logical block provisioning: lbpme=0, lbprz=0其中lbpme=0,因为LBPME位为0,所以内核默认是不会开启DISCARD的支持。针对这种情况,还需要继续通过sg_vpd -a /dev/sda命令查询设备支持的命令情况:

jetson-nano:chenfu:# sg_vpd -a /dev/sda
Supported VPD pages VPD page:
  ...
Unit serial number VPD page:
  Unit serial number: 704108E11D02

Device Identification VPD page:
  Addressed logical unit:
    designator type: NAA,  code set: Binary
      0x5000000000000001

Block limits VPD page (SBC):
  Write same non-zero (WSNZ): 0
  ...

Block device characteristics VPD page (SBC):
  Non-rotating medium (e.g. solid state)
  ...
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]

可以发现在Logical block provisioning VPD page (SBC)段下,有Unmap command supported (LBPU): 1,说明设备本身是支持Unmap指令的,因为前面说到,ATA中的Trim其实就是对应的SCSI中的UNMAP,所以支持UNMAP也就是支持了Trim,当然这中间的转换过程,应该是有硬盘盒的主控来完成。

那既然在物理上是支持Trim的,那剩下的就是逻辑上怎么启用的问题了,先看下目前内核识别的设备的provisioning_mode:

jetson-nano:chenfu:# cat /sys/block/sda/device/scsi_disk/0:0:0:0/provisioning_mode
full

可以发现输出是full,也就是说内核当前是没有检测到设备支持Trim特性,解决方法也比较简单,直接echo unmap到这个文件:

jetson-nano:chenfu:# echo unmap > /sys/block/sda/device/scsi_disk/0:0:0:0/provisioning_mode
jetson-nano:chenfu:# lsblk --discard
NAME        DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
sda                0      512B       4G         0
mmcblk1            0        4M      76M         0
└─mmcblk1p1        0        4M      76M         0

可以看到,强制指定provisioning_mode为unmap之后,lsblk --discard的输出已经提示sda设备支持Trim了。

最后,为了能让这个特性可以在插入硬盘盒的时候自动生效,可以手动编写一个Udev的规则文件:

echo 'ACTION=="add|change", ATTRS{idVendor}=="174c", ATTRS{idProduct}=="225c", SUBSYSTEM=="scsi_disk", ATTR{provisioning_mode}="unmap"' >>/etc/udev/rules.d/10-uas-discard.rules

也就是说,当有idVendor为174c,idProduct为225c的设备(也就是我的这个硬盘盒)连接的时候,自动设置provisioning_mode为unmap。