首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ioremap后的内存访问非常慢

ioremap后的内存访问非常慢
EN

Stack Overflow用户
提问于 2010-12-15 16:35:51
回答 4查看 7K关注 0票数 5

我正在开发一个Linux内核驱动程序,它使一大块物理内存可供用户空间使用。我有一个工作版本的驱动程序,但它目前非常慢。所以,我倒退了几步,试着制作一个简单的小驱动程序来重现这个问题。

我使用内核参数memmap=2G$1G在启动时保留内存。然后,在驱动程序的__init函数中,我将其中一些内存初始化为一个已知的值。我还输入了一些代码来度量时间:

代码语言:javascript
复制
#define RESERVED_REGION_SIZE    (1 * 1024 * 1024 * 1024)   // 1GB
#define RESERVED_REGION_OFFSET  (1 * 1024 * 1024 * 1024)   // 1GB

static int __init memdrv_init(void)
{
    struct timeval t1, t2;
    printk(KERN_INFO "[memdriver] init\n");

    // Remap reserved physical memory (that we grabbed at boot time)
    do_gettimeofday( &t1 );
    reservedBlock = ioremap( RESERVED_REGION_OFFSET, RESERVED_REGION_SIZE );
    do_gettimeofday( &t2 );
    printk( KERN_ERR "[memdriver] ioremap() took %d usec\n", usec_diff( &t2, &t1 ) );

    // Set the memory to a known value
    do_gettimeofday( &t1 );
    memset( reservedBlock, 0xAB, RESERVED_REGION_SIZE );
    do_gettimeofday( &t2 );
    printk( KERN_ERR "[memdriver] memset() took %d usec\n", usec_diff( &t2, &t1 ) );

    // Register the character device
    ...

    return 0;
}

我加载驱动程序,检查dmesg。它报告说:

代码语言:javascript
复制
[memdriver] init
[memdriver] ioremap() took 76268 usec
[memdriver] memset() took 12622779 usec

对memset来说是12.6秒。这意味着memset以81 MB/秒的运行。为什么这么慢?

这是Fedora 13上的内核2.6.34,它是一个x86_64系统。

编辑:

该方案的目标是获取一块物理内存,并将其提供给PCI设备(通过内存的总线/物理地址)和用户空间应用程序(通过调用mmap,由驱动程序支持)。然后PCI设备将不断地用数据填充这个内存,用户空间应用程序将把它读出来。如果ioremap不是这样做的好方法(如本在下面所建议的那样),我愿意接受其他建议,这些建议将允许我获得任何可以通过硬件和软件直接访问的内存块。我可能也可以用一个更小的缓冲区。

见下面我的最终解决方案。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-12-15 20:27:17

ioremap分配不可缓存的页面,就像您希望访问内存映射的io设备一样。那就能解释你的糟糕表现了。

你可能想要kmallocvmalloc平日 参考文献 材料将解释每个功能。

票数 5
EN

Stack Overflow用户

发布于 2010-12-15 17:48:47

我不认为ioremap()是你想要的。您应该只使用readbreadlwritebmemcpy_toio等访问结果(您称之为“readl”)。甚至不能保证返回实际上是映射的(尽管它显然在您的平台上)。我猜想该区域正在被映射为未被映射(适用于IO寄存器),从而导致了糟糕的性能。

票数 2
EN

Stack Overflow用户

发布于 2012-03-29 13:36:58

已经有一段时间了,但我一直在更新,因为我最终找到了解决这个ioremap问题的方法。

由于我们有自定义硬件直接写入内存,因此标记它可能更正确,但速度慢得令人无法忍受,而且不适合我们的应用程序。我们的解决方案是,一旦有足够的新数据来填充我们架构上的整个缓存行(我认为是256字节),我们就只能从该内存(一个环形缓冲区)中读取数据。这保证了我们永远不会得到过时的数据,而且速度很快。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4452400

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档