linux/fs
David Hildenbrand 98b1917cde fs/dax: fix folio splitting issue by resetting old folio order + _nr_pages
Alison reports an issue with fsdax when large extends end up using large
ZONE_DEVICE folios:

[  417.796271] BUG: kernel NULL pointer dereference, address: 0000000000000b00
[  417.796982] #PF: supervisor read access in kernel mode
[  417.797540] #PF: error_code(0x0000) - not-present page
[  417.798123] PGD 2a5c5067 P4D 2a5c5067 PUD 2a5c6067 PMD 0
[  417.798690] Oops: Oops: 0000 [#1] SMP NOPTI
[  417.799178] CPU: 5 UID: 0 PID: 1515 Comm: mmap Tainted: ...
[  417.800150] Tainted: [O]=OOT_MODULE
[  417.800583] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015
[  417.801358] RIP: 0010:__lruvec_stat_mod_folio+0x7e/0x250
[  417.801948] Code: ...
[  417.803662] RSP: 0000:ffffc90002be3a08 EFLAGS: 00010206
[  417.804234] RAX: 0000000000000000 RBX: 0000000000000200 RCX: 0000000000000002
[  417.804984] RDX: ffffffff815652d7 RSI: 0000000000000000 RDI: ffffffff82a2beae
[  417.805689] RBP: ffffc90002be3a28 R08: 0000000000000000 R09: 0000000000000000
[  417.806384] R10: ffffea0007000040 R11: ffff888376ffe000 R12: 0000000000000001
[  417.807099] R13: 0000000000000012 R14: ffff88807fe4ab40 R15: ffff888029210580
[  417.807801] FS:  00007f339fa7a740(0000) GS:ffff8881fa9b9000(0000) knlGS:0000000000000000
[  417.808570] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  417.809193] CR2: 0000000000000b00 CR3: 000000002a4f0004 CR4: 0000000000370ef0
[  417.809925] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[  417.810622] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[  417.811353] Call Trace:
[  417.811709]  <TASK>
[  417.812038]  folio_add_file_rmap_ptes+0x143/0x230
[  417.812566]  insert_page_into_pte_locked+0x1ee/0x3c0
[  417.813132]  insert_page+0x78/0xf0
[  417.813558]  vmf_insert_page_mkwrite+0x55/0xa0
[  417.814088]  dax_fault_iter+0x484/0x7b0
[  417.814542]  dax_iomap_pte_fault+0x1ca/0x620
[  417.815055]  dax_iomap_fault+0x39/0x40
[  417.815499]  __xfs_write_fault+0x139/0x380
[  417.815995]  ? __handle_mm_fault+0x5e5/0x1a60
[  417.816483]  xfs_write_fault+0x41/0x50
[  417.816966]  xfs_filemap_fault+0x3b/0xe0
[  417.817424]  __do_fault+0x31/0x180
[  417.817859]  __handle_mm_fault+0xee1/0x1a60
[  417.818325]  ? debug_smp_processor_id+0x17/0x20
[  417.818844]  handle_mm_fault+0xe1/0x2b0
[...]

The issue is that when we split a large ZONE_DEVICE folio to order-0 ones,
we don't reset the order/_nr_pages.  As folio->_nr_pages overlays
page[1]->memcg_data, once page[1] is a folio, it suddenly looks like it
has folio->memcg_data set.  And we never manually initialize
folio->memcg_data in fsdax code, because we never expect it to be set at
all.

