Commit 5acc17fd authored by Kefeng Wang's avatar Kefeng Wang Committed by Andrew Morton

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.comSigned-off-by: default avatarKefeng Wang <wangkefeng.wang@huawei.com>
Reviewed-by: default avatarSeongJae 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: default avatarAndrew Morton <akpm@linux-foundation.org>
parent becacb04
...@@ -31,19 +31,22 @@ ...@@ -31,19 +31,22 @@
* *
* This function tries to get a user memory page by pfn as described above. * 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 page *page = pfn_to_online_page(pfn);
struct folio *folio;
if (!page || !PageLRU(page) || if (!page || PageTail(page))
!get_page_unless_zero(page))
return NULL; return NULL;
if (unlikely(!PageLRU(page))) { folio = page_folio(page);
put_page(page); if (!folio_test_lru(folio) || !folio_try_get(folio))
page = NULL; 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, 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, ...@@ -83,10 +86,8 @@ static bool page_idle_clear_pte_refs_one(struct folio *folio,
return true; 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 * Since rwc.try_lock is unused, rwc is effectively immutable, so we
* can make it static to save some cycles and stack. * 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, ...@@ -115,7 +116,7 @@ static ssize_t page_idle_bitmap_read(struct file *file, struct kobject *kobj,
loff_t pos, size_t count) loff_t pos, size_t count)
{ {
u64 *out = (u64 *)buf; u64 *out = (u64 *)buf;
struct page *page; struct folio *folio;
unsigned long pfn, end_pfn; unsigned long pfn, end_pfn;
int bit; int bit;
...@@ -134,19 +135,19 @@ static ssize_t page_idle_bitmap_read(struct file *file, struct kobject *kobj, ...@@ -134,19 +135,19 @@ static ssize_t page_idle_bitmap_read(struct file *file, struct kobject *kobj,
bit = pfn % BITMAP_CHUNK_BITS; bit = pfn % BITMAP_CHUNK_BITS;
if (!bit) if (!bit)
*out = 0ULL; *out = 0ULL;
page = page_idle_get_page(pfn); folio = page_idle_get_folio(pfn);
if (page) { if (folio) {
if (page_is_idle(page)) { if (folio_test_idle(folio)) {
/* /*
* The page might have been referenced via a * The page might have been referenced via a
* pte, in which case it is not idle. Clear * pte, in which case it is not idle. Clear
* refs and recheck. * refs and recheck.
*/ */
page_idle_clear_pte_refs(page); page_idle_clear_pte_refs(folio);
if (page_is_idle(page)) if (folio_test_idle(folio))
*out |= 1ULL << bit; *out |= 1ULL << bit;
} }
put_page(page); folio_put(folio);
} }
if (bit == BITMAP_CHUNK_BITS - 1) if (bit == BITMAP_CHUNK_BITS - 1)
out++; out++;
...@@ -160,7 +161,7 @@ static ssize_t page_idle_bitmap_write(struct file *file, struct kobject *kobj, ...@@ -160,7 +161,7 @@ static ssize_t page_idle_bitmap_write(struct file *file, struct kobject *kobj,
loff_t pos, size_t count) loff_t pos, size_t count)
{ {
const u64 *in = (u64 *)buf; const u64 *in = (u64 *)buf;
struct page *page; struct folio *folio;
unsigned long pfn, end_pfn; unsigned long pfn, end_pfn;
int bit; int bit;
...@@ -178,11 +179,11 @@ static ssize_t page_idle_bitmap_write(struct file *file, struct kobject *kobj, ...@@ -178,11 +179,11 @@ static ssize_t page_idle_bitmap_write(struct file *file, struct kobject *kobj,
for (; pfn < end_pfn; pfn++) { for (; pfn < end_pfn; pfn++) {
bit = pfn % BITMAP_CHUNK_BITS; bit = pfn % BITMAP_CHUNK_BITS;
if ((*in >> bit) & 1) { if ((*in >> bit) & 1) {
page = page_idle_get_page(pfn); folio = page_idle_get_folio(pfn);
if (page) { if (folio) {
page_idle_clear_pte_refs(page); page_idle_clear_pte_refs(folio);
set_page_idle(page); folio_set_idle(folio);
put_page(page); folio_put(folio);
} }
} }
if (bit == BITMAP_CHUNK_BITS - 1) if (bit == BITMAP_CHUNK_BITS - 1)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment