what is "compound_page()" all about?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



  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 ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ



[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux