somewhat embarrassed to admit i'd never noticed this before, but it
has to do with pages and page flags.
LKD3, on p. 232, discusses the "_count" member field of "struct
page", and states that that field, when it reaches *negative one*,
represents a page that is no longer in use and is now available for
another allocation. however, it recommends that no one look at that
field directly; instead, use the page_count() function, which takes as
its argument a page structure. also, the book claims that, while the
_count field internally will use -1 to show free, page_count() will
return a zero to show the same thing.
ok, so knowing that, we can examine the page_count() function in
<linux/mm.h> and see how it represents that:
static inline int page_count(struct page *page)
{
return atomic_read(&compound_head(page)->_count);
}
um ... ok, so it's an atomic read of that member field (not
surprising), but it pulls in something called "compound_head()". and
that's defined right above that routine:
static inline struct page *compound_head(struct page *page)
{
if (unlikely(PageTail(page)))
return page->first_page;
return page;
}
ok, now i'm confused by this "first_page" field, so let's check out
<linux/page-flags.h> for this "PageTail" routine. now, everything
related to that can be found in that header file surrounded by:
#ifdef CONFIG_PAGEFLAGS_EXTENDED
/*
* System with lots of page flags available. This allows separate
* flags for PageHead() and PageTail() checks of compound pages so that bit
* tests can be used in performance sensitive paths. PageCompound is
* generally not used in hot code paths.
*/
__PAGEFLAG(Head, head)
__PAGEFLAG(Tail, tail)
... snip ...
#endif
and further up that same file, we have:
enum pageflags {
... snip ...
#ifdef CONFIG_PAGEFLAGS_EXTENDED
PG_head, /* A head page */
PG_tail, /* A tail page */
#else
PG_compound, /* A compound page */
#endif
...
};
i can see the entry in the mm/Kconfig file:
# If we have space for more page flags then we can enable additional
# optimizations and functionality.
#
# Regular Sparsemem takes page flag bits for the sectionid if it does not
# use a virtual memmap. Disable extended page flags for 32 bit platforms
# that require the use of a sectionid in the page flags.
#
config PAGEFLAGS_EXTENDED
def_bool y
depends on 64BIT || SPARSEMEM_VMEMMAP || !SPARSEMEM
but i have to admit, i don't know what that means. thoughts? and how
does all that map back to the proper use of the page_count() routine?
rday
--
========================================================================
Robert P. J. Day Waterloo, Ontario, CANADA
http://crashcourse.ca
Twitter: http://twitter.com/rpjday
LinkedIn: http://ca.linkedin.com/in/rpjday
========================================================================
--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to [email protected]
Please read the FAQ at http://kernelnewbies.org/FAQ