All of lore.kernel.org
 help / color / mirror / Atom feed
* PageLRU and the other flags
@ 2020-09-25 15:00 Matthew Wilcox
  2020-09-25 15:21 ` David Hildenbrand
  0 siblings, 1 reply; 3+ messages in thread
From: Matthew Wilcox @ 2020-09-25 15:00 UTC (permalink / raw)
  To: linux-mm

I'm not quite familiar with this side of the MM yet, but it seems to
me like we're encoding four page states in three bits:

 - !PageLRU (not an LRU page)
 - PageLRU (on the inactive list)
 - PageLRU + PageActive (on the active list)
 - PageLRU + PageUnevictable (on the unevictable list)

Can we neaten this up into two bits?

 - 00 (not an LRU page)
 - 01 (active list)
 - 10 (inactive list)
 - 11 (unevictable)

People who free up page flags are always popular, right?

I don't think the missing combos are used:

!LRU + Active
!LRU + Active + Unevictable
!LRU + Unevictable
LRU + Active + Unevictable

It seems fairly straightforward to add these macros:

bool PageLRU(struct page *page)
{
	page->flags & PAGE_FLAGS_LRU_MASK;
}

bool PageActive(struct page *page)
{
	page->flags & PAGE_FLAGS_LRU_MASK == PAGE_FLAGS_ACTIVE;
}

bool PageInactive(struct page *page)
{
	page->flags & PAGE_FLAGS_LRU_MASK == PAGE_FLAGS_INACTIVE;
}

bool PageUnevictable(struct page *page)
{
	page->flags & PAGE_FLAGS_LRU_MASK == PAGE_FLAGS_UNEVICTABLE;
}

SetPageActive seems a little more tricky to do atomically.  A cmpxchg()
loop, perhaps?  If we changed the API to be PageUnevictableToActive(page)
then it's an atomic subtraction / addition (although it's now twelve
macro instead of six Set/Clear for three bits).  Then I'm not sure how
to do TestClearPageActive().  Maybe TryPageActiveToInactive()?  That'd be
another twelve macros if all those state transitions are possible.


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: PageLRU and the other flags
  2020-09-25 15:00 PageLRU and the other flags Matthew Wilcox
@ 2020-09-25 15:21 ` David Hildenbrand
  2020-09-25 15:44   ` Yang Shi
  0 siblings, 1 reply; 3+ messages in thread
From: David Hildenbrand @ 2020-09-25 15:21 UTC (permalink / raw)
  To: Matthew Wilcox, linux-mm

On 25.09.20 17:00, Matthew Wilcox wrote:
> I'm not quite familiar with this side of the MM yet, but it seems to
> me like we're encoding four page states in three bits:
> 
>  - !PageLRU (not an LRU page)
>  - PageLRU (on the inactive list)
>  - PageLRU + PageActive (on the active list)
>  - PageLRU + PageUnevictable (on the unevictable list)
> 
> Can we neaten this up into two bits?
> 
>  - 00 (not an LRU page)
>  - 01 (active list)
>  - 10 (inactive list)
>  - 11 (unevictable)
> 
> People who free up page flags are always popular, right?

They are the best :)

Looking at __pagevec_lru_add_fn()

SetPageLRU(page);
smp_mb__after_atomic();
...

if (page_evictable(page)) {
	...
} else {
	lru = LRU_UNEVICTABLE;
	ClearPageActive(page);
	SetPageUnevictable(page);
	...
}

Looks like PageActive(page) could have been relevant even without
SetPageLRU(page);

So the combo

!PageLRU() + PageActive (previously was on the active list maybe?)

might be valid? Or dead code? Or valid races (someone else spotting
PageLRU() and setting it PageActive(page))?

But no expert, just blindly poking around ...

-- 
Thanks,

David / dhildenb



^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: PageLRU and the other flags
  2020-09-25 15:21 ` David Hildenbrand
@ 2020-09-25 15:44   ` Yang Shi
  0 siblings, 0 replies; 3+ messages in thread
From: Yang Shi @ 2020-09-25 15:44 UTC (permalink / raw)
  To: David Hildenbrand; +Cc: Matthew Wilcox, Linux MM

On Fri, Sep 25, 2020 at 8:21 AM David Hildenbrand <david@redhat.com> wrote:
>
> On 25.09.20 17:00, Matthew Wilcox wrote:
> > I'm not quite familiar with this side of the MM yet, but it seems to
> > me like we're encoding four page states in three bits:
> >
> >  - !PageLRU (not an LRU page)
> >  - PageLRU (on the inactive list)
> >  - PageLRU + PageActive (on the active list)
> >  - PageLRU + PageUnevictable (on the unevictable list)
> >
> > Can we neaten this up into two bits?
> >
> >  - 00 (not an LRU page)
> >  - 01 (active list)
> >  - 10 (inactive list)
> >  - 11 (unevictable)
> >
> > People who free up page flags are always popular, right?
>
> They are the best :)
>
> Looking at __pagevec_lru_add_fn()
>
> SetPageLRU(page);
> smp_mb__after_atomic();
> ...
>
> if (page_evictable(page)) {
>         ...
> } else {
>         lru = LRU_UNEVICTABLE;
>         ClearPageActive(page);
>         SetPageUnevictable(page);
>         ...
> }
>
> Looks like PageActive(page) could have been relevant even without
> SetPageLRU(page);
>
> So the combo
>
> !PageLRU() + PageActive (previously was on the active list maybe?)
>
> might be valid? Or dead code? Or valid races (someone else spotting
> PageLRU() and setting it PageActive(page))?

Yes, it is valid. The page might be marked active when it is on
pagevec, then will be moved to active LRU in the next drain. Please
refer to the comment in mark_page_accessed().

> But no expert, just blindly poking around ...
>
> --
> Thanks,
>
> David / dhildenb
>
>


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-09-25 15:44 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-25 15:00 PageLRU and the other flags Matthew Wilcox
2020-09-25 15:21 ` David Hildenbrand
2020-09-25 15:44   ` Yang Shi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.