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

Linux kernel 内核/用户地址空间之间的共享无锁队列,linux-kernel,locking,mmap,producer-consumer,critical-section,Linux Kernel,Locking,Mmap,Producer Consumer,Critical Section,我试图在用户和内核空间之间构建两个共享队列(一个命令队列和一个应答队列)。这样内核可以向用户空间发送消息,用户空间可以在处理完成后向内核发送回复 我所做的是使用allocate内核内存页(用于队列)和mmap到用户空间,现在用户和内核端都可以访问这些页面(这里我的意思是,在内核空间中写的内容可以在用户空间中正确读取,反之亦然) 问题是我不知道如何在内核和用户空间之间同步访问。比如说,如果我要为多生产者1消费者方案构建一个环形缓冲区,如何确保这些环形缓冲区访问不会被同时写入损坏 本周我做了一些研究

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

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

问题是我不知道如何在内核和用户空间之间同步访问。比如说,如果我要为多生产者1消费者方案构建一个环形缓冲区,如何确保这些环形缓冲区访问不会被同时写入损坏

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

  • 在用户/内核空间之间使用共享信号量:

    但是会使用很多系统调用,比如sem_timedwait(),我担心它会有多高效

  • 我真正喜欢的是无锁方案,如中所述。内核树中的相关文件包括:

    • kernel/trace/ring\u buffer\u benchmark.c
    • kernel/trace/ring\u buffer.c
    • 文档/trace/ring-buffer-design.txt
    这里记录了如何实现无锁:

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

  • 在那篇文章(LWN40072)中,还提到了一种使用perf工具的替代方法,这似乎与我正在尝试的方法类似。如果2不起作用,我将尝试这种方法

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


  • 抱歉,英文语法…希望有意义。

    对于内核和用户空间之间的同步,您可以使用curcular buffer机制(文档位于)

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


    请注意,对于内核中的多个生产者,您需要使用自旋锁或类似工具对其进行同步。

    对于内核和用户空间之间的同步,您可以使用curcular buffer机制(文档位于)

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


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

    Hi Tsyvarev。是的,具有内存边界的循环缓冲区看起来更像一个。直截了当的解决方案!我将尝试一下,看看它是如何工作的!谢谢,如果头指针是在内核空间(生产者)定义的,尾指针是在用户空间(消费者)定义的,那么muchIt很好。问题是,如果存在生产/消费操作,则头/尾指针仍然耦合在一起,例如:例如:在生产者侧,仍然需要尾信息:>如果(CIRC_SPACE(head,tail,buffer->size)>=1)这是否表明,每次生产者想要写入循环缓冲区时,它必须获取尾部指针的最新值?似乎我也应该把这两个指针放在共享空间。
    似乎我也应该把这两个指针放在共享空间。
    -没错。例如,您可以在内核空间中分配内存,并允许用户
    mmap()
    将其作为文件。Hi Tsyvarev。是的,具有内存边界的循环缓冲区看起来更像一个。直截了当的解决方案!我将尝试一下,看看它是如何工作的!谢谢,如果头指针是在内核空间(生产者)定义的,尾指针是在用户空间(消费者)定义的,那么muchIt很好。问题是,如果存在生产/消费操作,则头/尾指针仍然耦合在一起,例如:例如:在生产者侧,仍然需要尾信息:>如果(CIRC_SPACE(head,tail,buffer->size)>=1)这是否表明,每次生产者想要写入循环缓冲区时,它必须获取尾部指针的最新值?似乎我也应该把这两个指针放在共享空间。
    似乎我也应该把这两个指针放在共享空间。
    -没错。例如,您可以在内核空间中分配内存,并允许用户
    mmap()
    将其作为文件。