Linux 5.10将有完全无锁的环形缓冲区

subtitle 情感译言 10-21 08:54 跟贴 3 条

Linus Torvalds已经合并了John Ogness的一组printk()补丁程序,这些补丁程序使内核环形缓冲区(无论您键入什么dmesg)都完全无锁。这是一个很大的改进,它允许存储和读取消息,而无需临时的每个CPU的缓冲区,而没有死锁的风险。

printk问题:

环形缓冲区是Linux内核的核心部分。驱动程序,子系统和很多通用功能用printk()共享错误和普通消息。输入dmesg或sudo dmesg在终端中查看其内容。

John Ogness提供了长达57分钟的视频,标题为“为什么printk()如此复杂? ”

(https://linuxreviews.org/Why_is_printk()_so_complicated%3F),详细介绍了Linux内核的环形缓冲区的历史,自1991年Linux 0.01以来,2019 Linux会议上,他指出了printk()实现存在的问题,并printk()在那次会议上提出了一系列改进建议和内核的环形缓冲区功能。他的一些工作现在已经合并到Linux git树中,以确保它在几个月后发布时将成为Linux 5.10的一部分。

Linus Torvalds已合并John Ogness编写的一系列补丁中的第一个补丁,以使其printk()更加现代,安全和实用。

最大的新事物是完全无锁的环形缓冲区实现,包括对连续的支持。它将允许在没有死锁风险的任何情况下存储和读取消息,并且不需要临时的每个单独CPU缓冲区。

目前访问共享区仍由logbuf_lock序列化。它可以同步其他一些操作,例如用于格式化消息的临时缓冲区,syslog和kmsg_dump操作。解除锁定的问题正在讨论,为下一个版本做好准备。”

打开网易新闻 查看更多图片
Linux环形缓冲区原理

它是一个多生产者,单个或多个消费者组成的循环缓冲区。

单生产者单使用者循环缓冲区可以很容易地制成而没有锁。生产者写入缓冲区,然后原子地增加头指针。使用者读取缓冲区,然后以原子方式递增尾指针。

多个生产者在没有锁定的情况下变得棘手,因为它们需要相互协调,以至于不能覆盖缓冲区的同一部分。不过,这仍然可以通过原子递增头指针来完成。诀窍是,增量必须在写入缓冲区之前而不是之后进行。因此,缓冲区中需要有一个标记,以指示它已准备好被读取。生产者使用原子增量分配缓冲区,在需要时将其写入数据,然后将其标记为可以读取。消费者同时查看头部指针和标记以告知可以读取多少数据。

可以通过简单地为每个消费者维护一个尾指针来实现多个消费者。但是,为了真正实现无锁,生产者不能被缓慢的消费者所阻挡。取而代之的是,生产者只是简单地按照他们想要的速度写作,而消费者则尽其所能跟上。如果使用计数器而不是指针或索引,则消费者可以检测到它何时落在后面。不是围绕增量循环,而是围绕对循环缓冲区的访问。这样,可以判断何时计数器落后于头部计数器后面的缓冲区大小。可以使用64位计数器而不必担心翻转从头开始,也可以为计数器使用较小的数据类型,然后将缓冲区的大小设置为2的幂,以便整数翻转不会导致不连续性。

特别声明:本文为网易自媒体平台“网易号”作者上传并发布,仅代表该作者观点。网易仅提供信息发布平台。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.
打开网易新闻,阅读体验更佳
大家都在看