Skip to content

mm/filemap: optimize folio adding and splitting

Kairui Song linux-mm lkml 4 versions – New

Get series with b4
b4 am [email protected]

Versions newest first · linked by author and title

  1. v4 Latest4 patches 0 repliesNew 1 of 4 applied
  2. v34 patches 2 repliesSuperseded 3 of 4 applied
  3. v24 patches 0 repliesSuperseded
Earlier versions · 1
VersionPostedPatchesRepliesStatus
v14 patches6 repliesSuperseded

Patches in v4 1 of 4 applied

#Subject and filesSizeRepliesApplied
1/4mm/filemap: return early if failed to allocate memory for splitmm/filemap.c+4 -10 replies
2/4mm/filemap: clean up hugetlb exclusion codemm/filemap.c+8 -130 replies
3/4lib/xarray: introduce a new helper xas_get_orderinclude/linux/xarray.h lib/test_xarray.c lib/xarray.c+71 -180 repliesApplied
4/4mm/filemap: optimize filemap folio addinglib/test_xarray.c mm/filemap.c+100 -150 replies

Reviews trailers per patch

2 of 4 patches have a Reviewed-by or Acked-by.

PatchMatthew Wilcox (Oracle)
1/4A-b
2/4A-b
3/4
4/4

Trailers given in replies are filled; those carried in the patches from earlier versions are outlined with dashes.

Read the v4 thread

Cover letter [PATCH v4 0/4] mm/filemap: optimize folio adding and splitting

From: Kairui Song <[email protected]>

Currently, at least 3 tree walks are needed for filemap folio adding if the folio is previously evicted. One for getting the order of current slot, one for ranged conflict check, and one for another order retrieving. If a split is needed, more walks are needed.

This series is trying to merge these walks, and speed up filemap_add_folio, I see a 7.5% - 12.5% performance gain for fio stress test.

So instead of doing multiple tree walks, do one optimism range check with lock hold, and exit if raced with another insertion. If a shadow exists, check it with a new xas_get_order helper before releasing the lock to avoid redundant tree walks for getting its order.

Drop the lock and do the allocation only if a split is needed.

In the best case, it only need to walk the tree once. If it needs to alloc and split, 3 walks are issued (One for first ranged conflict check and order retrieving, one for the second check after allocation, one for the insert after split).

Testing with 4K pages, in an 8G cgroup, with 16G brd as block device:

echo 3 > /proc/sys/vm/drop_caches

  fio -name=cached --numjobs=16 --filename=/mnt/test.img \
    --buffered=1 --ioengine=mmap --rw=randread --time_based \
    --ramp_time=30s --runtime=5m --group_reporting

Before:
bw ( MiB/s): min= 1027, max= 3520, per=100.00%, avg=2445.02, stdev=18.90, samples=8691
iops : min=263001, max=901288, avg=625924.36, stdev=4837.28, samples=8691

After (+7.3%):
bw ( MiB/s): min= 493, max= 3947, per=100.00%, avg=2625.56, stdev=25.74, samples=8651
iops : min=126454, max=1010681, avg=672142.61, stdev=6590.48, samples=8651

Test result with THP (do a THP randread then switch to 4K page in hope it issues a lot of splitting):

echo 3 > /proc/sys/vm/drop_caches

  fio -name=cached --numjobs=16 --filename=/mnt/test.img \
      --buffered=1 --ioengine=mmap -thp=1 --readonly \
      --rw=randread --time_based --ramp_time=30s --runtime=10m \
      --group_reporting

  fio -name=cached --numjobs=16 --filename=/mnt/test.img \
      --buffered=1 --ioengine=mmap \
      --rw=randread --time_based --runtime=5s --group_reporting

Before:
bw ( KiB/s): min= 4141, max=14202, per=100.00%, avg=7935.51, stdev=96.85, samples=18976
iops : min= 1029, max= 3548, avg=1979.52, stdev=24.23, samples=18976·

READ: bw=4545B/s (4545B/s), 4545B/s-4545B/s (4545B/s-4545B/s), io=64.0KiB (65.5kB), run=14419-14419msec

After (+10.4%):
bw ( KiB/s): min= 4611, max=15370, per=100.00%, avg=8928.74, stdev=105.17, samples=19146
iops : min= 1151, max= 3842, avg=2231.27, stdev=26.29, samples=19146

READ: bw=4635B/s (4635B/s), 4635B/s-4635B/s (4635B/s-4635B/s), io=64.0KiB (65.5kB), run=14137-14137msec

The performance is better for both 4K (+7.5%) and THP (+12.5%) cached read.

V3: https://lore.kernel.org/linux-mm/[email protected]/
Updates from V3:
- Simplify comment, and fold in a sparse warning fix, as suggested by Matthew Wilcox.

V2: https://lore.kernel.org/lkml/[email protected]/
Updates from V2:
- Fix the misusage of locks in test module:
https://lore.kernel.org/oe-lkp/[email protected]

V1: https://lore.kernel.org/lkml/[email protected]/
Updates from V1:
- Collect Acks.
- Add tests for new xas_get_order and combined usage of xas_get_order with xas_for_each_conflict.
- Fix a memleak for patch 4/4 and modify the function in place instead of adding a new helper.
- Update benchmark, I forgot to drop cache and disable THP for pervious test, so the result was for mixed usaged of split and add. The result is even better now.

Kairui Song (4):
mm/filemap: return early if failed to allocate memory for split mm/filemap: clean up hugetlb exclusion code lib/xarray: introduce a new helper xas_get_order mm/filemap: optimize filemap folio adding

 include/linux/xarray.h |  6 +++
 lib/test_xarray.c      | 93 ++++++++++++++++++++++++++++++++++++++++++
 lib/xarray.c           | 49 ++++++++++++++--------
 mm/filemap.c           | 74 +++++++++++++++++++++------------
 4 files changed, 179 insertions(+), 43 deletions(-)
Signature · 1 line
2.44.0