Skip to content

Commit

Permalink
mm, THP, swap: fix allocating cluster for swapfile by mistake
Browse files Browse the repository at this point in the history
BugLink: https://bugs.launchpad.net/bugs/1898076

commit 4166343 upstream.

SWP_FS is used to make swap_{read,write}page() go through the
filesystem, and it's only used for swap files over NFS.  So, !SWP_FS
means non NFS for now, it could be either file backed or device backed.
Something similar goes with legacy SWP_FILE.

So in order to achieve the goal of the original patch, SWP_BLKDEV should
be used instead.

FS corruption can be observed with SSD device + XFS + fragmented
swapfile due to CONFIG_THP_SWAP=y.

I reproduced the issue with the following details:

Environment:

  QEMU + upstream kernel + buildroot + NVMe (2 GB)

Kernel config:

  CONFIG_BLK_DEV_NVME=y
  CONFIG_THP_SWAP=y

Some reproducible steps:

  mkfs.xfs -f /dev/nvme0n1
  mkdir /tmp/mnt
  mount /dev/nvme0n1 /tmp/mnt
  bs="32k"
  sz="1024m"    # doesn't matter too much, I also tried 16m
  xfs_io -f -c "pwrite -R -b $bs 0 $sz" -c "fdatasync" /tmp/mnt/sw
  xfs_io -f -c "pwrite -R -b $bs 0 $sz" -c "fdatasync" /tmp/mnt/sw
  xfs_io -f -c "pwrite -R -b $bs 0 $sz" -c "fdatasync" /tmp/mnt/sw
  xfs_io -f -c "pwrite -F -S 0 -b $bs 0 $sz" -c "fdatasync" /tmp/mnt/sw
  xfs_io -f -c "pwrite -R -b $bs 0 $sz" -c "fsync" /tmp/mnt/sw

  mkswap /tmp/mnt/sw
  swapon /tmp/mnt/sw

  stress --vm 2 --vm-bytes 600M   # doesn't matter too much as well

Symptoms:
 - FS corruption (e.g. checksum failure)
 - memory corruption at: 0xd2808010
 - segfault

Fixes: f0eea18 ("mm, THP, swap: Don't allocate huge cluster for file backed swap device")
Fixes: 38d8b4e ("mm, THP, swap: delay splitting THP during swap out")
Signed-off-by: Gao Xiang <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Reviewed-by: "Huang, Ying" <[email protected]>
Reviewed-by: Yang Shi <[email protected]>
Acked-by: Rafael Aquini <[email protected]>
Cc: Matthew Wilcox <[email protected]>
Cc: Carlos Maiolino <[email protected]>
Cc: Eric Sandeen <[email protected]>
Cc: Dave Chinner <[email protected]>
Cc: <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

Signed-off-by: Paolo Pisati <[email protected]>
  • Loading branch information
Gao Xiang authored and piso77 committed Oct 1, 2020
1 parent 01a48a9 commit 01aa27d
Showing 1 changed file with 1 addition and 1 deletion.
2 changes: 1 addition & 1 deletion mm/swapfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -1074,7 +1074,7 @@ int get_swap_pages(int n_goal, swp_entry_t swp_entries[], int entry_size)
goto nextsi;
}
if (size == SWAPFILE_CLUSTER) {
if (!(si->flags & SWP_FS))
if (si->flags & SWP_BLKDEV)
n_ret = swap_alloc_cluster(si, swp_entries);
} else
n_ret = scan_swap_map_slots(si, SWAP_HAS_CACHE,
Expand Down

0 comments on commit 01aa27d

Please sign in to comment.