2

A search for PageWriteback in 4.9 results in: "undefined identifier", yet a search for PageWriteback in 2.6.25 shows that it is defined there.

Why is PageWriteback in use in 4.9 but I can't find a definition for it?

  • 3
    Your title has a question, but the body seems to be two statements. What are you asking? – Jeff Schaller Jul 26 '17 at 18:32
  • 1
    @JeffSchaller Why PageWriteback use in 4.9 but can't found define of it? – illiterate Jul 26 '17 at 18:34
  • So you're saying that a particular identifier is in use, but you can't find where it's being defined? – Jeff Schaller Jul 26 '17 at 18:43
  • 3
    See if my edit captured your intent, please. – Jeff Schaller Jul 26 '17 at 18:53
  • 2
    I think trying to ask for any identifier would be too broad or unclear -- focusing this question on one identifier gives it a chance of an answer (as we've already seen). – Jeff Schaller Jul 26 '17 at 19:01
4

It is (along with many other PageXXX things) defined in include/linux/page-flags.h, but the definition is obscured by the use of macros. See the macro TESTPAGEFLAG in the above file.

In particular, this definition of the TESTPAGEFLAG macro:

#define TESTPAGEFLAG(uname, lname, policy)              \
static __always_inline int Page##uname(struct page *page)       \
    { return test_bit(PG_##lname, &policy(page, 0)->flags); }

combined with this call to TESTPAGEFLAG with the Writeback parameters:

TESTPAGEFLAG(Writeback, writeback, PF_NO_COMPOUND)
1

The general question stuck with me, so I thought I'd add an answer as to how I might go about finding an arbitrary identifier in the Linux kernel.

Download a version of the kernel source (or install your distribution's linux-kernel source package), and extract it:

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

Create a minimal .config, just to make a compilable kernel:

make menuconfig # just exit and save

Key step: compile the kernel with the -save-temps gcc flag so that it saves the intermediate pre-processor files:

make KCFLAGS=-save-temps

The compilation process will drop *.i files in the current directory. Find any file where the identifier is defined; I picked the same identifier here, for ease of comparison, but the process would work for any other identifier; I picked zbud.i only because I liked the filename:

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))); }
...

Open the file for viewing, scroll to the identifier in question, then search up/backwards in the file for a line that starts with # to see where the definition came from:

# 255 "./include/linux/page-flags.h"

which points us to the same source file that Nick found before.

Alternatively, you could search for the include lines and/or the identifier, then delete all the trailing lines; the last line of output will be the file where the identifier was defined:

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"
  • # 255 "./include/linux/page-flags.h" seem isn't definition of the TESTPAGEFLAG macro.I can't understand you how to found define by use your result. – illiterate Jul 28 '17 at 11:12
  • 2
    Nick did an awesome job finding that particular definition; all I did was extend their idea to ("expanding" / combining) the pre-processor tokens to the rest of the kernel so that it'd be easier to find the next one you were curious about. – Jeff Schaller Jul 28 '17 at 15:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.