]
FYI
----- Forwarded message from Hugh Dickins <[email protected]> -----
From: Hugh Dickins <[email protected]>
Date: Wed, 2 Feb 2005 21:56:53 +0000 (GMT)
To: Marcelo Tosatti <[email protected]>
In-Reply-To: <[email protected]>
Subject: Re: [[email protected]: Re: Q: shrink_cache() vs
Quoted 34 lines
----- Forwarded message from Marcelo Tosatti <[email protected]> -----
From: Marcelo Tosatti <[email protected]>
Date: Mon, 17 Jan 2005 07:17:23 -0200
To: Oleg Nesterov <[email protected]>, [email protected]
Cc: [email protected]
Subject: Re: Q:shrink_cache()vsrelease_pages()page->lrumanagementHi Oleg,
Quoted 23 lines · Oleg Nesterov
Another attempt, message was truncated...
shrink_cache:if (get_page_testone(page)) { __put_page(page); SetPageLRU(page); list_add(&page->lru, &zone->inactive_list); continue; }Is it really necessary to re-add the page to
inactive_list?It seems to me that
shrink_cache()can just do:if (get_page_testone(page)) { __put_page(page); --zone->nr_inactive; continue; }When the
__page_cache_release(or whatever) takeszone->lru_lockit must checkPG_lrubeforedel_page_from_lru().
Quoted 6 lines
Quoted 1 line
The same question applies to
refill_inactive_zone().Yes it seems OK to not re-add the page to LRU if "zero" page (-1 count) is found, since all callers which set page count to zero (
release_pagesand__page_cache_release()) are going to remove the page from LRU and most likely free it anyway.
Yes, I agree with both of you that it can equally be done his way.
No huge incentive to change it, and this no-page-count-for-the-LRU area has given 2.4 and 2.6 trouble and trouble, bugs lurking for years. I just re-read Andrew's ChangeLog-2.6.7 entry about get_page_testone (which I always read as "get_page_testosterone"!), and that certainly wasn't the first bug hereabouts, remember all the PageLRU headaches in 2.4's __free_pages_ok.
But I don't think it'd be introducing any bug, and it is good practice to remove unnecessary magic, so I'd back Oleg on this.
Though Andrew might object that this then makes the vmscan.c side even more dependent on knowing what the swap.c side does.
Quoted 1 line
The original code is just being safe I guess...
Yes, it think it's based on the principle that the side which brings page_count down to 0 (-1) should have control, and the other side which finds this should restore all state before dropping the lock.
But as Oleg observes, it simply isn't state which needs restoring.
I haven't fully thought through the (anyway buggy) pre-2.6.7 situation, but perhaps there was a race perceived there, whereby the page_count 0 (-1) page could get left behind unfreeable if it wasn't put back onto the LRU. Hmm, no, I don't think putting back on the LRU would solve anything if so. But it could be a relic of an even earlier version, where it did play an important part.
Quoted 22 lines
/*
* This path almost never happens for VM activity - pages are normally
* freed via pagevecs. But it gets used by networking.
*/
void fastcall__page_cache_release(struct page *page){ unsigned long flags; struct zone *zone = page_zone(page); spin_lock_irqsave(&zone->lru_lock, flags); if (TestClearPageLRU(page)) del_page_from_lru(zone, page); if (page_count(page) != 0) page = NULL; spin_unlock_irqrestore(&zone->lru_lock, flags); if (page) free_hot_page(page); }Looking at
__page_cache_release()it handles the case where another reference count is grabbed in the meantime (see thepage_count(page)!= 0 check).
Quoted 7 lines
Now that makes me wonder: in what case
page_count(page)!= 0 can happen during__page_cache_release()? Any user who has a direct pointer to the page could do that - pagecache pages have already been removed from the radix tree and can't be reached through it at this point in time.And when that happens, does the reference grabber has to re-add the page to LRU since it has just been removed from LRU by
__page_cache_release? Looks cheesy.
I was looking at the sources and framing my reply before reading this far down your mail. And I too was thinking that those two page_count checks in swap.c ought to be unnecessary now (though needed pre-2.6.7).
Do BUG_ON(page_count(page))? Shouldn't even need that, would hit the "Bad page state" message very soon. Best test for a while under load before removing those page_count checks, though!
Hugh
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>