Hardware Platform: DELL PowerEdge R410
Develop Platform: Redhat EL5
Kernel version: 2.6.29.5
gcc version: 4.3.2
Dell PowerEdge R410采用英特尔® 至强® 5500系列处理器.而至强5100以后系列产品,它采用了新的处理器架构——酷睿架构,而I/O加速技术是其显著的特点之一。
而直接DCA(高级缓存访问)是I/O AT 2在原有基础上增加了的工作模式,这是一项快速响应、增强性能的新特性。基本工作原理是使得CPU高速缓存中的数据可以被网络控制器优先访问,一方面充分利用缓存中的数据,另外一个方面利用高速缓存低延迟的特性,来避免CPU频繁的访问内存,降低系统开销。DCA有两种基本的工作模式,当处理小型I/O任务的时候,甚至不需要芯片组中QuickData引擎的参与,只有当处理大型I/O任务的时候才需要。DCA的意义在于,数据包尽可能采用最近最快的途径,进入CPU的高速缓存中被优先访问,这将极大降低CPU的数据存取延迟。
R410 启动后加载内核ioatdma模块后提示:
DCA is disabled in BIOS
注: ioatdma 只有在2.6.18以上内核才具有.
Intel 82598 10Gb Ixgbe网卡驱动 DCA 无法启用.通过BIOS启用也无果.
goolge 一把发现可以通过修改CPU MSR寄存器或PCI 配置寄存器将DCA强制打开.
可以通过两种方式打开DCA启用标志,一种是修改PCI配置寄存器方式,一种为修改CPU MSR寄存器方式.
Enable DCA in PCI Configuration Space
需要将0x1f8 寄存器置1.
以下是源代码, 需要libpci-dev库支持.
注: 因为需要在用户层操作msr设备,需要将内核选项中的msr选项打开.
#define _XOPEN_SOURCE 500 #include <stdio.h> #include <stdlib.h> #include <pci/pci.h> #include <sys/io.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #define INTEL_BRIDGE_DCAEN_OFFSET 0x64 #define INTEL_BRIDGE_DCAEN_BIT 6 #define PCI_HEADER_TYPE_BRIDGE 1 #define PCI_VENDOR_ID_INTEL 0x8086 /* lol @ intel */ #define PCI_HEADER_TYPE 0x0e #define MSR_P6_DCA_CAP 0x000001f8 void check_dca(struct pci_dev *dev) { u32 dca = pci_read_long(dev, INTEL_BRIDGE_DCAEN_OFFSET); if (!(dca & (1 << INTEL_BRIDGE_DCAEN_BIT))) { printf("DCA disabled, enabling now./n"); dca |= 1 << INTEL_BRIDGE_DCAEN_BIT; pci_write_long(dev, INTEL_BRIDGE_DCAEN_OFFSET, dca); } else { printf("DCA already enabled!/n"); } } void msr_dca_enable(void) { char msr_file_name[64]; int fd = 0, i = 0; u64 data; for (;i < NUM_CPUS; i++) { sprintf(msr_file_name, "/dev/cpu/%d/msr", i); fd = open(msr_file_name, O_RDWR); if (fd < 0) { perror("open failed!"); exit(1); } if (pread(fd, &data, sizeof(data), MSR_P6_DCA_CAP) != sizeof(data)) { perror("reading msr failed!"); exit(1); } printf("got msr value: %*llx/n", 1, (unsigned long long)data); if (!(data & 1)) { data |= 1; if (pwrite(fd, &data, sizeof(data), MSR_P6_DCA_CAP) != sizeof(data)) { perror("writing msr failed!"); exit(1); } } else { printf("msr already enabled for CPU %d/n", i); } } } int main(void) { struct pci_access *pacc; struct pci_dev *dev; u8 type; pacc = pci_alloc(); pci_init(pacc); pci_scan_bus(pacc); for (dev = pacc->devices; dev; dev=dev->next) { pci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_BASES); if (dev->vendor_id == PCI_VENDOR_ID_INTEL) { type = pci_read_byte(dev, PCI_HEADER_TYPE); if (type == PCI_HEADER_TYPE_BRIDGE) { check_dca(dev); } } } msr_dca_enable(); return 0; }
参考:
Enabling BIOS options on a live server with no rebooting