【问题标题】:shared lock-free queue between kernel/user address space内核/用户地址空间之间的共享无锁队列
【发布时间】:2017-06-20 18:14:59
【问题描述】:

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

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

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

这周我做了一些研究,这里有一些可能的方法,但我在内核模块开发方面还很陌生,不确定它是否有效。在挖掘它们的同时,如果我能得到任何 cmet 或建议,我会很高兴:

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

    但是会用到很多像 sem_timedwait() 这样的系统调用,我担心它的效率如何。

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

    • kernel/trace/ring_buffer_benchmark.c
    • kernel/trace/ring_buffer.c
    • 文档/trace/ring-buffer-design.txt

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

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

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

    因此,用户空间性能工具与 内核通过在共享内存区域中读写而不使用系统 来电。

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

【问题讨论】:

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


    【解决方案1】:

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

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

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

    【讨论】:

    • 嗨 Tsyvarev。是的,带有内存边界的循环缓冲区看起来更像一个。直截了当的解决方案!我会尝试一下,看看它是如何工作的!非常感谢
    • 头指针定义在内核空间(生产者),尾指针定义在用户空间(消费者)就可以了。问题是如果有生产/消费操作,头/尾指针仍然耦合在一起,例如:
    • 例如:在producer端的tail信息还是需要的:> if (CIRC_SPACE(head, tail, buffer->size) >= 1) 这是否暗示,每次producer要写的时候循环缓冲区,它必须获取尾指针的最新值?似乎我也应该将这两个指针放在共享空间中。
    • Seems like I should put those two pointers in shared space also. - 没错。例如,您可以在内核空间中分配内存,并允许用户将其作为文件mmap()
    猜你喜欢
    • 2012-03-02
    • 2014-06-24
    • 2011-12-16
    • 2018-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-12
    • 1970-01-01
    相关资源
    最近更新 更多