4.9 Linux 内核源代码中的 PageWriteback 定义在哪里?

4.9 Linux 内核源代码中的 PageWriteback 定义在哪里?

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:

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-tempsgcc 标志,以便保存中间预处理器文件:

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"

相关内容