mmdev 发表于 2013-1-29 22:26:52

强制打开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
http://p.blog.csdn.net/images/p_blog_csdn_net/force_eagle/EntryImages/20091015/dca_pci.png
看寄存器描叙只要将第6位置1即可.

Enable DCA in the CPU MSR
http://p.blog.csdn.net/images/p_blog_csdn_net/force_eagle/EntryImages/20091015/dca_msr.png
需要将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_BIT6#define PCI_HEADER_TYPE_BRIDGE          1#define PCI_VENDOR_ID_INTEL   0x8086 /* lol @ intel */#define PCI_HEADER_TYPE         0x0e #define MSR_P6_DCA_CAP0x000001f8void 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;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
页: [1]
查看完整版本: 强制打开BIOS中禁用的I/OAT DCA(一)