mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 20:51:03 +02:00
mm/workingset: Convert workingset_eviction() to take a folio
This removes an assumption that THPs are the only kind of compound pages and removes a few hidden calls to compound_head(). Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> Reviewed-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
@@ -328,7 +328,7 @@ static inline swp_entry_t folio_swap_entry(struct folio *folio)
|
|||||||
|
|
||||||
/* linux/mm/workingset.c */
|
/* linux/mm/workingset.c */
|
||||||
void workingset_age_nonresident(struct lruvec *lruvec, unsigned long nr_pages);
|
void workingset_age_nonresident(struct lruvec *lruvec, unsigned long nr_pages);
|
||||||
void *workingset_eviction(struct page *page, struct mem_cgroup *target_memcg);
|
void *workingset_eviction(struct folio *folio, struct mem_cgroup *target_memcg);
|
||||||
void workingset_refault(struct folio *folio, void *shadow);
|
void workingset_refault(struct folio *folio, void *shadow);
|
||||||
void workingset_activation(struct folio *folio);
|
void workingset_activation(struct folio *folio);
|
||||||
|
|
||||||
|
@@ -1242,6 +1242,7 @@ static pageout_t pageout(struct page *page, struct address_space *mapping)
|
|||||||
static int __remove_mapping(struct address_space *mapping, struct page *page,
|
static int __remove_mapping(struct address_space *mapping, struct page *page,
|
||||||
bool reclaimed, struct mem_cgroup *target_memcg)
|
bool reclaimed, struct mem_cgroup *target_memcg)
|
||||||
{
|
{
|
||||||
|
struct folio *folio = page_folio(page);
|
||||||
int refcount;
|
int refcount;
|
||||||
void *shadow = NULL;
|
void *shadow = NULL;
|
||||||
|
|
||||||
@@ -1289,7 +1290,7 @@ static int __remove_mapping(struct address_space *mapping, struct page *page,
|
|||||||
swp_entry_t swap = { .val = page_private(page) };
|
swp_entry_t swap = { .val = page_private(page) };
|
||||||
mem_cgroup_swapout(page, swap);
|
mem_cgroup_swapout(page, swap);
|
||||||
if (reclaimed && !mapping_exiting(mapping))
|
if (reclaimed && !mapping_exiting(mapping))
|
||||||
shadow = workingset_eviction(page, target_memcg);
|
shadow = workingset_eviction(folio, target_memcg);
|
||||||
__delete_from_swap_cache(page, swap, shadow);
|
__delete_from_swap_cache(page, swap, shadow);
|
||||||
xa_unlock_irq(&mapping->i_pages);
|
xa_unlock_irq(&mapping->i_pages);
|
||||||
put_swap_page(page, swap);
|
put_swap_page(page, swap);
|
||||||
@@ -1315,8 +1316,8 @@ static int __remove_mapping(struct address_space *mapping, struct page *page,
|
|||||||
*/
|
*/
|
||||||
if (reclaimed && page_is_file_lru(page) &&
|
if (reclaimed && page_is_file_lru(page) &&
|
||||||
!mapping_exiting(mapping) && !dax_mapping(mapping))
|
!mapping_exiting(mapping) && !dax_mapping(mapping))
|
||||||
shadow = workingset_eviction(page, target_memcg);
|
shadow = workingset_eviction(folio, target_memcg);
|
||||||
__delete_from_page_cache(page, shadow);
|
__filemap_remove_folio(folio, shadow);
|
||||||
xa_unlock_irq(&mapping->i_pages);
|
xa_unlock_irq(&mapping->i_pages);
|
||||||
if (mapping_shrinkable(mapping))
|
if (mapping_shrinkable(mapping))
|
||||||
inode_add_lru(mapping->host);
|
inode_add_lru(mapping->host);
|
||||||
|
@@ -245,31 +245,32 @@ void workingset_age_nonresident(struct lruvec *lruvec, unsigned long nr_pages)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* workingset_eviction - note the eviction of a page from memory
|
* workingset_eviction - note the eviction of a folio from memory
|
||||||
* @target_memcg: the cgroup that is causing the reclaim
|
* @target_memcg: the cgroup that is causing the reclaim
|
||||||
* @page: the page being evicted
|
* @folio: the folio being evicted
|
||||||
*
|
*
|
||||||
* Return: a shadow entry to be stored in @page->mapping->i_pages in place
|
* Return: a shadow entry to be stored in @folio->mapping->i_pages in place
|
||||||
* of the evicted @page so that a later refault can be detected.
|
* of the evicted @folio so that a later refault can be detected.
|
||||||
*/
|
*/
|
||||||
void *workingset_eviction(struct page *page, struct mem_cgroup *target_memcg)
|
void *workingset_eviction(struct folio *folio, struct mem_cgroup *target_memcg)
|
||||||
{
|
{
|
||||||
struct pglist_data *pgdat = page_pgdat(page);
|
struct pglist_data *pgdat = folio_pgdat(folio);
|
||||||
unsigned long eviction;
|
unsigned long eviction;
|
||||||
struct lruvec *lruvec;
|
struct lruvec *lruvec;
|
||||||
int memcgid;
|
int memcgid;
|
||||||
|
|
||||||
/* Page is fully exclusive and pins page's memory cgroup pointer */
|
/* Folio is fully exclusive and pins folio's memory cgroup pointer */
|
||||||
VM_BUG_ON_PAGE(PageLRU(page), page);
|
VM_BUG_ON_FOLIO(folio_test_lru(folio), folio);
|
||||||
VM_BUG_ON_PAGE(page_count(page), page);
|
VM_BUG_ON_FOLIO(folio_ref_count(folio), folio);
|
||||||
VM_BUG_ON_PAGE(!PageLocked(page), page);
|
VM_BUG_ON_FOLIO(!folio_test_locked(folio), folio);
|
||||||
|
|
||||||
lruvec = mem_cgroup_lruvec(target_memcg, pgdat);
|
lruvec = mem_cgroup_lruvec(target_memcg, pgdat);
|
||||||
/* XXX: target_memcg can be NULL, go through lruvec */
|
/* XXX: target_memcg can be NULL, go through lruvec */
|
||||||
memcgid = mem_cgroup_id(lruvec_memcg(lruvec));
|
memcgid = mem_cgroup_id(lruvec_memcg(lruvec));
|
||||||
eviction = atomic_long_read(&lruvec->nonresident_age);
|
eviction = atomic_long_read(&lruvec->nonresident_age);
|
||||||
workingset_age_nonresident(lruvec, thp_nr_pages(page));
|
workingset_age_nonresident(lruvec, folio_nr_pages(folio));
|
||||||
return pack_shadow(memcgid, pgdat, eviction, PageWorkingset(page));
|
return pack_shadow(memcgid, pgdat, eviction,
|
||||||
|
folio_test_workingset(folio));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user