mm/filemap: make buffered writes work with RWF_UNCACHED
authorJens Axboe <axboe@kernel.dk>
Tue, 5 Nov 2024 21:35:11 +0000 (14:35 -0700)
committerJens Axboe <axboe@kernel.dk>
Fri, 8 Nov 2024 03:51:49 +0000 (20:51 -0700)
commit71a7f791aa6f62edc0543914ba355b0a89d8f31f
tree3bb6231abb547c2693192ff145b02ee84bfdd979
parentd17a6ec6bfac4bdd38c8cef280eb31b8ede1a63f
mm/filemap: make buffered writes work with RWF_UNCACHED

If RWF_UNCACHED is set for a write, mark the folios being written with
drop_writeback. Then writeback completion will drop the pages. The
write_iter handler simply kicks off writeback for the pages, and
writeback completion will take care of the rest.

This provides similar benefits to using RWF_UNCACHED with reads. Testing
buffered writes on 32 files:

writing bs 65536, uncached 0
  1s: 216584MB/sec
  2s: 167372MB/sec
  3s: 165623MB/sec
  4s: 149808MB/sec
  5s: 104746MB/sec
  6s: 81277MB/sec
  7s: 79542MB/sec
  8s: 81041MB/sec
  9s: 77647MB/sec
 10s: 84352MB/sec
 11s: 80093MB/sec
 12s: 75488MB/sec
 13s: 80426MB/sec
 14s: 79989MB/sec
 15s: 80993MB/sec
 16s: 83123MB/sec
 17s: 78843MB/sec

where it's quite obvious where the page cache filled, and performance
dropped from to about half of where it started, settling in at around
80GB/sec. Meanwhile, 32 kswapds were running full steam trying to reclaim
pages.

Running the same test with uncached buffered writes:

writing bs 65536, uncached 1
  1s: 143400MB/sec
  2s: 144408MB/sec
  3s: 151327MB/sec
  4s: 157575MB/sec
  5s: 146573MB/sec
  6s: 139140MB/sec
  7s: 140509MB/sec
  8s: 141288MB/sec
  9s: 138323MB/sec
 10s: 137140MB/sec
 11s: 135954MB/sec
 12s: 136382MB/sec
 13s: 138430MB/sec
 14s: 139814MB/sec
 15s: 138521MB/sec
 16s: 138660MB/sec
 17s: 138960MB/sec

and the behavior is fully predictable, performing the same throughout
even after the page cache would otherwise have fully filled with dirty
data. It's also about 75% faster, and using half the CPU of the system
compared to the normal buffered write.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
mm/filemap.c