ANDROID: add vendor hooks and expoert reclaim_pages to reclaim memory

Add vendor hooks to reclaim MADV_PAGEOUT memory for asynchrnous
device. It also exports reclaim_pages to reclaim memory.

Bug: 326662423
Change-Id: Ic2516c64a9dbd53173a3bfb19b6cd21636916c27
Signed-off-by: Minchan Kim <minchan@google.com>
This commit is contained in:
Minchan Kim 2024-05-07 20:52:33 +00:00 committed by Todd Kjos
parent 1d241d978d
commit 6316af1012
5 changed files with 44 additions and 10 deletions

View File

@ -331,6 +331,9 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_alloc_pages_failure_bypass);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_madvise_pageout_swap_entry);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_madvise_swapin_walk_pmd_entry);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_process_madvise_end);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_madvise_pageout_begin);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_madvise_pageout_end);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_reclaim_folio_list);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_smaps_pte_entry);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_show_smap);
EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_ctl_dirty_rate);

View File

@ -439,6 +439,7 @@ extern int vm_swappiness;
long remove_mapping(struct address_space *mapping, struct folio *folio);
extern unsigned long reclaim_pages(struct list_head *page_list);
extern unsigned long __reclaim_pages(struct list_head *page_list, void *private);
#ifdef CONFIG_NUMA
extern int node_reclaim_mode;
extern int sysctl_min_unmapped_ratio;

View File

@ -99,6 +99,15 @@ DECLARE_HOOK(android_vh_madvise_swapin_walk_pmd_entry,
DECLARE_HOOK(android_vh_process_madvise_end,
TP_PROTO(int behavior, ssize_t *ret),
TP_ARGS(behavior, ret));
DECLARE_RESTRICTED_HOOK(android_rvh_madvise_pageout_begin,
TP_PROTO(void **private),
TP_ARGS(private), 1);
DECLARE_RESTRICTED_HOOK(android_rvh_madvise_pageout_end,
TP_PROTO(void *private, struct list_head *folio_list),
TP_ARGS(private, folio_list), 1);
DECLARE_RESTRICTED_HOOK(android_rvh_reclaim_folio_list,
TP_PROTO(struct list_head *folio_list, void *private),
TP_ARGS(folio_list, private), 1);
DECLARE_HOOK(android_vh_smaps_pte_entry,
TP_PROTO(swp_entry_t entry, unsigned long *writeback,
unsigned long *same, unsigned long *huge),

View File

@ -42,6 +42,7 @@
struct madvise_walk_private {
struct mmu_gather *tlb;
bool pageout;
void *private;
};
/*
@ -426,7 +427,7 @@ static int madvise_cold_or_pageout_pte_range(pmd_t *pmd,
huge_unlock:
spin_unlock(ptl);
if (pageout)
reclaim_pages(&page_list);
__reclaim_pages(&page_list, private->private);
return 0;
}
@ -534,7 +535,7 @@ static int madvise_cold_or_pageout_pte_range(pmd_t *pmd,
arch_leave_lazy_mmu_mode();
pte_unmap_unlock(orig_pte, ptl);
if (pageout)
reclaim_pages(&page_list);
__reclaim_pages(&page_list, private->private);
cond_resched();
return 0;
@ -591,10 +592,17 @@ static void madvise_pageout_page_range(struct mmu_gather *tlb,
.pageout = true,
.tlb = tlb,
};
LIST_HEAD(folio_list);
trace_android_rvh_madvise_pageout_begin(&walk_private.private);
tlb_start_vma(tlb, vma);
walk_page_range(vma->vm_mm, addr, end, &cold_walk_ops, &walk_private);
tlb_end_vma(tlb, vma);
trace_android_rvh_madvise_pageout_end(walk_private.private, &folio_list);
if (!list_empty(&folio_list))
reclaim_pages(&folio_list);
}
static long madvise_pageout(struct vm_area_struct *vma,

View File

@ -73,6 +73,9 @@
#undef CREATE_TRACE_POINTS
#include <trace/hooks/vmscan.h>
#undef CREATE_TRACE_POINTS
#include <trace/hooks/mm.h>
EXPORT_TRACEPOINT_SYMBOL_GPL(mm_vmscan_direct_reclaim_begin);
EXPORT_TRACEPOINT_SYMBOL_GPL(mm_vmscan_direct_reclaim_end);
EXPORT_TRACEPOINT_SYMBOL_GPL(mm_vmscan_kswapd_wake);
@ -2717,7 +2720,8 @@ static void shrink_active_list(unsigned long nr_to_scan,
}
static unsigned int reclaim_folio_list(struct list_head *folio_list,
struct pglist_data *pgdat)
struct pglist_data *pgdat,
void *private)
{
struct reclaim_stat dummy_stat;
unsigned int nr_reclaimed;
@ -2731,16 +2735,20 @@ static unsigned int reclaim_folio_list(struct list_head *folio_list,
};
nr_reclaimed = shrink_folio_list(folio_list, pgdat, &sc, &dummy_stat, false);
while (!list_empty(folio_list)) {
folio = lru_to_folio(folio_list);
list_del(&folio->lru);
folio_putback_lru(folio);
if (private) {
trace_android_rvh_reclaim_folio_list(folio_list, private);
} else {
while (!list_empty(folio_list)) {
folio = lru_to_folio(folio_list);
list_del(&folio->lru);
folio_putback_lru(folio);
}
}
return nr_reclaimed;
}
unsigned long reclaim_pages(struct list_head *folio_list)
unsigned long __reclaim_pages(struct list_head *folio_list, void *private)
{
int nid;
unsigned int nr_reclaimed = 0;
@ -2762,17 +2770,22 @@ unsigned long reclaim_pages(struct list_head *folio_list)
continue;
}
nr_reclaimed += reclaim_folio_list(&node_folio_list, NODE_DATA(nid));
nr_reclaimed += reclaim_folio_list(&node_folio_list, NODE_DATA(nid), private);
nid = folio_nid(lru_to_folio(folio_list));
} while (!list_empty(folio_list));
nr_reclaimed += reclaim_folio_list(&node_folio_list, NODE_DATA(nid));
nr_reclaimed += reclaim_folio_list(&node_folio_list, NODE_DATA(nid), private);
memalloc_noreclaim_restore(noreclaim_flag);
return nr_reclaimed;
}
unsigned long reclaim_pages(struct list_head *folio_list)
{
return __reclaim_pages(folio_list, NULL);
}
static unsigned long shrink_list(enum lru_list lru, unsigned long nr_to_scan,
struct lruvec *lruvec, struct scan_control *sc)
{