http://paulmck.livejournal.com/7314.html

RCU的作者,paul在他的blog中有提到这个问题,也明确提到需要在module exit的地方使用rcu_barrier来等待保证call_rcu的回调函数callback能够执行完成,然后再正式卸载模块,方式快速卸载之后call_back回调发现空指针的问题,从而导致kernel panic的问题。

RCU and unloadable modules

  • Jun. 8th, 2009 at 1:38 PM

The rcu_barrier() function was described some time back in an article on Linux Weekly News. This rcu_barrier() function solves the problem where a given module invokes call_rcu() using a function in that module, but the module is removed before the corresponding grace period elapses, or at least before the callback can be invoked. This results in an attempt to call a function whose code has been removed from the Linux kernel. Oops!!!

Since the above article was written, rcu_barrier_bh() and rcu_barrier_sched() have been accepted into the Linux kernel, for use with call_rcu_bh() and call_rcu_sched(), respectively. These functions have seen relatively little use, which is no surprise, given that they are quite specialized. However, Jesper Dangaard recently discovered that they need to be used a bit more heavily. This lead to the question of exactly when they needed to be used, to which I responded as follows:

Unless there is some other mechanism to ensure that all the RCU callbacks have been invoked before the module exit, there needs to be code in the module-exit function that does the following:

  1. Prevents any new RCU callbacks from being posted. In other words, make sure that no future call_rcu()invocations happen from this module unless those call_rcu() invocations touch only functions and data that outlive this module.
  2. Invokes rcu_barrier().
  3. Of course, if the module uses call_rcu_sched() instead of call_rcu(), then it should invoke rcu_barrier_sched() instead of rcu_barrier(). Similarly, if it uses call_rcu_bh() instead of call_rcu(), then it should invoke rcu_barrier_bh() instead of rcu_barrier(). If the module uses more than one of call_rcu()call_rcu_sched(), and call_rcu_bh(), then it must invoke more than one of rcu_barrier()rcu_barrier_sched(), and rcu_barrier_bh().

What other mechanism could be used? I cannot think of one that it safe. For example, a module that tried to count the number of RCU callbacks in flight would be vulnerable to races as follows:

  1. CPU 0: RCU callback decrements the counter.
  2. CPU 1: module-exit function notices that the counter is zero, so removes the module.
  3. CPU 0: attempts to execute the code returning from the RCU callback, and dies horribly due to that code no longer being in memory.

If there was an easy solution (or even a hard solution) to this problem, then I do not believe that Nikita Danilov would have asked Dipankar Sarma for rcu_barrier(). Therefore, I do not expect anyone to be able to come up with an alternative to rcu_barrier() and friends. Always happy to learn something by being proven wrong, of course!!!

So unless someone can show me some other safe mechanism, every unloadable module that uses call_rcu()call_rcu_sched(), or call_rcu_bh() must use rcu_barrier()rcu_barrier_sched(), and/or rcu_barrier_bh() in its module-exit function.

So if you have a module that uses one of the call_rcu() functions, please use the corresponding rcu_barrier()function in the module-exit code!

Update: Peter Zijlstra rightly points out that the issue is not whether your module invokes call_rcu(), but rather whether the corresponding RCU callback invokes a function that is in a module. So, if there is a call_rcu()call_rcu_sched(), or call_rcu_bh() anywhere in the kernel whose RCU callback either directly or indirectly invokes a function in your module, then your module's exit function needs to invoke rcu_barrier()rcu_barrier_sched(), and/or rcu_barrier_bh(). Thanks to Peter for pointing this out!

关于call_rcu在内核模块退出时可能引起kernel panic的问题的更多相关文章

  1. Android退出时关闭所有Activity的方法

    Android退出时,有的Activity可能没有被关闭.为了在Android退出时关闭所有的Activity,设计了以下的类: //关闭Activity的类 public class CloseAc ...

  2. Qt 程序退出时断言错误——_BLOCK_TYPE_IS_VALID(pHead->nBlockUse),由setAttribute(Qt::WA_DeleteOnClose)引起

    最近在学习QT,自己仿写了一个简单的QT绘图程序,但是在退出时总是报错,断言错误: 报错主要问题在_BLOCK_TYPE_IS_VALID(pHead->nBlockUse),是在关闭窗口时报的 ...

  3. Android设置Activity启动和退出时的动画

    业务开发时遇到的一个小特技,要求实现Activity启动时自下向上弹出,退出时自上向下退出. 此处不关注启动和退出时其他Activity的动画效果,实现方法有两种: 1.代码方式,通过Activity ...

  4. HP平台由于变量声明冲突导致程序退出时的core

    最近遇到一个莫名的问题,在HP-UX B.11.31 U ia64平台下,程序PetriService在接收到产品化退出或Ctrl-C时,程序在main函数返回后析构全局的CTQueue<SMs ...

  5. Android 编程下 Activity 的创建和应用退出时的销毁

    为了确保对应用中 Activity 的创建和销毁状态进行控制,所以就需要一个全局的变量来记录和销毁这些 Activity.这里的大概思路是写一个类继承 Application,并使获取该 Applic ...

  6. 解决log4cxx退出时的异常

    解决log4cxx退出时的异常(金庆的专栏)如果使用log4cxx的FileWatchdog线程来监视日志配置文件进行动态配置,就可能碰到程序退出时产生的异常.程序退出时清理工作耗时很长时,该异常很容 ...

  7. 神奇的bug,退出时自动更新时间

    遇到一个神奇的bug,用户退出时,上次登录时间会变成退出时的时间. 于是开始跟踪,发现Laravel在退出时,会做一次脏检查,这时会更新rember_token,这时就会有update操作如下. 而粗 ...

  8. java实现创建临时文件然后在程序退出时自动删除文件(转)

    这篇文章主要介绍了java实现创建临时文件然后在程序退出时自动删除文件,从个人项目中提取出来的,小伙伴们可以直接拿走使用. 通过java的File类创建临时文件,然后在程序退出时自动删除临时文件.下面 ...

  9. os.waitpid()无法获取sys.exit()退出时的status code

    [目的] 父进程使用os.waitpid()等待子进程退出,并检测子进程的exit code,以决定是否重启子进程. (常见的应用场景是:子进程接收外部命令,收到"stop"时退出 ...

随机推荐

  1. 一,Serializer和ModelSerializer

    1.REST Framework概述 Django REST framework是一套基于Django的REST框架,是一个用于构建Web API的功能强大且灵活的工具包. RESTful 简述 Re ...

  2. MySQL内连接,左(外)连接,右(外)连接

    用两个表(a_table.b_table),关联字段a_table.a_id和b_table.b_id来演示一下MySQL的内连接.外连接( 左(外)连接.右(外)连接.全(外)连接). MySQL版 ...

  3. python基础学习Day8 文件的基本操作

    1.文件的基本操作初识 f = open('a.text', 'r', encoding='utf-8')data = f.read()print(data)f.close() 2.读  r  r+b ...

  4. Numpy知识(三)

    ndarray的花式索引. 正负数索引,正数就是从0开始的下标正向寻找,负数是-1开始的负向寻找. arr[[1,5,2,6],[0,3,1,2]]:拿取arr[1,0],arr[5,3],arr[2 ...

  5. canvas刮奖

    (function (global, factory) { typeof module === 'object' && typeof module.exports === 'objec ...

  6. .html() 与.text() 获取值、取值 区别

    1.html代码<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <t ...

  7. excel表格输入思想

    1.创建工作簿  SXSSFWorkbook wb = new SXSSFWorkbook(); //#设置单元格的垂直居中,水平居中,字体颜色 2.创建sheet  Sheet sheet = wb ...

  8. 用PLSQL Developer 查看连接因子 tnsnames.ora

    1 2

  9. 微信小程序开发——全局配置详细介绍

    本文针对官方文档未说明清楚的进行详细探索研究,官方文档详见:全局配置 . pages: 删除页面,需要先删除app.json中pages对应页面的路径,再去删除页面相关的所有文件,不然会出现页面文件混 ...

  10. twitter oa

    字符串括号匹配有效性: 要求从直接return改成了返回yes or no.需要添加到list后break,然后每次循环之前,boolean要重新初始化. array index报错是什么鬼?算了,脑 ...