use*_*878 5 linux storage interrupt linux-kernel
我正在研究Linux内核的2.6.35.9版本,我正在尝试禁用Command Completion Coalescing.
输出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)
Run Code Online (Sandbox Code Playgroud)
我在驱动器上启用了本机命令队列.
我正在查看Serial ATA AHCI 1.3规范,并在第115页找到 -
仅当CCC_CTL.EN设置为"1"时才使用CCC功能.如果CCC_CTL.EN设置为'0',则不会产生CCC中断.
接下来,我查看了此版本内核的相关代码(即有关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
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,响应时间戳差异似乎表明写入完成中断被批处理为一个,然后引发一个单个中断,这可能解释了几十微秒内真正的低数字.
此外,在进行此实验时,使用了禁用磁盘写入缓存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的注册用户吗?如果是的话,我可以PM他...
我们使用的硬盘是:WD Caviar Black(型号 - WD1001FALS).
任何人?:-(
小智 0
AFAIK,HBA capabilities bit7(CCC supported)是RO,你可以先检查一下是否支持 CCC。然后根据规范,您可以CCC通过设置禁用,CCC_CTL.EN因为它是RW
您是否尝试清除它然后进行实验?