泰晓科技 -- 聚焦 Linux - 追本溯源,见微知著!
网站地址:https://tinylab.org

泰晓Linux实验盘,即刻上手内核与嵌入式开发
请稍侯

LWN 155344: 有关 `gfp_t`

Wang Chen 创作于 2018/10/31

原文:Introducing gfp_t 原创:By corbet @ Oct. 11, 2005 翻译:By unicornx of TinyLab.org 校对:By Xiaojie Yuan

Most kernel functions which deal with memory allocation take a set of “GFP flags” as an argument. These flags describe the allocation and how it should be satisfied; among other things, they control whether it is possible to sleep while waiting for memory, whether high memory can be used, and whether it is possible to call into the filesystem code. The flags are a simple integer value, and that leads to a potential problem: coding errors could result in functions being called with incorrect arguments. An occasional error has turned up where function arguments have gotten confused (usually through ordering mistakes). The resulting bugs can be strange and hard to track down.

内核中大多数处理内存分配的函数都会在参数中传递一组 “GFP 标志”(译者注, GFP 即 Get Free Page 的缩写)。这些标志描述了调用者对内存分配的要求;其中包括:分配内存时是否允许睡眠,是否可以使用高端内存,以及是否可以在分配内存过程中调用文件系统相关的代码等等。因为 “GFP 标志” 是一个简单的整数值,这可能会导致一个潜在的问题:即由于编程错误使得对函数传入了错误的参数。已经发现一种很少出现但会导致函数参数值发生混乱的情况(通常是因为传递参数时顺序不对所造成,译者注,参考 原先的 __alloc_pages() 的函数定义,第一个参数 gfp_mask 和第二个参数 order 的类型都是 unsigned int)。这些奇怪的错误一般都很难追查。

A while back, the __nocast attribute was added to catch these mistakes. This attribute simply says that automatic type coercion should not be applied; it is used by the sparse utility. A more complete solution is on the way, now, in the form of a new gfp_t type. The patch defining this type, and changing several kernel interfaces, was posted by Al Viro and merged just before 2.6.14-rc4 came out. There are several more patches in the series, but they have evidently been put on hold for now.

针对以上问题,不久前,内核采用的解决方法是在函数定义时对 “GFP 标志” 参数添加 __nocast 属性声明(译者注,参考一个改进后的例子),该属性的作用是简单地声明代码中传参时不可以对该参数进行强制类型转换,然后我们就可以利用 sparse 这个工具(译者注,参考 wiki Sparse)来辅助检查并捕获这类错误。现在,一种更好的解决方案正在开发中,该方案将创建一种新的类型叫做 gfp_t。相关补丁由 Al Viro 提交,除了定义此类型外还会更改多个内核接口,并已经在 2.6.14-rc4 之前被合入集成分支。该补丁系列中还有其他几处改动,但它们目前暂时没有被一起合入。

The patches are surprisingly large and intrusive; it turns out that quite a few kernel functions accept GFP flags as arguments. For all that, the actual code generated does not change, and the code, as seen by gcc, changes very little. Once the patch set is complete, however, it will allow comprehensive type checking of GFP flag arguments, catching a whole class of potential bugs before they bite anybody.

Al Viro 的补丁改动非常大;可见,相当多的内核函数会使用 “GFP 标志” 作为参数。尽管如此,其实该补丁对实际生成的机器指令并没有改变,对于 gcc (即编译器)来说其所看到的代码变化很小(译者注,只是把原先的 unsigned int 换成了 typedef,具体参考前述补丁描述)。然而,一旦主线合入该补丁后,它将允许对 “GFP 标志” 参数进行全面的类型检查,从而在实际运行之前就可以提前发现那些潜在的错误。



Read Album:

Read Related:

Read Latest: