ANDROID: vendor_hooks: account page-mapcount

Support five hooks as follows to account
the amount of multi-mapped pages in kernel:

- android_vh_show_mapcount_pages
- android_vh_do_traversal_lruvec
- android_vh_update_page_mapcount
- android_vh_add_page_to_lrulist
- android_vh_del_page_from_lrulist

Bug: 236578020
Signed-off-by: Peifeng Li <lipeifeng@oppo.com>
Change-Id: Ia2c7015aab442be7dbb496b8b630b9dff59ab935
This commit is contained in:
Peifeng Li
2022-06-23 14:15:35 +08:00
committed by Suren Baghdasaryan
parent 1d2287f56e
commit 3f775b9367
8 changed files with 129 additions and 23 deletions

View File

@@ -1113,6 +1113,7 @@ void do_page_add_anon_rmap(struct page *page,
{
bool compound = flags & RMAP_COMPOUND;
bool first;
bool success = false;
if (unlikely(PageKsm(page)))
lock_page_memcg(page);
@@ -1126,7 +1127,10 @@ void do_page_add_anon_rmap(struct page *page,
mapcount = compound_mapcount_ptr(page);
first = atomic_inc_and_test(mapcount);
} else {
first = atomic_inc_and_test(&page->_mapcount);
trace_android_vh_update_page_mapcount(page, true, compound,
&first, &success);
if (!success)
first = atomic_inc_and_test(&page->_mapcount);
}
if (first) {
@@ -1200,13 +1204,22 @@ void __page_add_new_anon_rmap(struct page *page,
void page_add_file_rmap(struct page *page, bool compound)
{
int i, nr = 1;
bool first_mapping;
bool success = false;
VM_BUG_ON_PAGE(compound && !PageTransHuge(page), page);
lock_page_memcg(page);
if (compound && PageTransHuge(page)) {
for (i = 0, nr = 0; i < thp_nr_pages(page); i++) {
if (atomic_inc_and_test(&page[i]._mapcount))
nr++;
trace_android_vh_update_page_mapcount(&page[i], true,
compound, &first_mapping, &success);
if ((success)) {
if (first_mapping)
nr++;
} else {
if (atomic_inc_and_test(&page[i]._mapcount))
nr++;
}
}
if (!atomic_inc_and_test(compound_mapcount_ptr(page)))
goto out;
@@ -1222,8 +1235,15 @@ void page_add_file_rmap(struct page *page, bool compound)
if (PageMlocked(page))
clear_page_mlock(compound_head(page));
}
if (!atomic_inc_and_test(&page->_mapcount))
goto out;
trace_android_vh_update_page_mapcount(page, true,
compound, &first_mapping, &success);
if (success) {
if (!first_mapping)
goto out;
} else {
if (!atomic_inc_and_test(&page->_mapcount))
goto out;
}
}
__mod_lruvec_page_state(page, NR_FILE_MAPPED, nr);
out:
@@ -1233,6 +1253,8 @@ out:
static void page_remove_file_rmap(struct page *page, bool compound)
{
int i, nr = 1;
bool first_mapping;
bool success = false;
VM_BUG_ON_PAGE(compound && !PageHead(page), page);
@@ -1246,8 +1268,15 @@ static void page_remove_file_rmap(struct page *page, bool compound)
/* page still mapped by someone else? */
if (compound && PageTransHuge(page)) {
for (i = 0, nr = 0; i < thp_nr_pages(page); i++) {
if (atomic_add_negative(-1, &page[i]._mapcount))
nr++;
trace_android_vh_update_page_mapcount(&page[i], false,
compound, &first_mapping, &success);
if (success) {
if (first_mapping)
nr++;
} else {
if (atomic_add_negative(-1, &page[i]._mapcount))
nr++;
}
}
if (!atomic_add_negative(-1, compound_mapcount_ptr(page)))
return;
@@ -1256,8 +1285,15 @@ static void page_remove_file_rmap(struct page *page, bool compound)
else
__dec_node_page_state(page, NR_FILE_PMDMAPPED);
} else {
if (!atomic_add_negative(-1, &page->_mapcount))
return;
trace_android_vh_update_page_mapcount(page, false,
compound, &first_mapping, &success);
if (success) {
if (!first_mapping)
return;
} else {
if (!atomic_add_negative(-1, &page->_mapcount))
return;
}
}
/*
@@ -1274,6 +1310,8 @@ static void page_remove_file_rmap(struct page *page, bool compound)
static void page_remove_anon_compound_rmap(struct page *page)
{
int i, nr;
bool first_mapping;
bool success = false;
if (!atomic_add_negative(-1, compound_mapcount_ptr(page)))
return;
@@ -1293,8 +1331,15 @@ static void page_remove_anon_compound_rmap(struct page *page)
* them are still mapped.
*/
for (i = 0, nr = 0; i < thp_nr_pages(page); i++) {
if (atomic_add_negative(-1, &page[i]._mapcount))
nr++;
trace_android_vh_update_page_mapcount(&page[i], false,
false, &first_mapping, &success);
if (success) {
if (first_mapping)
nr++;
} else {
if (atomic_add_negative(-1, &page[i]._mapcount))
nr++;
}
}
/*
@@ -1324,6 +1369,8 @@ static void page_remove_anon_compound_rmap(struct page *page)
*/
void page_remove_rmap(struct page *page, bool compound)
{
bool first_mapping;
bool success = false;
lock_page_memcg(page);
if (!PageAnon(page)) {
@@ -1336,10 +1383,16 @@ void page_remove_rmap(struct page *page, bool compound)
goto out;
}
/* page still mapped by someone else? */
if (!atomic_add_negative(-1, &page->_mapcount))
goto out;
trace_android_vh_update_page_mapcount(page, false,
compound, &first_mapping, &success);
if (success) {
if (!first_mapping)
goto out;
} else {
/* page still mapped by someone else? */
if (!atomic_add_negative(-1, &page->_mapcount))
goto out;
}
/*
* We use the irq-unsafe __{inc|mod}_zone_page_stat because
* these counters are not modified in interrupt context, and