When __lruvec_stat_mod_folio() then stumbles over such a folio, it tries
to use folio->memcg_data (because it's non-NULL) but it does not actually
point at a memcg, resulting in the problem.

Alison also observed that these folios sometimes have "locked" set, which
is rather concerning (folios locked from the beginning ...).  The reason
is that the order for large folios is stored in page[1]->flags, which
become the folio->flags of a new small folio.

Let's fix it by adding a folio helper to clear order/_nr_pages for
splitting purposes.

Maybe we should reinitialize other large folio flags / folio members as
well when splitting, because they might similarly cause harm once page[1]
becomes a folio?  At least other flags in PAGE_FLAGS_SECOND should not be
set for fsdax, so at least page[1]->flags might be as expected with this
fix.

From a quick glimpse, initializing ->mapping, ->pgmap and ->share should
re-initialize most things from a previous page[1] used by large folios
that fsdax cares about.  For example folio->private might not get
reinitialized, but maybe that's not relevant -- no traces of it's use in
fsdax code.  Needs a closer look.

Another thing that should be considered in the future is performing
similar checks as we perform in free_tail_page_prepare()
-- checking pincount etc.
-- when freeing a large fsdax folio.

Link: https://lkml.kernel.org/r/20250410091020.119116-1-david@redhat.com
Fixes: 4996fc547f ("mm: let _folio_nr_pages overlay memcg_data in first tail page")
Fixes: 38607c62b3 ("fs/dax: properly refcount fs dax pages")
Signed-off-by: David Hildenbrand <david@redhat.com>
Reported-by: Alison Schofield <alison.schofield@intel.com>
Closes: https://lkml.kernel.org/r/Z_W9Oeg-D9FhImf3@aschofie-mobl2.lan
Tested-by: Alison Schofield <alison.schofield@intel.com>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Tested-by: "Darrick J. Wong" <djwong@kernel.org>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Jan Kara <jack@suse.cz>
Cc: Matthew Wilcox <willy@infradead.org>
Cc: Alistair Popple <apopple@nvidia.com>
Cc: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
History 2025-04-17 20:10:06 -07:00
..
9p 9p update for 6.15-rc1 2025-04-03 15:35:46 -07:00
adfs Merge patch series "adfs, affs, befs, hfs, hfsplus: convert to new mount api" 2024-10-08 14:41:53 +02:00
affs vfs-6.15-rc1.async.dir 2025-03-24 10:47:14 -07:00
afs afs: Fix afs_dynroot_readdir() to not use the RCU read lock 2025-04-11 15:24:29 +02:00
autofs vfs-6.15-rc1.async.dir 2025-03-24 10:47:14 -07:00
bcachefs bcachefs fixes for 6.15-rc3 2025-04-17 15:08:29 -07:00
befs befs: convert befs to use the new mount api 2024-09-18 11:44:43 +02:00
bfs fs: Convert aops->write_begin to take a folio 2024-08-07 11:33:21 +02:00
btrfs for-6.15-rc2-tag 2025-04-17 09:17:57 -07:00
cachefiles cachefiles: Fix oops in vfs_mkdir from cachefiles_get_directory 2025-03-25 14:59:14 +01:00
ceph lib/crc: remove CONFIG_LIBCRC32C 2025-04-04 11:31:42 -07:00
coda Change inode_operations.mkdir to return struct dentry * 2025-02-27 20:00:17 +01:00
configfs Change inode_operations.mkdir to return struct dentry * 2025-02-27 20:00:17 +01:00
cramfs vfs-6.11.module.description 2024-07-15 11:14:59 -07:00
crypto for-6.15/block-20250322 2025-03-26 18:08:55 -07:00
debugfs debugfs: Fix the missing initializations in __debugfs_file_get() 2025-01-30 08:22:31 +01:00
devpts devpts: Fix type for uid and gid params 2025-04-07 15:22:12 +02:00
dlm dlm: make tcp still work in multi-link env 2025-03-18 10:49:22 -05:00
ecryptfs vfs-6.15-rc1.async.dir 2025-03-24 10:47:14 -07:00
efivarfs EFI updates for v6.15 2025-03-29 11:36:19 -07:00
efs efs: fix the efs new mount api implementation 2024-10-15 15:58:36 +02:00
erofs Changes since last update: 2025-04-13 10:52:04 -07:00
exfat exfat: call bh_read in get_block only when necessary 2025-03-29 22:03:11 +09:00
exportfs exportfs: add module description 2025-03-25 15:57:58 +01:00
ext2 \n 2025-03-31 17:53:44 -07:00
ext4 A few more miscellaneous ext4 bug fixes and cleanups including some 2025-04-13 07:15:50 -07:00
f2fs f2fs-for-6.15-rc1 2025-03-27 12:55:54 -07:00
fat Change inode_operations.mkdir to return struct dentry * 2025-02-27 20:00:17 +01:00
freevxfs freevxfs: Replace one-element array with flexible array member 2024-11-06 10:42:06 +01:00
fuse virtiofs: add filesystem context source name check 2025-04-07 15:22:25 +02:00
gfs2 lib/crc: remove CONFIG_LIBCRC32C 2025-04-04 11:31:42 -07:00
hfs hfs/hfsplus: fix slab-out-of-bounds in hfs_bnode_read_key 2025-04-07 19:21:51 +02:00
hfsplus hfs/hfsplus: fix slab-out-of-bounds in hfs_bnode_read_key 2025-04-07 19:21:51 +02:00
hostfs Updates for UML for this cycle, notably: 2025-04-02 12:25:03 -07:00
hpfs Change inode_operations.mkdir to return struct dentry * 2025-02-27 20:00:17 +01:00
hugetlbfs - The 6 patch series "Enable strict percpu address space checks" from 2025-04-01 09:29:18 -07:00
iomap iomap: skip unnecessary ifs_block_is_uptodate check 2025-04-11 16:02:27 +02:00
isofs isofs: Prevent the use of too small fid 2025-04-04 12:28:32 +02:00
jbd2 treewide: Switch/rename to timer_delete[_sync]() 2025-04-05 10:30:12 +02:00
jffs2 treewide: Switch/rename to timer_delete[_sync]() 2025-04-05 10:30:12 +02:00
jfs Various bug fixes and cleanups for JFS 2025-03-27 13:17:39 -07:00
kernfs Driver core updates for 6.15-rc1 2025-04-01 11:02:03 -07:00
lockd sysctl: Fixes nsm_local_state bounds 2025-03-10 09:11:13 -04:00
minix Change inode_operations.mkdir to return struct dentry * 2025-02-27 20:00:17 +01:00
netfs netfs: Only create /proc/fs/netfs with CONFIG_PROC_FS 2025-04-11 15:58:18 +02:00
nfs NFS client updates for Linux 6.15 2025-04-02 17:06:31 -07:00
nfs_common fs: nfs: acl: Avoid -Wflex-array-member-not-at-end warning 2025-03-10 09:11:04 -04:00
nfsd NFSD 6.15 Release Notes 2025-03-31 17:28:17 -07:00
nilfs2 treewide: Switch/rename to timer_delete[_sync]() 2025-04-05 10:30:12 +02:00
nls move asm/unaligned.h to linux/unaligned.h 2024-10-02 17:23:23 -04:00
notify vfs-6.15-rc1.mount 2025-03-24 09:34:10 -07:00
ntfs3 Changes for 6.15-rc1 2025-04-02 16:30:02 -07:00
ocfs2 treewide: Switch/rename to timer_delete[_sync]() 2025-04-05 10:30:12 +02:00
omfs Change inode_operations.mkdir to return struct dentry * 2025-02-27 20:00:17 +01:00
openpromfs openpromfs: add missing MODULE_DESCRIPTION() macro 2024-06-20 09:46:01 +02:00
orangefs orangefs: one fixup 2025-03-27 13:14:39 -07:00
overlayfs ovl: remove unused forward declaration 2025-04-07 11:22:49 +02:00
proc - The 7 patch series "powerpc/crash: use generic crashkernel 2025-04-01 10:06:52 -07:00
pstore treewide: Switch/rename to timer_delete[_sync]() 2025-04-05 10:30:12 +02:00
qnx4 qnx4: add MODULE_DESCRIPTION() 2024-05-28 11:52:53 +02:00
qnx6 fs/qnx6: Fix building with GCC 15 2024-12-03 10:40:36 +01:00
quota treewide: const qualify ctl_tables where applicable 2025-01-28 13:48:37 +01:00
ramfs Change inode_operations.mkdir to return struct dentry * 2025-02-27 20:00:17 +01:00
romfs romfs: fix romfs_read_folio() 2024-08-21 22:32:58 +02:00
smb smb3: Add defines for two new FileSystemAttributes 2025-04-09 23:42:16 -05:00
squashfs squashfs: fix invalid pointer dereference in squashfs_cache_delete 2025-03-16 17:40:24 -07:00
sysfs kernfs: Use RCU to access kernfs_node::name. 2025-02-15 17:46:32 +01:00
tests execve: Move KUnit tests to tests/ subdirectory 2024-07-22 18:25:47 -07:00
tracefs Change inode_operations.mkdir to return struct dentry * 2025-02-27 20:00:17 +01:00
ubifs This update includes the following changes: 2025-03-29 10:01:55 -07:00
udf - The 6 patch series "Enable strict percpu address space checks" from 2025-04-01 09:29:18 -07:00
ufs Change inode_operations.mkdir to return struct dentry * 2025-02-27 20:00:17 +01:00
unicode unicode: kunit: change tests filename and path 2025-02-12 14:00:11 -08:00
vboxsf vfs-6.15-rc1.async.dir 2025-03-24 10:47:14 -07:00
verity Revert "fsverity: relax build time dependency on CRYPTO_SHA256" 2025-02-17 11:34:15 -08:00
xfs xfs: fix fsmap for internal zoned devices 2025-04-16 12:56:10 +02:00
zonefs iomap: pass private data to iomap_page_mkwrite 2025-02-06 13:02:15 +01:00
aio.c treewide: const qualify ctl_tables where applicable 2025-01-28 13:48:37 +01:00
anon_inodes.c add a string-to-qstr constructor 2025-01-27 19:25:45 -05:00
attr.c fs: handle delegated timestamps in setattr_copy_mgtime 2024-10-10 10:20:51 +02:00
backing-file.c tree-wide: s/revert_creds_light()/revert_creds()/g 2024-12-02 11:25:09 +01:00
bad_inode.c Change inode_operations.mkdir to return struct dentry * 2025-02-27 20:00:17 +01:00
binfmt_elf.c binfmt_elf: Use note name macros 2025-02-10 16:47:07 -08:00
binfmt_elf_fdpic.c binfmt_elf_fdpic: fix variable set but not used warning 2025-03-07 20:07:33 -08:00
binfmt_flat.c binfmt_flat: Fix integer overflow bug on 32 bit systems 2025-01-10 08:49:05 -08:00
binfmt_misc.c execve updates for v6.14-rc1 2025-01-20 13:27:58 -08:00
binfmt_script.c fs: binfmt: add missing MODULE_DESCRIPTION() macros 2024-05-28 12:06:51 +02:00
bpf_fs_kfuncs.c bpf: fs/xattr: Add BPF kfuncs to set and remove xattrs 2025-02-13 19:35:32 -08:00
buffer.c - The 6 patch series "Enable strict percpu address space checks" from 2025-04-01 09:29:18 -07:00
char_dev.c fs: Reorganize kerneldoc parameter names 2024-10-22 11:16:57 +02:00
compat_binfmt_elf.c binfmt_elf: Wire up AT_HWCAP3 at AT_HWCAP4 2024-10-17 18:38:49 +01:00
coredump.c Summary 2025-03-26 21:02:05 -07:00
d_path.c fs: d_path: include internal.h 2023-05-17 09:16:59 +02:00
dax.c fs/dax: fix folio splitting issue by resetting old folio order + _nr_pages 2025-04-17 20:10:06 -07:00
dcache.c Summary 2025-03-26 21:02:05 -07:00
direct-io.c fs/direct-io: Remove linux/prefetch.h include 2024-08-19 13:45:02 +02:00
drop_caches.c fs: drop_caches: move sysctl to fs/drop_caches.c 2025-02-07 16:53:04 +01:00
eventfd.c make use of anon_inode_getfile_fmode() 2025-02-21 10:25:31 +01:00
eventpoll.c Networking changes for 6.15. 2025-03-26 21:48:21 -07:00
exec.c rseq: Eliminate useless task_work on execve 2025-04-03 13:10:47 +02:00
fcntl.c fs: get rid of __FMODE_NONOTIFY kludge 2024-12-09 11:34:29 +01:00
fhandle.c exportfs: add permission method 2024-12-17 09:16:11 +01:00
file.c vfs-6.15-rc1.file 2025-03-24 13:19:17 -07:00
file_table.c vfs-6.15-rc1.file 2025-03-24 13:19:17 -07:00
filesystems.c fs: simplify get_filesystem_list / get_all_fs_names 2021-08-23 01:25:40 -04:00
fs-writeback.c fs: fs-writeback: move sysctl to fs/fs-writeback.c 2025-02-07 16:53:04 +01:00
fs_context.c fs: fc_log replace magic number 7 with ARRAY_SIZE() 2024-12-22 11:29:52 +01:00
fs_parser.c bcachefs: add support for true/false & yes/no in bool-type options 2024-12-21 01:36:17 -05:00
fs_pin.c switch the remnants of releasing the mountpoint away from fs_pin 2019-07-16 22:52:37 -04:00
fs_struct.c kill do_each_thread() 2023-08-21 13:46:25 -07:00
fs_types.c fs: common implementation of file type 2019-01-21 17:48:13 +01:00
fsopen.c fs: support O_PATH fds with FSCONFIG_SET_FD 2025-02-12 10:02:10 +01:00
init.c VFS: Change vfs_mkdir() to return the dentry. 2025-03-05 11:52:50 +01:00
inode.c fs: call inode_sb_list_add() outside of inode hash lock 2025-03-20 13:06:51 +01:00
internal.h vfs-6.15-rc1.file 2025-03-24 13:19:17 -07:00
ioctl.c ioctl: Fix return type of several functions from long to int 2025-02-21 10:25:32 +01:00
Kconfig - The 6 patch series "Enable strict percpu address space checks" from 2025-04-01 09:29:18 -07:00
Kconfig.binfmt exec: Add KUnit test for bprm_stack_limits() 2024-06-19 13:13:55 -07:00
kernel_read_file.c fdget(), trivial conversions 2024-11-03 01:28:06 -05:00
libfs.c vfs-6.15-rc1.pidfs 2025-03-24 10:16:37 -07:00
locks.c treewide: const qualify ctl_tables where applicable 2025-01-28 13:48:37 +01:00
Makefile sysv: Remove the filesystem 2025-02-21 10:32:47 +01:00
mbcache.c vfs: remove SLAB_MEM_SPREAD flag usage 2024-02-27 11:21:31 +01:00
mnt_idmapping.c statmount: allow to retrieve idmappings 2025-02-12 12:12:27 +01:00
mount.h vfs-6.15-rc1.mount.namespace 2025-03-24 11:41:41 -07:00
mpage.c fs/buffer fs/mpage: remove large folio restriction 2025-02-24 11:44:44 +01:00
namei.c fs: Fix filename init after recent refactoring 2025-04-11 16:00:35 +02:00
namespace.c fs: use namespace_{lock,unlock} in dissolve_on_fput() 2025-04-11 16:07:50 +02:00
nsfs.c vfs-6.15-rc1.nsfs 2025-03-24 11:38:12 -07:00
open.c vfs-6.15-rc1.file 2025-03-24 13:19:17 -07:00
pidfs.c vfs-6.15-rc1.pidfs 2025-03-24 10:16:37 -07:00
pipe.c Merge patch series "pipe: Trivial cleanups" 2025-03-10 08:55:13 +01:00
pnode.c vfs-6.15-rc1.mount.namespace 2025-03-24 11:41:41 -07:00
pnode.h mount: handle mount propagation for detached mount trees 2025-03-04 09:29:54 +01:00
posix_acl.c acl: Annotate struct posix_acl with __counted_by() 2024-10-22 11:16:59 +02:00
proc_namespace.c fs: rename show_mnt_opts -> show_vfsmnt_opts 2024-06-28 14:36:43 +02:00
read_write.c fs: don't needlessly acquire f_lock 2025-02-21 10:25:32 +01:00
readdir.c introduce "fd_pos" class, convert fdget_pos() users to it. 2024-11-03 01:28:06 -05:00
remap_range.c convert vfs_dedupe_file_range(). 2024-11-03 01:28:07 -05:00
select.c select: Fix unbalanced user_access_end() 2025-01-13 16:24:16 +01:00
seq_file.c fs: Reorganize kerneldoc parameter names 2024-10-22 11:16:57 +02:00
signalfd.c make use of anon_inode_getfile_fmode() 2025-02-21 10:25:31 +01:00
splice.c fs/splice: Use pipe_buf() helper to retrieve pipe buffer 2025-03-10 08:55:05 +01:00
stack.c fs: convert core infrastructure to new timestamp accessors 2023-10-18 13:26:15 +02:00
stat.c fs/stat.c: avoid harmless garbage value problem in vfs_statx_path() 2025-02-07 10:27:24 +01:00
statfs.c fdget_raw() users: switch to CLASS(fd_raw) 2024-11-03 01:28:06 -05:00
super.c vfs-6.15-rc1.misc 2025-03-24 09:13:50 -07:00
sync.c fdget(), trivial conversions 2024-11-03 01:28:06 -05:00
sysctls.c treewide: const qualify ctl_tables where applicable 2025-01-28 13:48:37 +01:00
timerfd.c A treewide hrtimer timer cleanup 2025-03-25 10:54:15 -07:00
userfaultfd.c mm/userfaultfd: fix release hang over concurrent GUP 2025-04-01 15:14:42 -07:00
utimes.c fdget(), more trivial conversions 2024-11-03 01:28:06 -05:00
xattr.c xattr: remove redundant check on variable err 2024-11-06 13:00:01 -05:00