Skip to content

Commit 2168dbb

Browse files
Matthew Wilcox (Oracle)opsiff
authored andcommitted
mm: add folio_xor_flags_has_waiters()
mainline inclusion from mainline-v6.7-rc1 category: performance Optimise folio_end_read() by setting the uptodate bit at the same time we clear the unlock bit. This saves at least one memory barrier and one write-after-write hazard. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Matthew Wilcox (Oracle) <[email protected]> Cc: Albert Ou <[email protected]> Cc: Alexander Gordeev <[email protected]> Cc: Andreas Dilger <[email protected]> Cc: Christian Borntraeger <[email protected]> Cc: Christophe Leroy <[email protected]> Cc: Geert Uytterhoeven <[email protected]> Cc: Heiko Carstens <[email protected]> Cc: Ivan Kokshaysky <[email protected]> Cc: Matt Turner <[email protected]> Cc: Michael Ellerman <[email protected]> Cc: Nicholas Piggin <[email protected]> Cc: Palmer Dabbelt <[email protected]> Cc: Paul Walmsley <[email protected]> Cc: Richard Henderson <[email protected]> Cc: Sven Schnelle <[email protected]> Cc: "Theodore Ts'o" <[email protected]> Cc: Thomas Bogendoerfer <[email protected]> Cc: Vasily Gorbik <[email protected]> Signed-off-by: Andrew Morton <[email protected]> (cherry picked from commit 0410cd8) Signed-off-by: Wentao Guan <[email protected]>
1 parent 04ca35e commit 2168dbb

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

include/linux/page-flags.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,25 @@ TESTPAGEFLAG_FALSE(Ksm, ksm)
712712

713713
u64 stable_page_flags(struct page *page);
714714

715+
/**
716+
* folio_xor_flags_has_waiters - Change some folio flags.
717+
* @folio: The folio.
718+
* @mask: Bits set in this word will be changed.
719+
*
720+
* This must only be used for flags which are changed with the folio
721+
* lock held. For example, it is unsafe to use for PG_dirty as that
722+
* can be set without the folio lock held. It can also only be used
723+
* on flags which are in the range 0-6 as some of the implementations
724+
* only affect those bits.
725+
*
726+
* Return: Whether there are tasks waiting on the folio.
727+
*/
728+
static inline bool folio_xor_flags_has_waiters(struct folio *folio,
729+
unsigned long mask)
730+
{
731+
return xor_unlock_is_negative_byte(mask, folio_flags(folio, 0));
732+
}
733+
715734
/**
716735
* folio_test_uptodate - Is this folio up to date?
717736
* @folio: The folio.

mm/filemap.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,7 +1527,7 @@ void folio_unlock(struct folio *folio)
15271527
BUILD_BUG_ON(PG_waiters != 7);
15281528
BUILD_BUG_ON(PG_locked > 7);
15291529
VM_BUG_ON_FOLIO(!folio_test_locked(folio), folio);
1530-
if (xor_unlock_is_negative_byte(1 << PG_locked, folio_flags(folio, 0)))
1530+
if (folio_xor_flags_has_waiters(folio, 1 << PG_locked))
15311531
folio_wake_bit(folio, PG_locked);
15321532
}
15331533
EXPORT_SYMBOL(folio_unlock);
@@ -1548,9 +1548,17 @@ EXPORT_SYMBOL(folio_unlock);
15481548
*/
15491549
void folio_end_read(struct folio *folio, bool success)
15501550
{
1551+
unsigned long mask = 1 << PG_locked;
1552+
1553+
/* Must be in bottom byte for x86 to work */
1554+
BUILD_BUG_ON(PG_uptodate > 7);
1555+
VM_BUG_ON_FOLIO(!folio_test_locked(folio), folio);
1556+
VM_BUG_ON_FOLIO(folio_test_uptodate(folio), folio);
1557+
15511558
if (likely(success))
1552-
folio_mark_uptodate(folio);
1553-
folio_unlock(folio);
1559+
mask |= 1 << PG_uptodate;
1560+
if (folio_xor_flags_has_waiters(folio, mask))
1561+
folio_wake_bit(folio, PG_locked);
15541562
}
15551563
EXPORT_SYMBOL(folio_end_read);
15561564

0 commit comments

Comments
 (0)