Linux内核链表 内存屏障,从cache一致性到理解内存屏障
时间: 2023-12-09 18:05:35 浏览: 38
Linux内核链表是一个非常基础的数据结构,在Linux内核中被广泛使用。Linux内核链表通过指针连接节点,每个节点都包含下一个节点的指针,从而形成链表。
在多核处理器架构下,由于不同核心的缓存可能不一致,当多个核心同时对链表进行修改时,可能会出现数据不一致的情况。为了解决这个问题,Linux内核采用了一种叫做“cache一致性”的技术,即每次修改链表节点时,都需要将该节点所在的缓存行标记为无效,这样其他核心访问该节点时,就会重新从内存中读取数据,保证数据一致性。
而内存屏障则是保证代码执行顺序的关键技术。在多核处理器架构下,由于不同核心的指令可能乱序执行,因此需要内存屏障来确保指令的执行顺序。内存屏障分为读屏障、写屏障和全屏障三种。
读屏障(rmb)用于确保所有先于读屏障的读操作都完成后,才能执行读屏障之后的操作;写屏障(wmb)用于确保所有先于写屏障的写操作都完成后,才能执行写屏障之后的操作;全屏障(mb)则是同时执行读屏障和写屏障的作用。
在Linux内核链表中,内存屏障被广泛应用。例如,在向链表中添加节点时,需要先将新节点的指针指向下一个节点,再将上一个节点的指针指向新节点。此时就需要使用内存屏障来确保指针的修改顺序正确。具体来说,需要在修改新节点指针之后、修改上一个节点指针之前,加入写屏障;在读取新节点指针之前、读取上一个节点指针之后,加入读屏障。这样就可以确保指针的修改顺序正确,从而避免了数据不一致的情况。
相关问题
linux 内核链表
Linux 内核链表是 Linux 内核中常用的一种数据结构,它是由多个节点组成的链式结构,每个节点包含了指向前一个节点和后一个节点的指针。Linux 内核链表的实现是通过定义一个 struct list_head 结构体来实现的,这个结构体包含了指向前一个节点和后一个节点的指针。
在 Linux 内核中,链表被广泛应用于各种数据结构的实现,比如进程列表、文件系统中的 inode 链表等等。链表的优点是插入和删除操作非常高效,但是查找操作比较耗时。
linux内核链表实现
Linux内核链表的实现方式与传统链表实现方式有所不同。传统链表实现方式是在数据结构中嵌入链表指针,而Linux内核链表的实现方式是将链表节点嵌入数据结构中。具体实现方式定义在`<include/linux/list.h>`中,使用了`struct list_head`结构体来表示双向链表,其中包含了`next`和`prev`指针。
在Linux内核链表中,删除指定节点的方式是使用`list_del`函数,该函数将指定节点的`next`和`prev`指针设置为`LIST_POISON1`和`LIST_POISON2`。为什么不将这些指针设置为NULL呢?这是因为`LIST_POISON1`和`LIST_POISON2`是非NULL的指针,在普通环境中会引发page faults(页面错误),从而用于验证是否所有链表节点都已经被初始化。这样可以帮助检测和排查未初始化的链表节点。
在遍历链表时,可以使用`list_first_entry`宏来获取链表的第一个节点。这个宏会返回链表头节点的下一个节点,并使用`list_entry`宏将该节点转换为所需的数据结构类型。
综上所述,Linux内核链表实现方式独特,将链表节点嵌入数据结构中,使用`list_del`函数删除节点时将指针置为`LIST_POISON1`和`LIST_POISON2`,并可通过`list_first_entry`宏遍历链表。<span class="em">1</span><span class="em">2</span><span class="em">3</span>
#### 引用[.reference_title]
- *1* *2* *3* [linux 内核链表的实现](https://blog.csdn.net/qq_35031421/article/details/103938221)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"]
[ .reference_list ]