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.
|
* 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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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)
|
||||||
|
Loading…
Reference in New Issue
Block a user