我正在研究2.6.35.9版本的Linux内核,并尝试禁用命令完成合并。
lspci
的输出如下所示:
00:00.0 Host bridge: Intel Corporation 82P965/G965 Memory Controller Hub (rev 02)
00:01.0 PCI bridge: Intel Corporation 82P965/G965 PCI Express Root Port (rev 02)
00:19.0 Ethernet controller: Intel Corporation 82566DC Gigabit Network Connection (rev 02)
00:1a.0 USB Controller: Intel Corporation 82801H (ICH8 Family) USB UHCI Controller #4 (rev 02)
00:1a.1 USB Controller: Intel Corporation 82801H (ICH8 Family) USB UHCI Controller #5 (rev 02)
00:1a.7 USB Controller: Intel Corporation 82801H (ICH8 Family) USB2 EHCI Controller #2 (rev 02)
00:1c.0 PCI bridge: Intel Corporation 82801H (ICH8 Family) PCI Express Port 1 (rev 02)
00:1c.4 PCI bridge: Intel Corporation 82801H (ICH8 Family) PCI Express Port 5 (rev 02)
00:1d.0 USB Controller: Intel Corporation 82801H (ICH8 Family) USB UHCI Controller #1 (rev 02)
00:1d.1 USB Controller: Intel Corporation 82801H (ICH8 Family) USB UHCI Controller #2 (rev 02)
00:1d.2 USB Controller: Intel Corporation 82801H (ICH8 Family) USB UHCI Controller #3 (rev 02)
00:1d.7 USB Controller: Intel Corporation 82801H (ICH8 Family) USB2 EHCI Controller #1 (rev 02)
00:1e.0 PCI bridge: Intel Corporation 82801 PCI Bridge (rev f2)
00:1f.0 ISA bridge: Intel Corporation 82801HH (ICH8DH) LPC Interface Controller (rev 02)
00:1f.2 RAID bus controller: Intel Corporation 82801 SATA RAID Controller (rev 02)
00:1f.3 SMBus: Intel Corporation 82801H (ICH8 Family) SMBus Controller (rev 02)
01:00.0 VGA compatible controller: nVidia Corporation G72 [GeForce 7300 LE] (rev a1)
04:03.0 Mass storage controller: Promise Technology, Inc. PDC20268 (Ultra100 TX2) (rev 02)
我的驱动器上启用了本机命令队列。
我正在查看Serial ATA AHCI 1.3 Specification并在第115页找到 -
仅当CCC_CTL.EN设置为“1”时才使用CCC功能。如果CCC_CTL.EN设置为'0',则没有CCC 应该产生中断。
接下来,我查看了此版本内核的relevant code(即有关AHCI的文件),但无法取得任何进展。我在HOST_CAP_CCC = (1 << 7)
中找到了以下宏枚举drivers/ata/ahci.h
,但我不确定如何修改它以禁用命令合并。
有人可以帮助我确定如何禁用CCC吗?谢谢!
回应gby的评论:
我进行了一项实验,我从驱动程序代码发出了大小为64KB的请求。 64KB对应128个扇区(每个扇区= 512字节)。
当我查看响应时间戳差异时,我发现这是:
Timestamp | Timestamp | Difference
at | at | in microsecs
Sector 255 - Sector 127 = 510
Sector 383 - Sector 255 = 3068
Sector 511 - Sector 383 = 22
Sector 639 - Sector 511 = 22
Sector 767 - Sector 639 = 12
Sector 895 - Sector 767 = 19
Sector 1023 - Sector 895 = 13
Sector 1151 - Sector 1023 = 402
正如您所看到的,响应时间戳差异似乎表明写入完成中断被批处理为一个然后引发一个单个中断,这可能解释了十分真正的低数字微秒。
此外,在进行此实验时,使用hdparm
禁用了磁盘写入缓存。
显然,这里涉及一些中断批处理,我需要禁用它,以便为每个写入请求引发一个中断。
更新 这是我尝试的另一个实验。
在我的驱动程序中创建bio
结构并调用较低级别驱动程序的__make_request()
功能。我的驱动程序只发送了一个2560字节的写入请求。
一旦写入服务,就会生成一个被do_IRQ()
拦截的中断。最后,调用函数blk_complete_request()
。请记住,我们仍处于中断处理程序的上半部分(即中断上下文,不内核上下文)。现在,我们在struct bio
中组合另一个blk_complete_request()
并调用较低级别驱动程序的__make_request()
函数。我们此时记录一个时间戳(比如说T_0
)。当获得请求完成回调时,我们记录另一个时间戳(称为T_1
)。差异 - T_1 - T_0
- 始终超过1毫秒。该实验重复多次,每次目的地部门都会影响这种差异 - T_1 - T_0
。据观察,如果目标扇区间隔大约350个扇区,则对于大小为2560字节的请求,时间差约为1.2毫秒。
每次只有在服务上一个请求时才会发送下一个写请求。因此,所有这些请求都是链接,并且磁盘一次只能为一个请求提供服务。
我的理解是,由于连续请求的目标扇区已经分开了相当大的数量,因此在下一个请求发出时,请求的扇区将几乎低于磁盘头,因此写入应立即发生, T_1 - T_0
应该很小(至少<1毫秒)。
Serial ATA AHCI 1.3规范(第114页)指出:
当软件指定数量的命令完成或指定软件时 超时已过期,硬件生成一个中断,允许软件处理已完成的命令。
我的猜测是这个计时器可能是每个请求的延迟超过1毫秒的原因。这就是我需要禁用CCC的原因。
我确实邮寄了作者 - 杰夫加齐克 - 但我还没有收到他的消息。他是stackoverflow的注册用户吗?如果是的话,我可以告诉他......
我们使用的硬盘是:WD Caviar Black(型号 - WD1001FALS)。
任何? : - (
答案 0 :(得分:0)
AFAIK,HBA capabilities bit7(CCC supported
)是RO
,您可以先查看它,看看是否支持CCC。然后,按照规范,您可以通过设置CCC
来停用CCC_CTL.EN
,因为它是RW
您是否尝试清除它然后进行实验?