mm: page_idle: convert page idle to use a folio
Firstly, make page_idle_get_page() return a folio, also rename it to page_idle_get_folio(), then, use it to convert page_idle_bitmap_read() and page_idle_bitmap_write() functions. Link: https://lkml.kernel.org/r/20221230070849.63358-3-wangkefeng.wang@huawei.com Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com> Reviewed-by: SeongJae Park <sj@kernel.org> Cc: David Hildenbrand <david@redhat.com> Cc: Matthew Wilcox (Oracle) <willy@infradead.org> Cc: Vishal Moola (Oracle) <vishal.moola@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
becacb04fd
commit
5acc17fd35
|
@ -31,19 +31,22 @@
|
|||
*
|
||||
* This function tries to get a user memory page by pfn as described above.
|
||||
*/
|
||||
static struct page *page_idle_get_page(unsigned long pfn)
|
||||
static struct folio *page_idle_get_folio(unsigned long pfn)
|
||||
{
|
||||
struct page *page = pfn_to_online_page(pfn);
|
||||
struct folio *folio;
|
||||
|
||||
if (!page || !PageLRU(page) ||
|
||||
!get_page_unless_zero(page))
|
||||
if (!page || PageTail(page))
|
||||
return NULL;
|
||||
|
||||
if (unlikely(!PageLRU(page))) {
|
||||
put_page(page);
|
||||
page = NULL;
|
||||
folio = page_folio(page);
|
||||
if (!folio_test_lru(folio) || !folio_try_get(folio))
|
||||
return NULL;
|
||||
if (unlikely(page_folio(page) != folio || !folio_test_lru(folio))) {
|
||||
folio_put(folio);
|
||||
folio = NULL;
|
||||
}
|
||||
return page;
|
||||
return folio;
|
||||
}
|
||||
|
||||
static bool page_idle_clear_pte_refs_one(struct folio *folio,
|
||||
|
@ -83,10 +86,8 @@ static bool page_idle_clear_pte_refs_one(struct folio *folio,
|
|||
return true;
|
||||
}
|
||||
|
||||
static void page_idle_clear_pte_refs(struct page *page)
|
||||
static void page_idle_clear_pte_refs(struct folio *folio)
|
||||
{
|
||||
struct folio *folio = page_folio(page);
|
||||
|
||||
/*
|
||||
* Since rwc.try_lock is unused, rwc is effectively immutable, so we
|
||||
* can make it static to save some cycles and stack.
|
||||
|
@ -115,7 +116,7 @@ static ssize_t page_idle_bitmap_read(struct file *file, struct kobject *kobj,
|
|||
loff_t pos, size_t count)
|
||||
{
|
||||
u64 *out = (u64 *)buf;
|
||||
struct page *page;
|
||||
struct folio *folio;
|
||||
unsigned long pfn, end_pfn;
|
||||
int bit;
|
||||
|
||||
|
@ -134,19 +135,19 @@ static ssize_t page_idle_bitmap_read(struct file *file, struct kobject *kobj,
|
|||
bit = pfn % BITMAP_CHUNK_BITS;
|
||||
if (!bit)
|
||||
*out = 0ULL;
|
||||
page = page_idle_get_page(pfn);
|
||||
if (page) {
|
||||
if (page_is_idle(page)) {
|
||||
folio = page_idle_get_folio(pfn);
|
||||
if (folio) {
|
||||
if (folio_test_idle(folio)) {
|
||||
/*
|
||||
* The page might have been referenced via a
|
||||
* pte, in which case it is not idle. Clear
|
||||
* refs and recheck.
|
||||
*/
|
||||
page_idle_clear_pte_refs(page);
|
||||
if (page_is_idle(page))
|
||||
page_idle_clear_pte_refs(folio);
|
||||
if (folio_test_idle(folio))
|
||||
*out |= 1ULL << bit;
|
||||
}
|
||||
put_page(page);
|
||||
folio_put(folio);
|
||||
}
|
||||
if (bit == BITMAP_CHUNK_BITS - 1)
|
||||
out++;
|
||||
|
@ -160,7 +161,7 @@ static ssize_t page_idle_bitmap_write(struct file *file, struct kobject *kobj,
|
|||
loff_t pos, size_t count)
|
||||
{
|
||||
const u64 *in = (u64 *)buf;
|
||||
struct page *page;
|
||||
struct folio *folio;
|
||||
unsigned long pfn, end_pfn;
|
||||
int bit;
|
||||
|
||||
|
@ -178,11 +179,11 @@ static ssize_t page_idle_bitmap_write(struct file *file, struct kobject *kobj,
|
|||
for (; pfn < end_pfn; pfn++) {
|
||||
bit = pfn % BITMAP_CHUNK_BITS;
|
||||
if ((*in >> bit) & 1) {
|
||||
page = page_idle_get_page(pfn);
|
||||
if (page) {
|
||||
page_idle_clear_pte_refs(page);
|
||||
set_page_idle(page);
|
||||
put_page(page);
|
||||
folio = page_idle_get_folio(pfn);
|
||||
if (folio) {
|
||||
page_idle_clear_pte_refs(folio);
|
||||
folio_set_idle(folio);
|
||||
folio_put(folio);
|
||||
}
|
||||
}
|
||||
if (bit == BITMAP_CHUNK_BITS - 1)
|
||||
|
|
Loading…
Reference in New Issue