在 IA-32 系统中,物理内存最开始的1GB 被称为“低端内存”,1GB 以上的部分称为“高端内存”。先前的Linux 核心版本要求通往存储设备的数据缓存必须放在物理RAM 的低端内存区域,即使是应用程序可以同时使用高端内存和低端内存也存在同样状况。这样,来自低端内存区域数据缓存的I/O 请求可以直接进行内存存取操作。但是,当应用程序发出一个I/O 请求,其中包含位于高端内存的数据缓存时,核心将强制在低端内存中分配一个临时数据缓存,并将位于高端内存的应用程序缓存数据复制到此处,这个数据缓存相当于一个跳转的buffer。例如一些老设备只能访问16M以下的内存,但DMA的目的地址却在16M以上时,就需要在设备能访问16M范围内设置一个buffer作为跳转。这种额外的数据拷贝被称为“bounce buffering”,会明显地降低I/O 密集的数据库应用的性能,因为大量分配的bounce buffers 会占用许多内存,而且bouncebuffer 的复制会增加系统内存总线的负荷。

http://www.linuxdoc.org/HOWTO/IO-Perf-HOWTO/overview.html

3. Avoiding Bounce Buffers

This section provides information on applying and using the bounce buffer patch on the Linux 2.4 kernel. The bounce buffer patch, written by Jens Axboe, enables device drivers that support direct memory access (DMA) I/O to high-address physical memory to avoid bounce buffers.

This document provides a brief overview on memory and addressing in the Linux kernel, followed by information on why and how to make use of the bounce buffer patch.

3.1. Memory and Addressing in the Linux 2.4 Kernel

The Linux 2.4 kernel includes configuration options for specifying the amount of physical memory in the target computer. By default, the configuration is limited to the amount of memory that can be directly mapped into the kernel's virtual address space starting at PAGE_OFFSET. On i386 systems the default mapping scheme limits kernel-mode addressability to the first gigabyte (GB) of physical memory, also known as low memory. Conversely, high memory is normally the memory above 1 GB. High memory is not directly accessible or permanently mapped by the kernel. Support for high memory is an option that is enabled during configuration of the Linux kernel.

3.2. The Problem with Bounce Buffers

When DMA I/O is performed to or from high memory, an area is allocated in low memory known as a bounce buffer. When data travels between a device and high memory, it is first copied through the bounce buffer.

Systems with a large amount of high memory and intense I/O activity can create a large number of bounce buffers that can cause memory shortage problems. In addition, the excessive number of bounce buffer data copies can lead to performance degradation.

Peripheral component interface (PCI) devices normally address up to 4 GB of physical memory. When a bounce buffer is used for high memory that is below 4 GB, time and memory are wasted because the peripheral has the ability to address that memory directly. Using the bounce buffer patch can decrease, and possibly eliminate, the use of bounce buffers.

3.3. Locating the Patch

The latest version of the bounce buffer patch is block-highmem-all-18b.bz2, and it is available from Andrea Arcangeli's -aa series kernels athttp://kernel.org/pub/linux/kernel/people/andrea/kernels/v2.4/.

3.3.1. Configuring the Linux Kernel to Avoid Bounce Buffers

This section includes information on configuring the Linux kernel to avoid bounce buffers. The Linux Kernel-HOWTO at http://www.linuxdoc.org/HOWTO/Kernel-HOWTO.html explains the process of re-compiling the Linux kernel.

The following kernel configuration options are required to enable the bounce buffer patch:

Development Code - To enable the configurator to display the High I/O Support option, select the Code maturity level options category and specify "y" to Prompt for development and/or incomplete code/drivers.

High Memory Support - To enable support for physical memory that is greater than 1 GB, select the Processor type and features category, and select a value from the High Memory Support option.

High Memory I/O Support - To enable DMA I/O to physical addresses greater than 1 GB, select the Processor type and features category, and enter "y" to the HIGHMEM I/O support option. This configuration option is a new option introduced by the bounce buffer patch.

3.3.2. Enabled Device Drivers

The bounce buffer patch provides the kernel infrastructure, as well as the SCSI and IDE mid-level driver modifications to support DMA I/O to high memory. Updates for several device drivers to make use of the added support are also included with the patch.

If the bounce buffer patch is applied and you configure the kernel to support high memory I/O, many IDE configurations and the device drivers listed below perform DMA I/O without the use of bounce buffers:

aic7xxx_drv.o
aic7xxx_old.o
cciss.o
cpqarray.o
megaraid.o
qlogicfc.o
sym53c8xx.o

3.4. Modifying Your Device Driver to Avoid Bounce Buffers

If your device drivers are not listed above in the Enabled Device Drivers section, and the device is capable of high-memory DMA I/O, you can modify your device driver to make use of the bounce buffer patch as follows. More information on rebuilding a Linux device driver is available at http://www.xml.com/ldd/chapter/book/index.html.

  1. A.) For SCSI Adapter Drivers: set the highmem_io bit in the Scsi_Host_Template structure.

    B.) For IDE Adapter Drivers: set the highmembit in the ide_hwif_t structure.

  2. Call pci_set_dma_mask(struct pci_dev *pdev, dma_addr_t mask) to specify the address bits that the device can successfully use on DMA operations.

    If DMA I/O can be supported with the specified mask, pci_set_dma_mask() will set pdev->dma_mask and return 0. For SCSI or IDE, the mask value will also be passed by the mid-level drivers toblk_queue_bounce_limit(request_queue_t *q, u64 dma_addr) so that bounce buffers are not created for memory directly addressable by the device. Drivers other than SCSI or IDE must callblk_queue_bounce_limit() directly.

  3. Use pci_map_page(dev, page, offset, size, direction), instead of pci_map_single(dev, address, size, direction) to map a memory region so that it is accessible by the peripheral device. pci_map_page()supports both high and low memory.

    The address parameter for pci_map_single() correlates to the page and offset parameters for pci_map_page(). Use the virt_to_page() macro to convert an address to a page and offset. The virt_to_page()macro is defined by including pci.h. For example:

    void *address;
    
    struct page *page;
    
    unsigned long offset;
    
    page = virt_to_page(address);
    
    offset = (unsigned long) address & ~PAGE_MASK;
    

    Call pci_unmap_page() after the DMA I/O transfer is complete to remove the mapping established by pci_map_page().

    pci_map_single() is implemented using virt_to_bus()virt_to_bus() handles low memory addresses only. Drivers supporting high memory should no longer call virt_to_bus() or bus_to_virt().

  4. If your driver calls pci_map_sg() to map a scatter-gather DMA operation, your driver should set the page and offset fields instead of the address field of the scatterlist structure. Refer to step 3 for converting an address to a page and offset.

    If your driver is already using the PCI DMA API, continue to use pci_map_page() or pci_map_sg() as appropriate. However, do not use the address field of the scatterlist structure.

转载于:https://www.cnblogs.com/szhan/p/3388280.html

I/O Performance HOWTO: Avoiding Bounce Buffers相关推荐

  1. 英特尔虚拟化技术发展蓝图

     当前非常热门的Virtualization虚拟化技术的出现和应用其实已经有数十年的历史了,在早期,这个技术主要应用在服务器以及大型主机上面,现在,随着PC性能的不断增长,Virtualizati ...

  2. make xconfig详解

    http://blog.csdn.net/yanshuai_tek/article/details/50902817 make menuconfig 图形化的内核配置 make mrproper 删除 ...

  3. linux 内核配置简介

    Gentoo Linux Gentoo内核(gentoo-sources)特有的选项 Gentoo Linux support CONFIG_GENTOO_LINUX 选"Y"后, ...

  4. Characterizing, exploiting, and detecting DMA code injection vulnerabilities,Eurosys2021

    Characterizing, exploiting, and detecting DMA code injection vulnerabilities in the presence of an I ...

  5. FreeBSD开发手册(一)

    The FreeBSD Documentation Project FreeBSD 中文计划 版权 © 2000, 2001, 2002, 2003, 2004, 2005 The FreeBSD D ...

  6. Linux源码研究-用户管理员手册-内核命令行参数

    下面的列表是__setup(), core_param()和module_param()宏实现的内核参数,内核从命令-开始解析参数,如果参数不被识别,也不包含".",参数会被用来启 ...

  7. I.MX6ULL_Linux_系统篇(20) kernel分析-menuconfig

    linux内核的功能非常丰富,大多功能可以通过menuconfig图形界面来选择配置,但是我们面对众多的功能,往往不能快速确定配置项位置或无法理解配置项功能,本篇将对配置项做一下简要解析!(作者不建议 ...

  8. linux 统计_聊聊 Linux 的内存统计

    写在前面 本文主要分析 Linux 系统内存统计的一些指标以及进程角度内存使用监控的一些方法. 开始阅读这篇文章前,请先简单阅读下面的几篇文章. <进程眼中的线性地址空间> <线程眼 ...

  9. linux内核那些事之ZONE

    struct zone 从linux 三大内存模型中可以了解到,linux内核将物理内存按照实际使用用途划分成不同的ZONE区域,ZONE管理在物理内存中占用重要地位,在内核中对应的结构为struct ...

最新文章

  1. Java获取游戏头像_java爬取堆糖所有头像(高质量版头像)
  2. 【Android 逆向】使用 Python 解析 ELF 文件 ( Capstone 反汇编 ELF 文件中的机器码数据 | 创建反汇编解析器实例对象 | 设置汇编解析器显示细节 )
  3. 在flask中使用websocket-实时消息推送
  4. cmder 基本配置和使用
  5. android view添加背景,android – 如何将视图作为背景添加到surfaceView?
  6. 使用sql语句向SDO_Geometry插入要素
  7. [转帖]windows+xshell+xming访问非桌面版Linux服务器
  8. mysql基于时间盲注_MySQL基于时间盲注(Time-Based Blind SQL Injection)五种延时方法...
  9. virtuoso配合calibre进行电路后仿真
  10. NBIOT工作模式详解(BC26模组)
  11. Fedora 9安装vmware tools解决方案
  12. Arduino 常用电子元件和扩展模块
  13. Android7(N)中webview导致应用内语言切换失效
  14. springboot实战派PDF文档
  15. 核心单词 Word List 1
  16. 三言二拍:五年有多长对牛乱弹琴 | Playinamp;#39; with IT
  17. C语言入门(什么是C语言,C语言的编程机制以及一些基础计算机概念)
  18. Spark集群安装和WordCount编写
  19. excel相同数据汇总
  20. .NET MEF托管可扩展框架

热门文章

  1. windows下安装TensorFlow(清华镜像)
  2. c++Error:c++调用python文件提示由于找不到python3.8.dll,无法继续运行。。。
  3. 【每周CV论文】深度学习图像降噪应该从阅读哪些文章开始
  4. Openssl和PKCS#11的故事
  5. 教育谋定应用型高校 经济和信息化研究共建成都工业学院
  6. 深入理解 Vuejs 动画效果
  7. xvfb-run: error: xauth command not found 解决方式
  8. freertos之任务
  9. 关于Java中的线程安全(线程同步)
  10. 常用正则表达式大全!