问题
我想在Linux上的SSD磁盘内的交换分区上启用后台 TRIM操作。根据几篇文章(例如,这篇文章),内核会检测到此配置并自动执行丢弃操作,但是在我的测试中,尽管使用了“丢弃”安装选项来强制执行此行为,但它似乎无法正常工作。
情境
- 运行Linux 3.2.0的Debian Wheezy
- SSD磁盘:1 x 120GB OCZ Vertex 3 MI
- 2GB交换“普通”分区,不带其他层(LVM,RAID等)
背景
这些是我检查后台TRIM是否在交换分区上工作的步骤:
TRIM支持:检查SSD磁盘是否支持TRIM命令,并且内核将设备标记为不可旋转:
# hdparm -I /dev/sda | grep TRIM * Data Set Management TRIM supported (limit 1 block) * Deterministic read data after TRIM # cat /sys/block/sda/queue/rotational 0
交换填充:挂载分区,清理所有VM高速缓存,并将Linux配置为主动进行交换,将vm.swappiness设置为100。然后,运行一个分配所有可用内存并强制内核开始交换的脚本:
# swapon [--discard] /dev/sda2 # echo 3 > /proc/sys/vm/drop_caches # echo 100 > /proc/sys/vm/swappiness # ./fill-up-memory.up
该脚本在具有32GB物理内存+ 2GB交换分区的服务器上运行,并在内存中创建〜33.8GB对象,这足以填满所有内存并开始交换。这是实现此行为的脚本的示例:
#!/usr/bin/python mem = 33.8 testing = 'A' * int(1024 * 1024 * 1024 * mem) raw_input()
检查交换内容:“ swapon -s”表明已使用100%的交换内存。使用“ hdparm --read-sector”检查交换分区扇区的原始内容,并将所有字节设置为“ 4141”,并为“ A”字符使用相应的十六进制表示法,所有操作均按预期进行。这是一个脚本示例,用于逐扇区读取交换分区的内容:
#!/bin/bash for sector in `seq 194560 4100095` ; do hdparm --read-sector $sector /dev/sda done
注意:您可以使用parted,cfdisk等获取交换分区的开始/结束扇区。
当我停止脚本时,它将释放所有内存,包括交换分配,“ swapon -s”在系统中不返回任何交换使用情况。在这一点上,预计Linux将在后台开始丢弃交换分区的内容,但是它不起作用,甚至在几个小时之后,扇区的内容仍为“ 4141”。
我进行了几次测试,似乎Linux仅在使用swapon()
系统调用启用分区时才执行完全丢弃,而从不在后台执行,尽管在/ etc / fstab上启用了“丢弃”安装选项。
进一步的研究:blkdev_issue_discard()是负责向底层SSD设备发送TRIM命令的内核函数,该函数在mm/swapfile.c
以下位置有两个唯一的引用:
discard_swap()
它在swapon()过程中被调用,如果启用了“ discard”挂载选项,它将丢弃所有内容,这将按预期工作。discard_swap_cluster()
它应该丢弃集群交换的内容,但似乎它从不执行TRIM命令。
问题:交换+ SSD设备上Linux的预期行为是什么?在启动过程中启用分区时,它应该丢弃所有空闲扇区/页面还是仅发出初始完全丢弃?谢谢。