繁体   English   中英

mmap共享缓冲区读取问题

[英]mmap shared buffer read problems

我有一个内核模块,该模块分配了很大的内存缓冲区,然后将该缓冲区映射到用户空间。
该模块从硬件接收一些数据,然后将新数据放入缓冲区中,并在其前面带有一个标志。 (内存初始化为零,标志为1)。

用户空间程序在返回指向有效数据的指针之前先在循环中读取标志

代码的简化版:

uint8_t * getData()
{
    while(1)
   {
      if(*((volatile uint32_t*)this->buffer) == 1)
          return this->buffer+sizeof(uint32_t);
   }
}

内存区域被映射为共享,并且完整的缓冲区内存转储确认缓冲区已正确写入。

问题在于,经过一定数量的正确读取后,此函数将停止返回。
这可能是由于CPU缓存引起的吗? 有没有一种方法可以避免这种情况,并确保每次都是直接从RAM而不是从缓存进行读取?

是的,这可能是由于读取器端的cpu缓存。 有人可能会认为“ volatile”关键字应该可以防止此类问题,但这并不是很正确,因为volatile只是指示编译器不要注册变量,这与指示cpu直接从主内存中读取并不完全相同每次。

该问题需要在写端解决。 根据您的描述,听起来好像是在内核模块中进行写操作并从用户端读取。 如果这两个操作发生在不同的cpus(不同的缓存域)上,并且没有什么可以触发读取端的缓存失效,那么您将被描述为卡在读取端。 在您执行存储指令后,您需要在Linux内核上强制刷新存储缓冲区。 假设它是Linux内核,则在设置了标志之后立即插入对smp_mb的调用,模块中的值很可能在所有体系结构上都可以正确执行。

提醒用户空间应用程序存在更多数据的更好方法是,将其阻止在内核模块提供的文件描述符的read() ,当更多数据可用时,内核模块将其唤醒。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM