Skip to content

Commit

Permalink
mm: round down folio split requirements
Browse files Browse the repository at this point in the history
When we truncate we always check if we can split a large folio, we do
this by checking the userspace mapped pages match folio_nr_pages() - 1,
but if we are using a filesystem or a block device which has a min order
it must be respected and we should only split rounding down to the
min order page requirements.

Without this we could end up splitting up a folio below the min order
and later on a new readahead use it, but readahead code already assumes
the minorder is respected so any checks there for the min order will
force a crash.

This fixes the odd folio order 0 issue found with fsx op 114 and we
move up to fsx ops 116. We crash on that now here on
do_async_mmap_readahead() on:

WARN_ON_ONCE(round_down(vmf->pgoff, nrpages) != folio->index);

[   17.236177] WARNING: CPU: 2 PID: 616 at mm/filemap.c:3290 filemap_fault+0x862/0xc10
[   17.238864] Modules linked in: xfs <etc>
[   17.258835] CPU: 2 PID: 616 Comm: fsx Not tainted 6.5.0-rc3-next-20230724+ torvalds#219
[   17.261578] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
[   17.264885] RIP: 0010:filemap_fault+0x862/0xc10
[   17.266681] Code: <whatever>
[   17.273292] RSP: 0000:ffffad9b805a3cd8 EFLAGS: 00010297
[   17.275417] RAX: 0000000000000014 RBX: ffffdc7844c43a00 RCX: 0000000000000010
[   17.278079] RDX: ffff8d5f96dad958 RSI: ffff8d5f85d482b0 RDI: 00000000ffffffff
[   17.280726] RBP: ffffad9b805a3e08 R08: 00000000ffffefff R09: 00000000ffffefff
[   17.283181] R10: ffffffffb1666a00 R11: ffffffffb1666a00 R12: ffff8d5f85d482b0
[   17.285550] R13: ffff8d5f9fa7a200 R14: 0000000000000014 R15: ffff8d5f85d48138
[   17.287910] FS:  00007fa1478d0740(0000) GS:ffff8d5ffbc80000(0000) knlGS:0000000000000000
[   17.290359] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[   17.292218] CR2: 00007fa147846000 CR3: 000000011eebc006 CR4: 0000000000170ee0
[   17.294332] Call Trace:
[   17.295296]  <TASK>
[   17.296178]  ? filemap_fault+0x862/0xc10
[   17.297517]  ? __warn+0x81/0x130
[   17.298635]  ? filemap_fault+0x862/0xc10
[   17.299904]  ? report_bug+0x191/0x1c0
[   17.301071]  ? handle_bug+0x41/0x70
[   17.302170]  ? exc_invalid_op+0x17/0x70
[   17.303359]  ? asm_exc_invalid_op+0x1a/0x20
[   17.304603]  ? filemap_fault+0x862/0xc10
[   17.305743]  ? filemap_fault+0x544/0xc10
[   17.306874]  ? __mod_lruvec_page_state+0xce/0x200
[   17.308151]  ? page_add_file_rmap+0xaa/0x2c0
[   17.309273]  __do_fault+0x33/0x1c0
[   17.310213]  do_fault+0x2b2/0x4c0
[   17.311131]  __handle_mm_fault+0x74c/0xd80
[   17.312215]  handle_mm_fault+0x130/0x300
[   17.313203]  do_user_addr_fault+0x201/0x650
[   17.314236]  exc_page_fault+0x77/0x170
[   17.315195]  asm_exc_page_fault+0x26/0x30
[   17.316223] RIP: 0033:0x7fa147a25747

Signed-off-by: Luis Chamberlain <mcgrof@kernel.org>
  • Loading branch information
mcgrof authored and Panky-codes committed Aug 28, 2023
1 parent 565220a commit a444847
Showing 1 changed file with 10 additions and 2 deletions.
12 changes: 10 additions & 2 deletions mm/huge_memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -2592,16 +2592,24 @@ static void __split_huge_page(struct page *page, struct list_head *list,
bool can_split_folio(struct folio *folio, int *pextra_pins)
{
int extra_pins;
unsigned int min_order = 0;
unsigned int nrpages;

/* Additional pins from page cache */
if (folio_test_anon(folio))
extra_pins = folio_test_swapcache(folio) ?
folio_nr_pages(folio) : 0;
else
else {
extra_pins = folio_nr_pages(folio);
if (folio->mapping)
min_order = mapping_min_folio_order(folio->mapping);
}

nrpages = 1UL << min_order;

if (pextra_pins)
*pextra_pins = extra_pins;
return folio_mapcount(folio) == folio_ref_count(folio) - extra_pins - 1;
return folio_mapcount(folio) == folio_ref_count(folio) - extra_pins - nrpages;
}

/*
Expand Down

0 comments on commit a444847

Please sign in to comment.