Skip to content

Commit fb7d3bc

Browse files
axboeakpm00
authored andcommitted
mm/filemap: drop streaming/uncached pages when writeback completes
If the folio is marked as streaming, drop pages when writeback completes. Intended to be used with RWF_DONTCACHE, to avoid needing sync writes for uncached IO. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]> Cc: Brian Foster <[email protected]> Cc: Chris Mason <[email protected]> Cc: Christoph Hellwig <[email protected]> Cc: Johannes Weiner <[email protected]> Cc: Kirill A. Shutemov <[email protected]> Cc: Matthew Wilcox (Oracle) <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 8026e49 commit fb7d3bc

File tree

1 file changed

+28
-0
lines changed

1 file changed

+28
-0
lines changed

mm/filemap.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1571,6 +1571,27 @@ int folio_wait_private_2_killable(struct folio *folio)
15711571
}
15721572
EXPORT_SYMBOL(folio_wait_private_2_killable);
15731573

1574+
/*
1575+
* If folio was marked as dropbehind, then pages should be dropped when writeback
1576+
* completes. Do that now. If we fail, it's likely because of a big folio -
1577+
* just reset dropbehind for that case and latter completions should invalidate.
1578+
*/
1579+
static void folio_end_dropbehind_write(struct folio *folio)
1580+
{
1581+
/*
1582+
* Hitting !in_task() should not happen off RWF_DONTCACHE writeback,
1583+
* but can happen if normal writeback just happens to find dirty folios
1584+
* that were created as part of uncached writeback, and that writeback
1585+
* would otherwise not need non-IRQ handling. Just skip the
1586+
* invalidation in that case.
1587+
*/
1588+
if (in_task() && folio_trylock(folio)) {
1589+
if (folio->mapping)
1590+
folio_unmap_invalidate(folio->mapping, folio, 0);
1591+
folio_unlock(folio);
1592+
}
1593+
}
1594+
15741595
/**
15751596
* folio_end_writeback - End writeback against a folio.
15761597
* @folio: The folio.
@@ -1581,6 +1602,8 @@ EXPORT_SYMBOL(folio_wait_private_2_killable);
15811602
*/
15821603
void folio_end_writeback(struct folio *folio)
15831604
{
1605+
bool folio_dropbehind = false;
1606+
15841607
VM_BUG_ON_FOLIO(!folio_test_writeback(folio), folio);
15851608

15861609
/*
@@ -1602,9 +1625,14 @@ void folio_end_writeback(struct folio *folio)
16021625
* reused before the folio_wake_bit().
16031626
*/
16041627
folio_get(folio);
1628+
if (!folio_test_dirty(folio))
1629+
folio_dropbehind = folio_test_clear_dropbehind(folio);
16051630
if (__folio_end_writeback(folio))
16061631
folio_wake_bit(folio, PG_writeback);
16071632
acct_reclaim_writeback(folio);
1633+
1634+
if (folio_dropbehind)
1635+
folio_end_dropbehind_write(folio);
16081636
folio_put(folio);
16091637
}
16101638
EXPORT_SYMBOL(folio_end_writeback);

0 commit comments

Comments
 (0)