Thanks for your careful review.No problem!! It's a valuable learning experience for me.
My bad. What I meant was, if CONFIG_KSM is undefined, then- if (PageKsm(page))This might need an #ifdef?
+ if (mapping & PAGE_MAPPING_KSM)
u |= 1 << KPF_KSM;
Say mapping is movable and anon -- then (mapping & PAGE_MAPPING_KSM) is
true. Before, we called PageKsm, which falls through to a PG_ksm check.
If !CONFIG_KSM then that flag is always false. But now, we're liable to
report KPF_KSM even if !CONFIG_KSM.
I'm not sure where you see a PG_ksm check:
static __always_inline bool folio_test_ksm(const struct folio *folio)
{
return ((unsigned long)folio->mapping & PAGE_MAPPING_FLAGS) ==
PAGE_MAPPING_KSM;
}
static __always_inline bool PageKsm(const struct page *page)
{
return folio_test_ksm(page_folio(page));
}
There's no such thing as a movable anon page -- the two bits in theI see. I misunderstood how the flags are applied.
bottom of the mapping pointer mean:
00 file (or NULL)
01 anon
10 movable
11 KSM
Perhaps it might be clearer to say that anon pages are inherently
movable; the movable type really means that the reset of the mapping
pointer refers to a movable_operations instead of a mapping or anon_vma.
/*This makes sense but it'd require changes to the documentation.
* compound pages: export both head/tail info
* they together define a compound page's start/end pos and order
*/
- if (PageHead(page))
- u |= 1 << KPF_COMPOUND_HEAD;
- if (PageTail(page))
+ if (page == &folio->page)
+ u |= kpf_copy_bit(k, KPF_COMPOUND_HEAD, PG_head);
+ else
u |= 1 << KPF_COMPOUND_TAIL;
I ran a python3 memhog to see if anonymous pages are currently reported
as COMPOUND_HEAD or COMPOUND_TAIL and it seems to be a no on both.
But with this, I think every pfn will have one of the two set.
Unless you can have a page outside of a folio -- not sure.
I see your confusion. We have three cases; head, tail and neither
(obviously a page is never both head & tail). If a page is neither,
it's order-0 and it is the only page in the folio. So we handle head
or neither in the first leg of the 'if' where we set KPF_COMPOUND_HEAD
if PG_head is set, and tail in the 'else' leg.
It's not so much the performance as it is the atomicity. I'm doing myI see. That makes sense.
best to get an atomic snapshot of the flags and report a consistent
state, even if it might be stale by the time the user sees it.