ANDROID: mm: add reclaim_shmem_address_space() for faster reclaims

Add the functionality that allow users of shmem to reclaim its pages
without going through the kswapd/direct reclaim path. An example usecase
is: Say that device allocates a larger amount of shmem pages and shares
it with hardware. To faster reclaims such pages, drivers can register
the shrinkers and call reclaim_shmem_address_space().

This commit is a squash of changes that contains all the fixes in the
reclaim_shmem_address_space() API.

Bug: 201263305
Bug: 263340150
Change-Id: I03d2c3b9610612af977f89ddeabb63b8e9e50918
Signed-off-by: Charan Teja Reddy <charante@codeaurora.org>
Signed-off-by: Charan Teja Kalla <quic_charante@quicinc.com>
(cherry picked from commit 81102cdb3d594c164676eef4afec4b3c48b55392)
[georgi: Replace page_isolate_lru() with folio_isolate_lru()]
Signed-off-by: Georgi Djakov <quic_c_gdjako@quicinc.com>
This commit is contained in:
Charan Teja Reddy
2021-06-28 16:00:03 +05:30
committed by Georgi Djakov
parent 4c4bfdf7c6
commit 2bc85a5a38
2 changed files with 40 additions and 0 deletions
+1
View File
@@ -4072,6 +4072,7 @@ unsigned long wp_shared_mapping_range(struct address_space *mapping,
#endif
extern int sysctl_nr_trim_pages;
extern int reclaim_shmem_address_space(struct address_space *mapping);
#ifdef CONFIG_PRINTK
void mem_dump_obj(void *object);
+39
View File
@@ -40,6 +40,7 @@
#include <linux/fs_parser.h>
#include <linux/swapfile.h>
#include <linux/iversion.h>
#include <linux/mm_inline.h>
#include "swap.h"
static struct vfsmount *shm_mnt __ro_after_init;
@@ -5369,3 +5370,41 @@ struct page *shmem_read_mapping_page_gfp(struct address_space *mapping,
return page;
}
EXPORT_SYMBOL_GPL(shmem_read_mapping_page_gfp);
int reclaim_shmem_address_space(struct address_space *mapping)
{
#ifdef CONFIG_SHMEM
pgoff_t start = 0;
struct page *page;
LIST_HEAD(page_list);
XA_STATE(xas, &mapping->i_pages, start);
if (!shmem_mapping(mapping))
return -EINVAL;
lru_add_drain();
rcu_read_lock();
xas_for_each(&xas, page, ULONG_MAX) {
if (xas_retry(&xas, page))
continue;
if (xa_is_value(page))
continue;
if (!folio_isolate_lru(page_folio(page)))
continue;
list_add(&page->lru, &page_list);
if (need_resched()) {
xas_pause(&xas);
cond_resched_rcu();
}
}
rcu_read_unlock();
return reclaim_pages(&page_list);
#else
return 0;
#endif
}
EXPORT_SYMBOL_GPL(reclaim_shmem_address_space);