4.9 中对 PageWriteback 的搜索结果是:“未定义的标识符”,但是 2.6.25 中搜索 PageWriteback表明它是在那里定义的。
为什么PageWriteback
在 4.9 中使用但我找不到它的定义?
答案1
它(以及许多其他 PageXXX 事物)在 中定义include/linux/page-flags.h
,但该定义因宏的使用而变得模糊。请参阅TESTPAGEFLAG
上面文件中的宏。
特别是,这TESTPAGEFLAG 宏的定义:
#define TESTPAGEFLAG(uname, lname, policy) \
static __always_inline int Page##uname(struct page *page) \
{ return test_bit(PG_##lname, &policy(page, 0)->flags); }
TESTPAGEFLAG(Writeback, writeback, PF_NO_COMPOUND)
答案2
这个一般性问题一直困扰着我,所以我想添加一个关于如何在 Linux 内核中查找任意标识符的答案。
下载一个版本的内核源代码(或安装您的发行版的 linux-kernel 源代码包),然后解压:
wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.9.39.tar.xz
tar xf linux-4.9.39.tar.xz
cd linux-4.9.39
创建一个最小的 .config,只是为了制作一个可编译的内核:
make menuconfig # just exit and save
关键步骤:编译内核使用-save-temps
gcc 标志,以便保存中间预处理器文件:
make KCFLAGS=-save-temps
编译过程将*.i
在当前目录中放置文件。查找定义了该标识符的任何文件;为了便于比较,我在这里选择了相同的标识符,但该过程适用于任何其他标识符;我选择 zbud.i 只是因为我喜欢这个文件名:
grep PageWriteback *.i
...
zbud.i:static inline __attribute__((no_instrument_function)) __attribute__((always_inline)) int PageWriteback(struct page *page) { return (__builtin_constant_p((PG_writeback)) ? constant_test_bit((PG_writeback), (&({ ((void)(sizeof(( long)(0 && PageCompound(page))))); page;})->flags)) : variable_test_bit((PG_writeback), (&({ ((void)(sizeof(( long)(0 && PageCompound(page))))); page;})->flags))); }
...
打开文件进行查看,滚动到有问题的标识符,然后在文件中向上/向后搜索以 开头的行,以#
查看定义的来源:
# 255 "./include/linux/page-flags.h"
这向我们指出了尼克之前找到的相同源文件。
或者,您可以搜索包含行和/或标识符,然后删除所有尾随行;输出的最后一行将是定义标识符的文件:
grep -E '^# |PageWriteback' zbud.i | sed '/PageWriteback/,$d' | tail -n 1
...
# 74 "./include/linux/page-flags.h"
# 108 "./include/linux/page-flags.h"
# 255 "./include/linux/page-flags.h"