Change the guts of check_move_unevictable_pages() over to use folios
and add check_move_unevictable_pages() as a wrapper.
Signed-off-by: Matthew Wilcox (Oracle) <[email protected]>
---
include/linux/swap.h | 3 ++-
mm/vmscan.c | 55 ++++++++++++++++++++++++++------------------
2 files changed, 35 insertions(+), 23 deletions(-)
diff --git a/include/linux/swap.h b/include/linux/swap.h
index 0c0fed1b348f..8672a7123ccd 100644
--- a/include/linux/swap.h
+++ b/include/linux/swap.h
@@ -438,7 +438,8 @@ static inline bool node_reclaim_enabled(void)
return node_reclaim_mode & (RECLAIM_ZONE|RECLAIM_WRITE|RECLAIM_UNMAP);
}
-extern void check_move_unevictable_pages(struct pagevec *pvec);
+void check_move_unevictable_folios(struct folio_batch *fbatch);
+void check_move_unevictable_pages(struct pagevec *pvec);
extern void kswapd_run(int nid);
extern void kswapd_stop(int nid);
diff --git a/mm/vmscan.c b/mm/vmscan.c
index f7d9a683e3a7..5222c5ad600a 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -4790,45 +4790,56 @@ int node_reclaim(struct pglist_data *pgdat, gfp_t gfp_mask, unsigned int order)
}
#endif
+void check_move_unevictable_pages(struct pagevec *pvec)
+{
+ struct folio_batch fbatch;
+ unsigned i;
+
+ for (i = 0; i < pvec->nr; i++) {
+ struct page *page = pvec->pages[i];
+
+ if (PageTransTail(page))
+ continue;
+ folio_batch_add(&fbatch, page_folio(page));
+ }
+ check_move_unevictable_folios(&fbatch);
+}
+EXPORT_SYMBOL_GPL(check_move_unevictable_pages);
+
/**
- * check_move_unevictable_pages - check pages for evictability and move to
- * appropriate zone lru list
- * @pvec: pagevec with lru pages to check
+ * check_move_unevictable_folios - Move evictable folios to appropriate zone
+ * lru list
+ * @fbatch: Batch of lru folios to check.
*
- * Checks pages for evictability, if an evictable page is in the unevictable
+ * Checks folios for evictability, if an evictable folio is in the unevictable
* lru list, moves it to the appropriate evictable lru list. This function
- * should be only used for lru pages.
+ * should be only used for lru folios.
*/
-void check_move_unevictable_pages(struct pagevec *pvec)
+void check_move_unevictable_folios(struct folio_batch *fbatch)
{
struct lruvec *lruvec = NULL;
int pgscanned = 0;
int pgrescued = 0;
int i;
- for (i = 0; i < pvec->nr; i++) {
- struct page *page = pvec->pages[i];
- struct folio *folio = page_folio(page);
- int nr_pages;
-
- if (PageTransTail(page))
- continue;
+ for (i = 0; i < fbatch->nr; i++) {
+ struct folio *folio = fbatch->folios[i];
+ int nr_pages = folio_nr_pages(folio);
- nr_pages = thp_nr_pages(page);
pgscanned += nr_pages;
- /* block memcg migration during page moving between lru */
- if (!TestClearPageLRU(page))
+ /* block memcg migration while the folio moves between lrus */
+ if (!folio_test_clear_lru(folio))
continue;
lruvec = folio_lruvec_relock_irq(folio, lruvec);
- if (page_evictable(page) && PageUnevictable(page)) {
- del_page_from_lru_list(page, lruvec);
- ClearPageUnevictable(page);
- add_page_to_lru_list(page, lruvec);
+ if (folio_evictable(folio) && folio_test_unevictable(folio)) {
+ lruvec_del_folio(lruvec, folio);
+ folio_clear_unevictable(folio);
+ lruvec_add_folio(lruvec, folio);
pgrescued += nr_pages;
}
- SetPageLRU(page);
+ folio_set_lru(folio);
}
if (lruvec) {
@@ -4839,4 +4850,4 @@ void check_move_unevictable_pages(struct pagevec *pvec)
count_vm_events(UNEVICTABLE_PGSCANNED, pgscanned);
}
}
-EXPORT_SYMBOL_GPL(check_move_unevictable_pages);
+EXPORT_SYMBOL_GPL(check_move_unevictable_folios);
--
2.35.1
On Sun, Jun 05, 2022 at 08:38:52PM +0100, Matthew Wilcox (Oracle) wrote:
> Change the guts of check_move_unevictable_pages() over to use folios
> and add check_move_unevictable_pages() as a wrapper.
The changes here look fine, but please also add patches for converting
the two callers (which looks mostly trivial to me).
Greeting,
FYI, we noticed the following commit (built with gcc-11):
commit: bc9eb0d5ef0a437e399f0fe3b7430b9da5ef9f95 ("[PATCH 08/10] vmscan: Add check_move_unevictable_folios()")
url: https://github.com/intel-lab-lkp/linux/commits/Matthew-Wilcox-Oracle/Convert-to-filemap_get_folios/20220606-034220
base: https://git.kernel.org/cgit/linux/kernel/git/tytso/ext4.git dev
patch link: https://lore.kernel.org/linux-fsdevel/[email protected]
in testcase: boot
on test machine: qemu-system-x86_64 -enable-kvm -cpu SandyBridge -smp 2 -m 16G
caused below changes (please refer to attached dmesg/kmsg for entire log/backtrace):
+---------------------------------------------------------------+------------+------------+
| | 9f1a7a0465 | bc9eb0d5ef |
+---------------------------------------------------------------+------------+------------+
| boot_successes | 24 | 0 |
| boot_failures | 0 | 26 |
| BUG:KASAN:stack-out-of-bounds_in_check_move_unevictable_pages | 0 | 26 |
| canonical_address#:#[##] | 0 | 26 |
| RIP:check_move_unevictable_folios | 0 | 26 |
| Kernel_panic-not_syncing:Fatal_exception | 0 | 26 |
+---------------------------------------------------------------+------------+------------+
If you fix the issue, kindly add following tag
Reported-by: kernel test robot <[email protected]>
[ 40.053150][ T1] ==================================================================
[ 40.054793][ T1] BUG: KASAN: stack-out-of-bounds in check_move_unevictable_pages+0x34c/0x40f
[ 40.056610][ T1] Write of size 8 at addr ffff88810083fd88 by task swapper/0/1
[ 40.056720][ T1]
[ 40.056720][ T1] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.18.0-rc5-00033-gbc9eb0d5ef0a #1
[ 40.056720][ T1] Call Trace:
[ 40.056720][ T1] <TASK>
[ 40.056720][ T1] dump_stack_lvl+0x45/0x59
[ 40.056720][ T1] ? check_move_unevictable_pages+0x34c/0x40f
[ 40.056720][ T1] print_address_description.cold+0xcc/0x404
[ 40.056720][ T1] ? check_move_unevictable_pages+0x34c/0x40f
[ 40.056720][ T1] print_report.cold+0x36/0x20b
[ 40.056720][ T1] kasan_report+0xbe/0x199
[ 40.056720][ T1] ? check_move_unevictable_pages+0x34c/0x40f
[ 40.056720][ T1] check_move_unevictable_pages+0x34c/0x40f
[ 40.056720][ T1] ? check_move_unevictable_folios+0xba6/0xba6
[ 40.056720][ T1] ? lock_is_held_type+0x9c/0x111
[ 40.056720][ T1] ? lru_lazyfree_fn+0x245/0x245
[ 40.056720][ T1] ? lock_release+0xdf/0x1fb
[ 40.056720][ T1] ? mlock_page_drain_local+0x1a9/0x31b
[ 40.056720][ T1] ? lock_is_held_type+0x96/0x111
[ 40.056720][ T1] drm_gem_put_pages+0x206/0x363
[ 40.056720][ T1] ? drm_gem_vm_open+0x75/0x75
[ 40.056720][ T1] ? slab_free_freelist_hook+0xba/0x167
[ 40.056720][ T1] ? drm_gem_shmem_vunmap+0x121/0x1a2
[ 40.056720][ T1] drm_gem_shmem_put_pages_locked+0xf8/0x1f2
[ 40.056720][ T1] drm_gem_shmem_vunmap+0x13a/0x1a2
[ 40.056720][ T1] drm_gem_vunmap+0xcb/0x1d0
[ 40.056720][ T1] drm_fbdev_cleanup+0x251/0x33d
[ 40.056720][ T1] drm_fbdev_client_hotplug+0x3fa/0x50e
[ 40.056720][ T1] drm_fbdev_generic_setup+0x16b/0x3f0
[ 40.056720][ T1] vkms_create+0x401/0x470
[ 40.056720][ T1] ? drm_sched_pick_best.cold+0x32/0x32
[ 40.056720][ T1] ? drm_sched_fence_slab_init+0x31/0x31
[ 40.056720][ T1] ? __kasan_kmalloc+0x81/0x95
[ 40.056720][ T1] ? vgem_init+0x1cb/0x1cb
[ 40.056720][ T1] do_one_initcall+0xbc/0x3db
[ 40.056720][ T1] ? trace_event_raw_event_initcall_level+0x19c/0x19c
[ 40.056720][ T1] ? parameq+0xcc/0xcc
[ 40.056720][ T1] do_initcalls+0x1ce/0x202
[ 40.056720][ T1] kernel_init_freeable+0x21f/0x250
[ 40.056720][ T1] ? rest_init+0x202/0x202
[ 40.056720][ T1] kernel_init+0x19/0x12b
[ 40.056720][ T1] ret_from_fork+0x22/0x30
[ 40.056720][ T1] </TASK>
[ 40.056720][ T1]
[ 40.056720][ T1] The buggy address belongs to stack of task swapper/0/1
[ 40.056720][ T1] and is located at offset 120 in frame:
[ 40.056720][ T1] vkms_create+0x0/0x470
[ 40.056720][ T1]
[ 40.056720][ T1] This frame has 1 object:
[ 40.056720][ T1] [32, 120) 'pdevinfo'
[ 40.056720][ T1]
[ 40.056720][ T1] The buggy address belongs to the physical page:
[ 40.056720][ T1] page:(____ptrval____) refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x10083f
[ 40.056720][ T1] flags: 0x8000000000000000(zone=2)
[ 40.056720][ T1] raw: 8000000000000000 ffffea0004020fc8 ffffea0004020fc8 0000000000000000
[ 40.056720][ T1] raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000
[ 40.056720][ T1] page dumped because: kasan: bad access detected
[ 40.056720][ T1] page_owner tracks the page as allocated
[ 40.056720][ T1] page last allocated via order 0, migratetype Unmovable, gfp_mask 0x0(), pid 1, tgid 1 (swapper/0), ts 22266683981, free_ts 0
[ 40.056720][ T1] register_early_stack+0x65/0xa4
[ 40.056720][ T1] init_page_owner+0x2a/0xa7
[ 40.056720][ T1] kernel_init_freeable+0x1d7/0x250
[ 40.056720][ T1] kernel_init+0x19/0x12b
[ 40.056720][ T1] page_owner free stack trace missing
[ 40.056720][ T1]
[ 40.056720][ T1] Memory state around the buggy address:
[ 40.056720][ T1] ffff88810083fc80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 40.056720][ T1] ffff88810083fd00: 00 00 f1 f1 f1 f1 00 00 00 00 00 00 00 00 00 00
[ 40.056720][ T1] >ffff88810083fd80: 00 f3 f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00
[ 40.056720][ T1] ^
[ 40.056720][ T1] ffff88810083fe00: 00 f1 f1 f1 f1 00 00 00 00 00 00 00 00 f3 f3 f3
[ 40.056720][ T1] ffff88810083fe80: f3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 40.056720][ T1] ==================================================================
[ 40.146127][ T1] Disabling lock debugging due to kernel taint
[ 40.147606][ T1] general protection fault, probably for non-canonical address 0xdffffc0000000048: 0000 [#1] SMP KASAN PTI
[ 40.150060][ T1] KASAN: null-ptr-deref in range [0x0000000000000240-0x0000000000000247]
[ 40.150060][ T1] CPU: 0 PID: 1 Comm: swapper/0 Tainted: G B 5.18.0-rc5-00033-gbc9eb0d5ef0a #1
[ 40.150060][ T1] RIP: 0010:check_move_unevictable_folios+0x140/0xba6
[ 40.150060][ T1] Code: 48 c1 e8 03 80 3c 28 00 0f 85 b1 07 00 00 48 63 c3 4d 8b 7c c5 08 be 08 00 00 00 4c 89 ff e8 e2 e6 12 00 4c 89 f8 48 c1 e8 03 <80> 3c 28 00 0f 85 a8 07 00 00 49 8b 07 a9 00 00 01 00 74 05 0f 1f
[ 40.150060][ T1] RSP: 0000:ffff88810083f930 EFLAGS: 00010207
[ 40.150060][ T1] RAX: 0000000000000048 RBX: 0000000000000000 RCX: ffffffff8154d44e
[ 40.150060][ T1] RDX: 0000000000000000 RSI: 0000000000000008 RDI: 0000000000000246
[ 40.150060][ T1] RBP: dffffc0000000000 R08: 000000000000024e R09: 0000000000000000
[ 40.150060][ T1] R10: ffffffff8154d44e R11: fffffbfff0e09dc8 R12: ffff88810083f9e0
[ 40.150060][ T1] R13: ffff88810083f9d8 R14: 000000000000007e R15: 0000000000000246
[ 40.150060][ T1] FS: 0000000000000000(0000) GS:ffff8883aec00000(0000) knlGS:0000000000000000
[ 40.150060][ T1] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 40.150060][ T1] CR2: ffff88843ffff000 CR3: 0000000005466000 CR4: 00000000000406f0
[ 40.150060][ T1] Call Trace:
[ 40.150060][ T1] <TASK>
[ 40.150060][ T1] ? kasan_report.cold+0x10/0x1a
[ 40.150060][ T1] check_move_unevictable_pages+0x156/0x40f
[ 40.150060][ T1] ? check_move_unevictable_folios+0xba6/0xba6
[ 40.150060][ T1] ? lock_is_held_type+0xa5/0x111
[ 40.150060][ T1] ? lru_lazyfree_fn+0x245/0x245
[ 40.150060][ T1] ? lock_release+0xdf/0x1fb
[ 40.150060][ T1] ? mlock_page_drain_local+0x1a9/0x31b
[ 40.150060][ T1] ? lock_is_held_type+0x96/0x111
[ 40.150060][ T1] drm_gem_put_pages+0x206/0x363
[ 40.150060][ T1] ? drm_gem_vm_open+0x75/0x75
[ 40.150060][ T1] ? slab_free_freelist_hook+0xba/0x167
[ 40.150060][ T1] ? drm_gem_shmem_vunmap+0x121/0x1a2
[ 40.150060][ T1] drm_gem_shmem_put_pages_locked+0xf8/0x1f2
[ 40.150060][ T1] drm_gem_shmem_vunmap+0x13a/0x1a2
[ 40.150060][ T1] drm_gem_vunmap+0xcb/0x1d0
[ 40.150060][ T1] drm_fbdev_cleanup+0x251/0x33d
[ 40.150060][ T1] drm_fbdev_client_hotplug+0x3fa/0x50e
[ 40.150060][ T1] drm_fbdev_generic_setup+0x16b/0x3f0
[ 40.150060][ T1] vkms_create+0x401/0x470
[ 40.150060][ T1] ? drm_sched_pick_best.cold+0x32/0x32
[ 40.150060][ T1] ? drm_sched_fence_slab_init+0x31/0x31
[ 40.150060][ T1] ? vgem_init+0x1cb/0x1cb
[ 40.150060][ T1] do_one_initcall+0xbc/0x3db
[ 40.150060][ T1] ? trace_event_raw_event_initcall_level+0x19c/0x19c
[ 40.150060][ T1] ? parameq+0xcc/0xcc
[ 40.150060][ T1] do_initcalls+0x1ce/0x202
[ 40.150060][ T1] kernel_init_freeable+0x21f/0x250
[ 40.150060][ T1] ? rest_init+0x202/0x202
[ 40.150060][ T1] kernel_init+0x19/0x12b
[ 40.150060][ T1] ret_from_fork+0x22/0x30
[ 40.150060][ T1] </TASK>
To reproduce:
# build kernel
cd linux
cp config-5.18.0-rc5-00033-gbc9eb0d5ef0a .config
make HOSTCC=gcc-11 CC=gcc-11 ARCH=x86_64 olddefconfig prepare modules_prepare bzImage modules
make HOSTCC=gcc-11 CC=gcc-11 ARCH=x86_64 INSTALL_MOD_PATH=<mod-install-dir> modules_install
cd <mod-install-dir>
find lib/ | cpio -o -H newc --quiet | gzip > modules.cgz
git clone https://github.com/intel/lkp-tests.git
cd lkp-tests
bin/lkp qemu -k <bzImage> -m modules.cgz job-script # job-script is attached in this email
# if come across any failure that blocks the test,
# please remove ~/.lkp and /lkp dir to run from a clean state.
--
0-DAY CI Kernel Test Service
https://01.org/lkp
On Wed, Jun 08, 2022 at 01:07:32AM -0700, Christoph Hellwig wrote:
> On Sun, Jun 05, 2022 at 08:38:52PM +0100, Matthew Wilcox (Oracle) wrote:
> > Change the guts of check_move_unevictable_pages() over to use folios
> > and add check_move_unevictable_pages() as a wrapper.
>
> The changes here look fine, but please also add patches for converting
> the two callers (which looks mostly trivial to me).
I do want to get rid of pagevecs entirely, but that conversion isn't
going to happen in time for the next merge window. for_each_sgt_page()
is a little intimidating.
On Wed, Jun 08, 2022 at 05:32:34PM +0100, Matthew Wilcox wrote:
> On Wed, Jun 08, 2022 at 01:07:32AM -0700, Christoph Hellwig wrote:
> > On Sun, Jun 05, 2022 at 08:38:52PM +0100, Matthew Wilcox (Oracle) wrote:
> > > Change the guts of check_move_unevictable_pages() over to use folios
> > > and add check_move_unevictable_pages() as a wrapper.
> >
> > The changes here look fine, but please also add patches for converting
> > the two callers (which looks mostly trivial to me).
>
> I do want to get rid of pagevecs entirely, but that conversion isn't
> going to happen in time for the next merge window. for_each_sgt_page()
> is a little intimidating.
for_each_sgt_page, just like other creative scatterlist abuse in the gpu
code is a beast. But, instead of doing a for_each_sgt_page to add
pages to the pagevec and then do a loop over the pagevec to add to
the folio batch it should be pretty trivial to just cut out the
middle man.