强制打开BIOS中禁用的I/OAT DCA(一)

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


看寄存器描叙只要将第6位置1即可.

Enable DCA in the CPU MSR

需要将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

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页