From: Jens Axboe <axboe@kernel.dk>
To: linux-mm@kvack.org, linux-fsdevel@vger.kernel.org
Cc: hannes@cmpxchg.org, clm@meta.com, linux-kernel@vger.kernel.org,
Jens Axboe <axboe@kernel.dk>
Subject: [PATCH 10/13] mm/filemap: make buffered writes work with RWF_UNCACHED
Date: Fri, 8 Nov 2024 10:43:33 -0700 [thread overview]
Message-ID: <20241108174505.1214230-11-axboe@kernel.dk> (raw)
In-Reply-To: <20241108174505.1214230-1-axboe@kernel.dk>
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: 196035MB/sec, MB=196035
2s: 132308MB/sec, MB=328147
3s: 132438MB/sec, MB=460586
4s: 116528MB/sec, MB=577115
5s: 103898MB/sec, MB=681014
6s: 108893MB/sec, MB=789907
7s: 99678MB/sec, MB=889586
8s: 106545MB/sec, MB=996132
9s: 106826MB/sec, MB=1102958
10s: 101544MB/sec, MB=1204503
11s: 111044MB/sec, MB=1315548
12s: 124257MB/sec, MB=1441121
13s: 116031MB/sec, MB=1557153
14s: 114540MB/sec, MB=1671694
15s: 115011MB/sec, MB=1786705
16s: 115260MB/sec, MB=1901966
17s: 116068MB/sec, MB=2018034
18s: 116096MB/sec, MB=2134131
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
115GB/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: 198974MB/sec
2s: 189618MB/sec
3s: 193601MB/sec
4s: 188582MB/sec
5s: 193487MB/sec
6s: 188341MB/sec
7s: 194325MB/sec
8s: 188114MB/sec
9s: 192740MB/sec
10s: 189206MB/sec
11s: 193442MB/sec
12s: 189659MB/sec
13s: 191732MB/sec
14s: 190701MB/sec
15s: 191789MB/sec
16s: 191259MB/sec
17s: 190613MB/sec
18s: 191951MB/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 65% 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 | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/mm/filemap.c b/mm/filemap.c
index 1e455ca872b5..d4c5928c5e2a 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1610,6 +1610,8 @@ EXPORT_SYMBOL(folio_wait_private_2_killable);
*/
void folio_end_writeback(struct folio *folio)
{
+ bool folio_uncached;
+
VM_BUG_ON_FOLIO(!folio_test_writeback(folio), folio);
/*
@@ -1631,6 +1633,7 @@ void folio_end_writeback(struct folio *folio)
* reused before the folio_wake_bit().
*/
folio_get(folio);
+ folio_uncached = folio_test_clear_uncached(folio);
if (__folio_end_writeback(folio))
folio_wake_bit(folio, PG_writeback);
acct_reclaim_writeback(folio);
@@ -1639,12 +1642,10 @@ void folio_end_writeback(struct folio *folio)
* If folio is marked as uncached, then pages should be dropped when
* writeback completes. Do that now.
*/
- if (folio_test_uncached(folio)) {
- folio_lock(folio);
- if (invalidate_complete_folio2(folio->mapping, folio, 0))
- folio_clear_uncached(folio);
+ if (folio_uncached && folio_trylock(folio)) {
+ if (folio->mapping)
+ invalidate_complete_folio2(folio->mapping, folio, 0);
folio_unlock(folio);
-
}
folio_put(folio);
}
@@ -4082,6 +4083,9 @@ ssize_t generic_perform_write(struct kiocb *iocb, struct iov_iter *i)
if (unlikely(status < 0))
break;
+ if (iocb->ki_flags & IOCB_UNCACHED)
+ folio_set_uncached(folio);
+
offset = offset_in_folio(folio, pos);
if (bytes > folio_size(folio) - offset)
bytes = folio_size(folio) - offset;
@@ -4122,6 +4126,12 @@ ssize_t generic_perform_write(struct kiocb *iocb, struct iov_iter *i)
if (!written)
return status;
+ if (iocb->ki_flags & IOCB_UNCACHED) {
+ /* kick off uncached writeback, completion will drop it */
+ __filemap_fdatawrite_range(mapping, iocb->ki_pos,
+ iocb->ki_pos + written,
+ WB_SYNC_NONE);
+ }
iocb->ki_pos += written;
return written;
}
--
2.45.2
next prev parent reply other threads:[~2024-11-08 17:45 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-08 17:43 [PATCHSET v4] Uncached buffered IO Jens Axboe
2024-11-08 17:43 ` [PATCH 01/13] mm/filemap: change filemap_create_folio() to take a struct kiocb Jens Axboe
2024-11-08 18:18 ` Matthew Wilcox
2024-11-08 19:22 ` Jens Axboe
2024-11-08 17:43 ` [PATCH 02/13] mm/readahead: add folio allocation helper Jens Axboe
2024-11-08 17:43 ` [PATCH 03/13] mm: add PG_uncached page flag Jens Axboe
2024-11-08 19:25 ` Kirill A. Shutemov
2024-11-08 19:39 ` Jens Axboe
2024-11-08 17:43 ` [PATCH 04/13] mm/readahead: add readahead_control->uncached member Jens Axboe
2024-11-08 18:21 ` Matthew Wilcox
2024-11-08 19:22 ` Jens Axboe
2024-11-08 17:43 ` [PATCH 05/13] mm/filemap: use page_cache_sync_ra() to kick off read-ahead Jens Axboe
2024-11-08 17:43 ` [PATCH 06/13] mm/truncate: make invalidate_complete_folio2() public Jens Axboe
2024-11-08 17:43 ` [PATCH 07/13] fs: add FOP_UNCACHED flag Jens Axboe
2024-11-08 18:27 ` Matthew Wilcox
2024-11-08 19:23 ` Jens Axboe
2024-11-08 17:43 ` [PATCH 08/13] fs: add read support for RWF_UNCACHED Jens Axboe
2024-11-08 18:33 ` Matthew Wilcox
2024-11-08 19:25 ` Jens Axboe
2024-11-11 13:04 ` Stefan Metzmacher
2024-11-11 14:10 ` Jens Axboe
2024-11-11 15:44 ` Jens Axboe
2024-11-08 17:43 ` [PATCH 09/13] mm: drop uncached pages when writeback completes Jens Axboe
2024-11-08 17:43 ` Jens Axboe [this message]
2024-11-08 17:43 ` [PATCH 11/13] iomap: make buffered writes work with RWF_UNCACHED Jens Axboe
2024-11-08 18:46 ` Matthew Wilcox
2024-11-08 19:26 ` Jens Axboe
2024-11-08 19:49 ` Jens Axboe
2024-11-08 20:07 ` Matthew Wilcox
2024-11-08 20:18 ` Jens Axboe
2024-11-08 17:43 ` [PATCH 12/13] ext4: flag as supporting FOP_UNCACHED Jens Axboe
2024-11-08 17:43 ` [PATCH 13/13] xfs: " Jens Axboe
2024-11-11 12:55 ` [PATCHSET v4] Uncached buffered IO Stefan Metzmacher
2024-11-11 14:08 ` Jens Axboe
2024-11-11 15:05 ` Jens Axboe
2024-11-11 23:54 ` Jens Axboe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20241108174505.1214230-11-axboe@kernel.dk \
--to=axboe@kernel.dk \
--cc=clm@meta.com \
--cc=hannes@cmpxchg.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox