linux-kernel - mmap() 比 write() copy_form_user() 慢,为什么?

标签 linux-kernel linux-device-driver dma pci-e

我需要将大块数据 (~6MB) 从用户空间传输到我的驱动程序。在驱动程序中,我使用 pci_alloc_consistent() 为每个 block 分配了 2 个 3MB block 。然后我使用 vm_insert_page() 将每个 block (即 2 个 block )mmap() 到单个 vma。这允许用户空间在 mmap 之后读/写每个 block 。它似乎有效,但性能 Not Acceptable 。

我还实现了另一种写入/读取驱动程序中由 pci_alloc_consistent() 分配的内存的方法。我从用户空间使用 write() 然后在驱动程序中使用 copy_from_user() 将 block 中每个 block 的内容移动到上面的内存。我对阅读做相反的事情。

我发现第一种方法至少慢了 2-3 倍,并且多使用了大约 40% 的 CPU。我预计在第二种情况下引入额外的缓冲区副本会使速度变慢。然而,事实并非如此。

我在 x86 64 位平台上运行了最测试,内核:2.6.* 和 3.*。

以上结果有意义吗?如果是,有人可以提供一些关于正在发生的事情的背景吗?

谢谢。

最佳答案

缓存可能被禁用。你 ioremap_cache() 你分配的 block 和 vm_inserted 了吗?我在 x86/x86_64 上遇到过这种问题,并且与 PAT(页面属性表)有关。您需要 ioremap_cache() 物理页面以将内存类型设置为可缓存,然后调用 vm_insert_page。这应该可以解决您的性能问题。

关于linux-kernel - mmap() 比 write() copy_form_user() 慢,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16628164/

相关文章:

linux - Linux内核中使用的三个优先级有什么区别?

linux-kernel - Linux 内核如何知道在哪里寻找驱动程序固件?

caching - DMA/Microblaze 直接访问用户空间页面物理地址后读取错误数据(内核分散/聚集)

c - DMA 内存到内存模式在 STM32F103C8 中不起作用

c - 如何使用动态分配的数组实现队列?

linux-kernel - 这个内核函数可以更具可读性吗? (学术研究需要的想法!)

linux - 对多个task_struct结构进行排队?

linux - 带有 Buildroot 的 BeagleBoard Ralink Wifi USB

linux - 如果文件存在,如何设置 polkit 规则以锁定关闭?

c - 在设备驱动程序中使用 stdlib.h