首页
学习
活动
专区
圈层
工具
发布
    • 综合排序
    • 最热优先
    • 最新优先
    时间不限
  • 来自专栏韩曙亮的移动开发专栏

    【Linux 内核 内存管理】RCU 机制 ③ ( RCU 模式下添加链表项 list_add_rcu 函数 | RCU 模式下删除链表项 list_del_rcu 函数 )

    文章目录 一、RCU 模式下添加链表项 list_add_rcu 函数 二、RCU 模式下删除链表项 list_del_rcu 函数 一、RCU 模式下添加链表项 list_add_rcu 函数 --- - 在 Linux 源码 linux-5.6.18\include\linux\rculist.h 头文件中定义的就是 RCU 链表的操作 , 其中定义的 static inline void list_add_rcu (list_next_rcu(prev), new); next->prev = new; } /** * list_add_rcu - add a new entry to rcu-protected 二、RCU 模式下删除链表项 list_del_rcu 函数 ---- 在 Linux 源码 linux-5.6.18\include\linux\rculist.h 头文件中定义的就是 RCU 链表的操作 Instead, either synchronize_rcu() * or call_rcu() must be used to defer freeing until an RCU * grace

    1.3K30编辑于 2023-03-30
  • 来自专栏韩曙亮的移动开发专栏

    【Linux 内核 内存管理】RCU 机制 ① ( RCU 机制简介 | RCU 机制的优势与弊端 | RCU 机制的链表应用场景 )

    文章目录 一、RCU 机制 二、RCU 机制的优势与弊端 三、RCU 机制的链表应用场景 一、RCU 机制 ---- RCU , 英文全称是 " Read-Copy-Update “ , 对应的中文名称是 ” 读取-拷贝-更新 “ , 这是 Linux 内核中的 ” 同步机制 " ; Linux 内核中还有其它同步机制 , 如 " 原子操作 " , " 读写信号量 " 等 " 锁机制 " ; RCU 机制 机制的优势与弊端 ---- RCU 的优势是 " 读者 " ( 读取共享数据的线程 ) 不需要承担同步开销 , 同步开销指的是 : ① 获取 " 锁 " , ② 执行 " 原子指令 " , ③ 执行 " 内存屏障 " ; 与此相对的 RCU 机制也有一定弊端 , " 写者 " ( 修改共享数据的线程 ) 需要 承担很大的同步开销 , 其需要 ① 延迟对象释放 , ② 读取 并 复制 共享数据 , ③ 必须使用 互斥锁 机制 ; 三、RCU 机制的链表应用场景 ---- RCU 机制 可以极大地 提高 " 链表 " 数据结构的 读取效率 , 多个线程 同时读取 链表 时 , 使用 rcu_read_lock

    2.3K20编辑于 2023-03-30
  • 来自专栏韩曙亮的移动开发专栏

    【Linux 内核 内存管理】RCU 机制 ② ( RCU 机制适用场景 | RCU 机制特点 | 使用 RCU 机制保护链表 )

    文章目录 一、RCU 机制适用场景 二、RCU 机制特点 三、使用 RCU 机制保护链表 一、RCU 机制适用场景 ---- 在上一篇博客 【Linux 内核 内存管理】RCU 机制 ① ( RCU 机制简介 | RCU 机制的优势与弊端 | RCU 机制的链表应用场景 ) 中 , 分析了 RCU 机制的优势与弊端 ; 优势 : RCU 的优势是 " 读者 " ( 读取共享数据的线程 ) 不需要承担同步开销 " ( 读取共享数据的线程 ) 性能要求高的场景 ; 二、RCU 机制特点 ---- RCU 机制 只能 保护 " 动态分配 “ 的 ” 共享数据结构 " , 该 共享数据 必须 通过指针访问 , 这里的 ) 性能要求很高 ; 三、使用 RCU 机制保护链表 ---- RCU 机制 除了保护 普通指针 指向的数据 之外 , 还可以用于 保护 " 链表 " 数据结构 ; Linux 内核中 , 提供了 一系列的 标准函数 , 可以 使用 " RCU 机制 " 保护 " 双链表 " ; 标准链表元素 : 使用 RCU 机制 保护 的 链表 , 链表中的 标准 元素 , 仍然可以使用 ; 标准函数 RCU 变体

    1.2K30编辑于 2023-03-30
  • 来自专栏LINUX阅码场

    谢宝友:深入理解RCU之六:分级RCU基础

    经典RCU和分级RCU实现都有和经典RCU相同的语义和API。但是,原有的实现被称为“经典RCU”,新实现被称为“分级RCU”。 2.1. 在RCU中,被等待的事件被称为“RCU 读端临界区”。RCU读端临界区以rcu_read_lock()原语开始,以相应的rcu_read_unlock() 原语结束。 经典RCU实现概要 经典RCU实现的关键原理是:经典RCU 读端临界区限制其中的内核代码不允许阻塞。 RCU-bh的静止状态是在开中断状态下,退出软中断。 需要注意的是,rcu的静止状态也是rcu_bh的静止状态。rcu的静止状态通过调用rcu_qsctr_inc()来记录。 CONFIG_CLASSIC_RCU:经典 RCU。 2. CONFIG_PREEMPT_RCU:可抢占 (实时) RCU。 3. CONFIG_TREE_RCU:用于大型SMP系统的经典 RCU

    1.8K10编辑于 2023-12-28
  • 来自专栏LINUX阅码场

    谢宝友: 深入理解RCU之七:分级RCU实现

    rcurcu_bh共享这个值。 1.2. 分级RCU实现中的节点 rcu_node是被放到 rcu_state结构内的。 RCU全局状态 rcu_state 结构包含每一个RCU实例(rcurcu_bh)的全局状态。 这个数组的值被初始化为NUM_RCU_LVL_0,NUM_RCU_LVL_1,NUM_RCU_LVL_2和 NUM_RCU_LVL_3。 <= RCU_FANOUT */ 27 28 #define RCU_SUM (NUM_RCU_LVL_0 + NUM_RCU_LVL_1 + NUM_RCU_LVL_2 + NUM_RCU_LVL_3 这些接口是rcu_read_lock()、rcu_read_unlock()、 rcu_read_lock_bh()、rcu_read_unlock_bh()、call_rcu() (是对__call_rcu

    3.8K20发布于 2019-10-08
  • 来自专栏韩曙亮的移动开发专栏

    【Linux 内核 内存管理】RCU 机制 ⑤ ( RCU 层次架构概念 | RCU 层次架构源码解析 | RCU 层次架构每层最多叶子数 | RCU 层次架构每个叶子 CPU 数量 )

    文章目录 一、RCU 层次架构概念及源码 二、RCU 层次架构源码解析 1、RCU 层次架构每层最多叶子数 2、RCU 层次架构每个叶子 CPU 数量 一、RCU 层次架构概念及源码 ---- RCU * #else #ifdef CONFIG_RCU_FANOUT_LEAF */ #define RCU_FANOUT_1 (RCU_FANOUT_LEAF) #define RCU_FANOUT _2 (RCU_FANOUT_1 * RCU_FANOUT) #define RCU_FANOUT_3 (RCU_FANOUT_2 * RCU_FANOUT) #define RCU_FANOUT _4 (RCU_FANOUT_3 * RCU_FANOUT) 源码路径 : linux-5.6.18\include\linux\rcu_node_tree.h#31 二、RCU 层次架构源码解析 CONFIG_RCU_FANOUT 宏 , 表示 每个层次 支持的最多的叶子个数 ; #ifdef CONFIG_RCU_FANOUT #define RCU_FANOUT CONFIG_RCU_FANOUT

    1.2K10编辑于 2023-03-30
  • 来自专栏linux驱动个人学习

    Linux RCU 机制详解

    RCU主要针对的数据对象是链表,目的是提高遍历读取数据的效率,为了达到目的使用RCU机制读取数据的时候不对链表进行耗时的加锁操作。 McKenney 是内核中RCU源码的主要实现者,他也写了很多RCU方面的文章。他把这些文章和一些关于RCU的论文的链接整理到了一起。 (); 17 kfree(old_fp); 18 } 其中foo_read中增加了rcu_read_lock和rcu_read_unlock,这两个函数用来标记一个RCU读过程的开始和结束。 rcu_assign_pointer(p, v) \ 2 __rcu_assign_pointer((p), (v), __rcu) 1 #define RCU_INIT_POINTER(p, 为了避免该类问题,RCU还是提供了宏来解决该问题: 1 #define rcu_dereference_check(p, c) \ 2 __rcu_dereference_check((p)

    4K40发布于 2018-03-07
  • 来自专栏韩曙亮的移动开发专栏

    【Linux 内核 内存管理】RCU 机制 ④ ( RCU 模式下更新链表项 list_replace_rcu 函数 | 链表操作时使用 smp_wmb() 函数保证代码执行顺序 )

    文章目录 一、RCU 模式下更新链表项 list_replace_rcu 函数 二、链表操作时使用 smp_wmb() 函数保证代码执行顺序 一、RCU 模式下更新链表项 list_replace_rcu 函数 ---- 在 Linux 源码 linux-5.6.18\include\linux\rculist.h 头文件中定义的就是 RCU 链表的操作 , 其中定义的 static inline void list_replace_rcu(struct list_head *old, struct list_head *new) 函数 , 就是 更新 链表元素 的 函数 ; list_replace_rcu (list_next_rcu(new->prev), new); new->next->prev = new; old->prev = LIST_POISON2; list_replace_rcu struct list_head *new) { new->next = old->next; new->prev = old->prev; rcu_assign_pointer(list_next_rcu

    1.1K20编辑于 2023-03-30
  • 来自专栏Linux内核那些事

    RCU锁原理与实现

    RCU 读者 要做Linux内核中使用 RCU,读者需要使用 rcu_read_lock() 来对临界区进行 “上锁”,本质上 rcu_read_lock() 就是禁止CPU进行抢占,如下代码: #define 实现 在介绍 RCU 实现前,先要介绍两个重要的数据结构:rcu_ctrlblk 和 rcu_data。 list_empty(&RCU_curlist(cpu)) && rcu_batch_after(rcu_ctrlblk.curbatch, RCU_batch(cpu))) { RCU_batch(cpu) = rcu_ctrlblk.curbatch + 1; // 把CPU当前批次设置为全局批次数加一 rcu_start_batch(RCU_batch(cpu 列表的标志位 cpu_clear(cpu, rcu_ctrlblk.rcu_cpu_mask); RCU_last_qsctr(cpu) = RCU_QSCTR_INVALID;

    7.7K52发布于 2020-08-24
  • 来自专栏全栈程序员必看

    RCU 机制_NRPS作用机制

    rcu_read_lock() 和 rcu_read_unlock() 绝对是必须的:他们定义了 RCU 读方临界区的范围。 (…, NULL) rcu_dereference() 循环链表 list_add_rcu() list_add_tail_rcu() list_replace_rcu() list_del_rcu hlist_replace_rcu() hlist_del_rcu() hlist_for_each_entry_rcu() 注意,list_replace_rcu(), list_del_rcu RCU 中,被等待的东西被叫做“RCU读方临界区”。一个RCU读方临界区始于 rcu_read_lock() 原语,止于 rcu_read_unlock() 原语。 问题6:如果 rcu_read_lock() 与 rcu_read_unlock() 之间没有自旋锁或阻塞,RCU更新者会怎样延迟RCU读者?

    1.1K20编辑于 2022-11-15
  • 来自专栏嵌入式ARM和Linux

    Linux内核32-读-拷贝-更新(RCU

    2 RCU实现 既然RCU没有使用共享数据结构,那么它是如何神奇地实现同步技术的呢?其核心思想就是限制RCU的使用范围: 只有动态分配的、通过指针进行访问的数据结构。 进入RCU保护的临界代码段的内核控制路径不能休眠。 3 基本操作 对于reader,RCU的基本操作为: (1)调用rcu_read_lock(),进入RCU保护的临界代码段。 (2)调用rcu_dereference,获取RCU保护的数据指针。然后通过该指针读取数据。当然了,在此期间读操作不能发生休眠。 (3)调用rcu_read_unlock(),离开RCU保护的临界代码段。等价于调用preempt_enable()。 对于writer,RCU的基本操作为: (1)拷贝一份旧数据到新数据,修改新数据。 (2)调用rcu_assign_pointer(),将RCU保护的指针修改为新数据的指针。

    2.2K10编辑于 2022-08-15
  • 来自专栏Linux知识

    【Linux内核】【锁机制】RCU机制入门

    RCU是什么? 、读写锁、自旋锁归为一类,但RCU与它们不同的是——RCU支持多个读者和单一写者并发进行,并且读者是无锁的,因此RCU适用于读密集型的应用场景。 在此之前,我们有必要介绍几个RCU的核心概念: RCU 核心概念 临界区 通过 rcu_read_lock() 和 rcu_read_unlock() 这两个宏来界定的代码区间称为(读)临界区。 RCU保护普通数据结构的示例 下面介绍的是RCU保护普通数据结构的例子,这是RCU最简单的应用场景。 Linux RCU 内核同步机制 深入剖析Linux RCU原理(二)-渐入佳境 【Linux 内核源码分析】RCU机制

    1.6K10编辑于 2025-02-25
  • 来自专栏梁康的专栏

    深入理解 Linux 的 RCU 机制

    增加链表项Linux kernel 中利用 RCU 往链表增加项的源码如下:#define list_next_rcu(list) (*((struct list_head __rcu **)( (list_next_rcu(prev), new); next->prev = new;}list_next_rcu() 函数中的 rcu 是一个供代码分析工具 Sparse 使用的编译选项 ,规定有 rcu 标签的指针不能直接使用,而需要使用 rcu_dereference() 返回一个受 RCU 保护的指针才能使用。 // do something with `pos`}rcu_read_unlock();这里要讲到的 rcu_read_lock() 和 rcu_read_unlock(),是 RCU “随意读” 的关键 因此上一节 “增加链表项” 中提到的 “__rcu” 编译选项强制检查是否使用 rcu_dereference() 访问受 RCU 保护的数据,实际上是为了让代码拥有更好的可移植性。

    15.6K52编辑于 2022-10-19
  • 来自专栏程序那些事

    并发和Read-copy update(RCU)

    处理这个问题就需要用到对象生命周期的跟踪技术,也就是RCU中的RCU-sync。 所以RCU和COW的关系就是:RCU是由RCU-sync和COW两部分组成的。 () rcu_read_unlock() synchronize_rcu() rcu_read_lock和rcu_read_unlock必须是成对出现的,并且synchronize_rcu不能出现在rcu_read_lock 记住RCU比较的是synchronize_rcurcu_read_lock的顺序。 Thread5中,rcu_read_lock在synchronize_rcu返回之后才执行的,所以a=1一定可见。 RCU要注意的事项 RCU虽然没有提供锁的机制,但允许同时多个线程进行读操作。 注意,RCU同时只允许一个synchronize_rcu操作,所以需要我们自己来实现synchronize_rcu的排它锁操作。

    2.5K30发布于 2020-07-08
  • 来自专栏Linuxer的专栏

    谢宝友:深入理解 RCU 之概念

    这不是一篇单独的文章,这是《谢宝友:深入理解Linux RCU》系列的第3篇,前序文章:谢宝友: 深入理解Linux RCU之一——从硬件说起= 谢宝友:深入理解Linux RCU:从硬件说起之内存屏障作者简介 请注意,rcu_assign_pointer()和rcu_dereference()这对原语既不会自旋或者阻塞,也不会阻止list_add rcu()的并发执行。 例如,将rcu_assign_pointer()和rcu_dereference()原语嵌入在Linux链表的RCU变体中。 RCU读端临界区从rcu_read_lock()原语开始,到对应的rcu_read_unlock()原语结束。 理解RCU的难点,主要在于synchronize_rcu()的实现。 3、维护最近被更新对象的多个版本 下面展示RCU如何维护链表的多个版本,供并发的读者访问。

    6.6K10发布于 2017-11-10
  • 来自专栏三丰SanFeng

    无锁编程(五) - RCU(Read-Copy-Update)

    RCU(Read-Copy Update) RCU就是指读-拷贝修改,它是基于其原理命名的。 对于被RCU保护的共享数据结构,读操作不需要获得任何锁就可以访问,但写操作在访问它时首先拷贝一个副本,然后对副本进行修改,最后在适当的时机把指向原来数据的指针重新指向新的被修改的数据。 Linux内核中内存管理大量的运用到了RCU机制。为每个内存对象增加了一个原子计数器用来继续该对象当前访问数。当没有其他进程在访问该对象时(计数器为0),才允许回收该内存。 从这个流程可以看出,RCU类似于一种读写锁的优化,用于解决读和写之间的同步问题。比较适合读多,写少的情况,当写操作过多的时候,这里的拷贝和修改的成本同样也很大。 /lockfree_rcu product begin ************************consumed world, index1, self 1395513088 *********

    2K70发布于 2018-01-16
  • 来自专栏LINUX阅码场

    最浅显易懂的一篇:RCU机制

    RCU主要针对的数据对象是链表,目的是提高遍历读取数据的效率,为了达到目的使用RCU机制读取数据的时候不对链表进行耗时的加锁操作。 Linux内核源码当中,关于RCU的文档比较齐全,你可以在 /Documentation/RCU/ 目录下找到这些文件。Paul E. McKenney 是内核中RCU源码的主要实现者,他也写了很多RCU方面的文章。他把这些文章和一些关于RCU的论文的链接整理到了一起。 (); kfee(old_fp); } 其中foo_read中增加了rcu_read_lock和rcu_read_unlock,这两个函数用来标记一个RCU读过程的开始和结束。 为了避免该类问题,RCU还是提供了宏来解决该问题: <include/linux/rcupdate.h> #define rcu_dereference(p) rcu_dereference_check

    3.8K21发布于 2019-10-15
  • 来自专栏Linuxer的专栏

    谢宝友: 深入理解 Linux RCU 之从硬件说起

    对于想要理解RCU的软件工程师来说,也需要具备一定的硬件基础。 作者简介:谢宝友,在编程一线工作已经有20年时间,其中接近10年时间工作于Linux操作系统。 该书作者Paul E.McKeney是IBM Linux中心领导者,Linux RCU Maintainer。 《深入理解RCU》系列文章整理了Paul E.McKeney的相关著作,希望能帮助读者更深刻的理解Linux内核中非常难于理解的模块----RCU。 如果不能理解这一点,就没办法真正理解RCU。 要明白这一点,考虑下面的代码片段。它被几个CPU并行的执行。

    5.1K31发布于 2017-10-27
  • 来自专栏Linuxer的专栏

    谢宝友:深入理解 Linux RCU 从硬件说起之内存屏障

    本文简介:本文从硬件的角度引申出内存屏障,这不是内存屏障的详尽手册,但是相关知识对于理解RCU有所帮助。 这不是一篇单独的文章,这是《谢宝友:深入理解Linux RCU》系列的第2篇,前序文章:《谢宝友:深入理解 Linux RCU 从硬件说起之内存屏障》 作者简介:谢宝友,在编程一线工作已经有20年时间 该书作者Paul E.McKeney是IBM Linux中心领导者,Linux RCU Maintainer。 《深入理解RCU》系列文章整理了Paul E.McKeney的相关著作,希望能帮助读者更深刻的理解Linux内核中非常难于理解的模块----RCU。 其目的是为了后续文章中,更好的讲解RCU。因此,并不会对内存屏障进行深入的剖析。但是,对于理解RCU来说,本文中的内存屏障知识已经可以了。

    7.7K44发布于 2017-10-30
  • 来自专栏人人都是极客

    一文搞懂 | Linux 同步管理(下)

    RCU 例子 RCU 常用的接口如下图所示: API 说明 rcu_read_lock 标记读者进入读端临界区 rcu_read_unlock 标记读者退出临界区 synchronize_rcu 同步RCU 由于该函数将阻塞写者,只能在进程上下文中使用 call_rcu 把回调函数 func 注册到RCU回调函数链上,然后立即返回 rcu_assign_pointer 用于RCU指针赋值 rcu_dereference 用于RCU指针取值 list_add_rcuRCU注册一个链表结构 list_del_rcuRCU移除一个链表结构 为了更好的理解,在剖析 RCU 之前先看一个例子: #include <linux 结合 API 实现就是,首先使用 rcu_assign_pointer 来移除旧的指针指向,指向更新后的临界资源;然后使用 synchronize_rcu 或 call_rcu 来启动 Reclaimer ,对旧的临界资源进行回收(其中 synchronize_rcu 表示同步等待回收,call_rcu 表示异步回收)。

    87820发布于 2021-10-21
领券