Idle THPs

2 messages, 2 authors, 2021-06-14 · open the first message on its own page

Idle THPs

From: Matthew Wilcox <willy@infradead.org>
Date: 2021-06-10 03:43:54

As part of the folio work, I'm looking at PageIdle and PageYoung and
they're defined to operate on PF_ANY.  So, for example, in
pagecache_get_page(), we will call clear_page_idle() on the head page
(actually, I changed this in a8cf7f272b5a -- before, it would call
clear_page_idle() on the tail page).

However, we never actually call set_page_idle() on tail pages.  This is
because we only call it here:

                        page = page_idle_get_page(pfn);
                        if (page) {
                                page_idle_clear_pte_refs(page);
                                set_page_idle(page);
                                put_page(page);
                        }

where page_idle_get_page() does:

        struct page *page = pfn_to_online_page(pfn);

        if (!page || !PageLRU(page) ||
            !get_page_unless_zero(page))
                return NULL;

get_page_unless_zero() will always fail for tail pages (as it uses
page_ref_add_unless(), which does not redirect to the head page's
refcount).  So all tail pages read back as !idle in
page_idle_bitmap_read().  Is this intended?  Should they rather
mirror the state of their head page?

Re: Idle THPs

From: SeongJae Park <hidden>
Date: 2021-06-14 08:16:18

From: SeongJae Park <redacted>

On Thu, 10 Jun 2021 04:43:18 +0100 Matthew Wilcox [off-list ref] wrote:
As part of the folio work, I'm looking at PageIdle and PageYoung and
they're defined to operate on PF_ANY.  So, for example, in
pagecache_get_page(), we will call clear_page_idle() on the head page
(actually, I changed this in a8cf7f272b5a -- before, it would call
clear_page_idle() on the tail page).

However, we never actually call set_page_idle() on tail pages.  This is
because we only call it here:

                        page = page_idle_get_page(pfn);
                        if (page) {
                                page_idle_clear_pte_refs(page);
                                set_page_idle(page);
                                put_page(page);
                        }

where page_idle_get_page() does:

        struct page *page = pfn_to_online_page(pfn);

        if (!page || !PageLRU(page) ||
            !get_page_unless_zero(page))
                return NULL;

get_page_unless_zero() will always fail for tail pages (as it uses
page_ref_add_unless(), which does not redirect to the head page's
refcount).  So all tail pages read back as !idle in
page_idle_bitmap_read().  Is this intended?  Should they rather
mirror the state of their head page?
I think this is an intended behavior, as the document[1] says as below:

    For huge pages the idle flag is set only on the head page, so one has to
    read /proc/kpageflags in order to correctly count idle huge pages.

[1] https://www.kernel.org/doc/html/latest/admin-guide/mm/idle_page_tracking.html

Thanks,
SeongJae Park
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help