"address_space()" 在 linux 内核中定义为 "Sparse" 注释
"address_space()" definition as a "Sparse" annotation in the linux kernel
我遇到了一些定义如下的宏:
#ifdef __CHECKER__
# define __user __attribute__((noderef, address_space(1)))
而且我知道这些仅用于稀疏(__CHECKER__) 并且 GCC 忽略它们 completely.But 我不明白的是address_space()
到底是什么意思?它的可能值是什么?看起来它的唯一文档是大约 16 年前的 post from linus in the mailing list,上面写着:
When you do use parse, it is another matter entirely. For
"sparse", that "__iomem" has lots of meaning:
# define __iomem __attribute__((noderef, address_space(2)))
ie "iomem" means two separate things: it means that sparse should complain
if the pointer is ever dereferenced (it's a "noderef" pointer) directly,
and it's in "address space 2" as opposed to the normal address space (0).
从 this and this 等类似的问答中,我发现 3 表示 per-cpu 指针和 1 似乎与从 userspace.And 收到的指针有关,也与 0 的普通指针有关。
但是 address_space(2) 到底是什么意思?
{0,1,2,3} 是唯一可能的值吗?
谢谢。
address_space()
和 noderef
是属性。可能令人困惑的是它们不是 GCC 属性。它们是 Sparse 属性,因此只有在定义 __CHECKER__
并启用 Sparse
时,它们才对 Sparse
有意义。
address_space()
属性对标记它的指针施加了特定限制。我的理解是,作为参数的数字是任意选择的,表示指针属于某个 class。因此,如果你遵循规则,你应该清楚地注释一个指针属于特定的 class(例如 __user
或 __iomem
等),而不是混合来自不同 [=36] 的指针=]是的。使用这些注释,Sparse
作为静态检查器可以帮助您发现不正确使用的情况。
对于 address_space(2)
又名 __iomem
我在这里找到了一个很好的描述:What is the use of __iomem in linux while writing device drivers? Linus 的 post 也是一个很好的描述。
除了 {0,1,2,3} 还有 {4} 将 __rcu
指针标记为分开 class。我认为目前没有更多。
此属性将用于指针,以指定相应内存的地址 space 不同于通常的内核内存。因此,不能通过简单地取消引用指针来访问它,而是需要通过一些特定的函数集(或宏)来访问它。 Sparse 将具有不同地址 spaces 的指针视为不同的类型,并将警告混合地址 spaces.
的强制转换(隐式或显式)
地址space曾经用一个小数字来标识,但在当前的内核中使用了一个标识符。允许的值(对于内核)是:
- __user/1:用于user-space内存(通过get_user()/put_user(), copy_from_user()访问/copy_to_user(), ...)
- __iomem/2: 用于 I/O 内存(通过 ioread{8,16,32,64}(), writel()/readl(), .. .)
- __percpu/3:用于'per-CPU'内存(要访问get_cpu_var()/put_cpu_var(),...,还需要专门分配或声明:alloc_percpu(), DECLARE_PER_CPU(), ...)
- __rcu/4:用于 'RCU' 内存(通过 rcu_dereference(), ... 访问)
- 0: 是默认值,用于普通内核内存。
某些文档可在 https://sparse.docs.kernel.org/en/latest/annotations.html 获得。
我遇到了一些定义如下的宏:
#ifdef __CHECKER__
# define __user __attribute__((noderef, address_space(1)))
而且我知道这些仅用于稀疏(__CHECKER__) 并且 GCC 忽略它们 completely.But 我不明白的是address_space()
到底是什么意思?它的可能值是什么?看起来它的唯一文档是大约 16 年前的 post from linus in the mailing list,上面写着:
When you do use parse, it is another matter entirely. For "sparse", that "__iomem" has lots of meaning:
# define __iomem __attribute__((noderef, address_space(2)))
ie "iomem" means two separate things: it means that sparse should complain if the pointer is ever dereferenced (it's a "noderef" pointer) directly, and it's in "address space 2" as opposed to the normal address space (0).
从 this and this 等类似的问答中,我发现 3 表示 per-cpu 指针和 1 似乎与从 userspace.And 收到的指针有关,也与 0 的普通指针有关。
但是 address_space(2) 到底是什么意思?
{0,1,2,3} 是唯一可能的值吗?
谢谢。
address_space()
和 noderef
是属性。可能令人困惑的是它们不是 GCC 属性。它们是 Sparse 属性,因此只有在定义 __CHECKER__
并启用 Sparse
时,它们才对 Sparse
有意义。
address_space()
属性对标记它的指针施加了特定限制。我的理解是,作为参数的数字是任意选择的,表示指针属于某个 class。因此,如果你遵循规则,你应该清楚地注释一个指针属于特定的 class(例如 __user
或 __iomem
等),而不是混合来自不同 [=36] 的指针=]是的。使用这些注释,Sparse
作为静态检查器可以帮助您发现不正确使用的情况。
对于 address_space(2)
又名 __iomem
我在这里找到了一个很好的描述:What is the use of __iomem in linux while writing device drivers? Linus 的 post 也是一个很好的描述。
除了 {0,1,2,3} 还有 {4} 将 __rcu
指针标记为分开 class。我认为目前没有更多。
此属性将用于指针,以指定相应内存的地址 space 不同于通常的内核内存。因此,不能通过简单地取消引用指针来访问它,而是需要通过一些特定的函数集(或宏)来访问它。 Sparse 将具有不同地址 spaces 的指针视为不同的类型,并将警告混合地址 spaces.
的强制转换(隐式或显式)地址space曾经用一个小数字来标识,但在当前的内核中使用了一个标识符。允许的值(对于内核)是:
- __user/1:用于user-space内存(通过get_user()/put_user(), copy_from_user()访问/copy_to_user(), ...)
- __iomem/2: 用于 I/O 内存(通过 ioread{8,16,32,64}(), writel()/readl(), .. .)
- __percpu/3:用于'per-CPU'内存(要访问get_cpu_var()/put_cpu_var(),...,还需要专门分配或声明:alloc_percpu(), DECLARE_PER_CPU(), ...)
- __rcu/4:用于 'RCU' 内存(通过 rcu_dereference(), ... 访问)
- 0: 是默认值,用于普通内核内存。
某些文档可在 https://sparse.docs.kernel.org/en/latest/annotations.html 获得。