hulk inclusion category: feature -------------------------------- Wire ZRAM-Reclaim into the VM paths that provide the policy's input signals and consume its scan-balance decision. Record anon swapin cost in do_swap_page() after the PageUptodate check, so failed swapins caused by I/O errors are not counted as reclaim pressure. Use the faulting memcg and the page's pgdat lruvec for the accounting update. Record file refault cost in workingset_refault(). Call zram_reclaim_should_use_policy() from get_scan_count() after the priority-0 near-OOM bypass. A true return selects SCAN_ANON. A false return lets the normal balance path continue; if zram is overloaded the helper has already raised the local swappiness value. The swapin and refault hooks are compiled only when CONFIG_ZRAM_RECLAIM is enabled. Signed-off-by: Ze Zuo <zuoze1@huawei.com> Signed-off-by: Nanyong Sun <sunnanyong@huawei.com> --- mm/memory.c | 17 +++++++++++++++++ mm/vmscan.c | 13 +++++++++++++ mm/workingset.c | 5 +++++ 3 files changed, 35 insertions(+) diff --git a/mm/memory.c b/mm/memory.c index a54204f0f733..c98214f9ef24 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -71,6 +71,7 @@ #include <linux/oom.h> #include <linux/ktask.h> #include <linux/share_pool.h> +#include <linux/zram_reclaim.h> #include <asm/io.h> #include <asm/mmu_context.h> @@ -3081,6 +3082,22 @@ vm_fault_t do_swap_page(struct vm_fault *vmf) goto out_nomap; } +#ifdef CONFIG_ZRAM_RECLAIM + /* + * Record anon swapin cost only for successful swapins (past + * PageUptodate check). Failed swapins are excluded because they + * reflect I/O errors rather than reclaim pressure. This heuristic + * assumes anon swapins come primarily from zram; mixed swap backends + * should only enable it when that topology assumption holds. + */ + if (memcg) { + struct lruvec *zram_lruvec; + + zram_lruvec = mem_cgroup_lruvec(page_pgdat(page), memcg); + zram_reclaim_refault_cost(memcg, zram_lruvec, false, 1); + } +#endif + /* * The page isn't present yet, go ahead with the fault. * diff --git a/mm/vmscan.c b/mm/vmscan.c index fa08ffd043de..343244e1fe10 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -57,6 +57,7 @@ #include <linux/swapops.h> #include <linux/balloon_compaction.h> #include <linux/mem_reliable.h> +#include <linux/zram_reclaim.h> #include "internal.h" @@ -2379,6 +2380,18 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg, goto out; } +#ifdef CONFIG_ZRAM_RECLAIM + /* + * Apply ZRAM reclaim policy. Note: priority 0 (near-OOM) check + * above takes precedence; heuristic policies are bypassed. + */ + if (zram_reclaim_should_use_policy(lruvec, memcg, sc->priority, + &swappiness)) { + scan_balance = SCAN_ANON; + goto out; + } +#endif + /* * Prevent the reclaimer from falling into the cache trap: as * cache pages start out inactive, every cache fault will tip diff --git a/mm/workingset.c b/mm/workingset.c index a1f61b3a0cd3..03c732abb963 100644 --- a/mm/workingset.c +++ b/mm/workingset.c @@ -15,6 +15,7 @@ #include <linux/dax.h> #include <linux/fs.h> #include <linux/mm.h> +#include <linux/zram_reclaim.h> /* * Double CLOCK lists @@ -291,6 +292,10 @@ bool workingset_refault(void *shadow) inc_lruvec_state(lruvec, WORKINGSET_REFAULT); +#ifdef CONFIG_ZRAM_RECLAIM + zram_reclaim_refault_cost(memcg, lruvec, true, 1); +#endif + if (refault_distance <= active_file) { inc_lruvec_state(lruvec, WORKINGSET_ACTIVATE); rcu_read_unlock(); -- 2.25.1