内核/用户地址空间之间共享无锁队列

时间:2017-06-20 18:14:59

标签: linux-kernel locking mmap producer-consumer critical-section

我正在尝试在用户和内核空间之间构造两个共享队列(一个命令队列和一个回复队列)。这样内核就可以向用户空间发送消息,用户空间可以在完成处理后向内核发送回复。

我所做的是使用分配内核内存页面(用于队列)和mmap到用户空间,现在用户和内核都可以访问这些页面(这里我的意思是内核空间中写的内容可以正确读取用户空间,反之亦然。)

问题是我不知道如何在内核和用户空间之间同步访问。假如我要为多生产者1-消费者方案构建一个环形缓冲区,如何通过同时写入来破坏那些环形缓冲区访问?

我本周做了一些研究,这里有一些可能的方法,但我在内核模块开发方面很新,不太确定它是否可行。在深入研究它们时,如果我能得到任何意见或建议,我将非常高兴:

  1. 在用户/内核空间之间使用共享信号量:Shared semaphore between user and kernel spaces

    但是会使用像sem_timedwait()这样的系统调用,我担心它会有多高效。

  2. 我真正喜欢的是无锁方案,如https://lwn.net/Articles/400702/中所述。内核树中的相关文件是:

      
        
    • 内核/跟踪/ ring_buffer_benchmark.c
    •   
    • 内核/跟踪/ ring_buffer.c
    •   
    • 文档/跟踪/环形缓冲design.txt
    •   

    这里记录了如何实现无锁:https://lwn.net/Articles/340400/

    但是,我假设这些是内核实现,不能直接在用户空间中使用(如ring_buffer_benchmark.c中的示例)。有什么办法可以在用户空间中重用这些方案吗?也希望我能找到更多的例子。

  3. 同样在那篇文章(lwn 40072)中,提到了一种使用perf工具的替代方法,它看起来与我想做的相似。如果2不起作用,我将尝试这种方法。

      

    用户空间perf工具因此与之交互   内核通过共享内存区域中的读取和写入而不使用系统   调用

  4. 对不起英语语法......希望它有意义。

1 个答案:

答案 0 :(得分:0)

对于内核和用户空间之间的同步,您可以使用 curcular buffer 机制(Documentation/circular-buffers.txt处的文档)。

此类缓冲区的关键因素是两个指针(头部和尾部),可以单独更新,这非常适合分离的用户和内核代码。此外,循环缓冲区的实现非常简单,因此在用户空间中实现它并不困难。

请注意,对于内核中的多个生产者,您需要使用spinlock或类似的方法对它们进行同步。