Re: what is "compound_page()" all about?

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

 



On Wed, Nov 03, 2010 at 01:24:22PM -0400, Robert P. J. Day wrote:
> 
>   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

Up to this point, your good, but I think you got derailed here looking
for at the PAGEFLAGS_EXTENDED Kconfig option.  If you look a little
closer, there is actually an #else, with a different definition of
PageTail below, which uses a single page flag PG_compound, in
combination with PG_reclaim to determine whether a page is a 'head' page
or 'tail' page.  Here is the relavant comment:

   /*
    * PG_reclaim is used in combination with PG_compound to mark the
    * head and tail of a compound page. This saves one page flag
    * but makes it impossible to use compound pages for the page cache.
    * The PG_reclaim bit would have to be used for reclaim or readahead
    * if compound pages enter the page cache.
    *
    * PG_compound & PG_reclaim>--=> Tail page
    * PG_compound & ~PG_reclaim>-=> Head page
    */

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

Yep, this is explained above.

> 
>   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?

Yep, from the comment above, you can see that there is a limitation of
hijacking the PG_reclaim bit in the page flags, in that 'compound' pages can't
be used in the page cache.

If there is sufficient space available in the struct page for an additional
flag, enabling PAGEFLAGS_EXTENDED will eliminate this restriction by using a
PG_head and PG_tail flag.

As far as the page count goes, IIRC 'compound' pages only maintain a count on
the head page.

Hope that helps.

-- 
                                    joshc

--
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