Chapter3:MemoryManagement
be using two different functions and select the proper one each time it is called with some pre-processor
conditionals:
void do_something() {
...
#ifdef CONFIG_WORK_HARD
do_work_fast();
#else
do_work_at_your_leisure();
#endif
...
}
Since this requires using the pre-processor each time the function is called, this approach is consid-
ered bad style by the kernel developers. A much more elegant solution is to define the function itself
differently depending on the chosen configuration:
#ifdef CONFIG_WORK_HARD
void do_work() {
/* Get going, fast! */
...
}
#else
void do_work() {
/* Relax, take it easy */
...
}
#endif
Notice that the same name is employed for both implementations because they can never be active
at the same time. Calling the proper function is now not more complicated than calling a regular
function:
void do_something() {
...
do_work(); /* Work hard or not, depending on configuration /*
...
}
Clearly, this variant is much more readable and is always preferred by the kernel developers (in fact,
patches using the first style will have a very hard time getting into the mainline kernel, if at all).
Let us go back to setting up the zone lists. The portion ofbuild_all_zoneliststhat is currently of
interest to us (there is some more work to do for the page group mobility extensions to the page allocator,
but I will discuss this separately below) delegates all work to__build_all_zonelists, which, in turn,
invokesbuild_zonelistsfor each NUMA node in the system.
mm/page_alloc.c
static int __build_all_zonelists(void *dummy)
{
int nid;