@@ -496,6 +496,7 @@ extern int init_swap_address_space(unsigned int type, unsigned long nr_pages);
extern void exit_swap_address_space(unsigned int type);
extern struct swap_info_struct *get_swap_device(swp_entry_t entry);
sector_t swap_page_sector(struct page *page);
+extern int get_tier_idx(struct lruvec *lruvec, int type);
static inline void put_swap_device(struct swap_info_struct *si)
{
@@ -452,6 +452,18 @@ static int madvise_cold_or_pageout_pte_range(pmd_t *pmd,
if (!folio || folio_is_zone_device(folio))
continue;
+ if (lru_gen_enabled() && pageout) {
+ int gen = folio_lru_gen(folio);
+ struct lruvec *lruvec = folio_lruvec(folio);
+ int type = folio_is_file_lru(folio);
+ int refs = folio_lru_refs(folio);
+ int tier = lru_tier_from_refs(refs);
+ int tier_st = get_tier_idx(lruvec, type);
+
+ if (gen > lru_gen_from_seq(lruvec->lrugen.min_seq[type]) + 1
+ || tier > tier_st)
+ continue;
+ }
/*
* Creating a THP page is expensive so split it only if we
* are sure it's worth. Split it if we are only owner.
@@ -5072,7 +5072,7 @@ static int scan_folios(struct lruvec *lruvec, struct scan_control *sc,
return isolated || !remaining ? scanned : 0;
}
-static int get_tier_idx(struct lruvec *lruvec, int type)
+int get_tier_idx(struct lruvec *lruvec, int type)
{
int tier;
struct ctrl_pos sp, pv;
@@ -5091,6 +5091,7 @@ static int get_tier_idx(struct lruvec *lruvec, int type)
return tier - 1;
}
+EXPORT_SYMBOL_GPL(get_tier_idx);
static int get_type_to_scan(struct lruvec *lruvec, int swappiness, int *tier_idx)
{