Skip to content

Commit 1d8d227

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 5361dfc commit 1d8d227

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
@@ -726,6 +726,25 @@ TESTPAGEFLAG_FALSE(Ksm, ksm)
726726

727727
u64 stable_page_flags(struct page *page);
728728

729+
/**
730+
* folio_xor_flags_has_waiters - Change some folio flags.
731+
* @folio: The folio.
732+
* @mask: Bits set in this word will be changed.
733+
*
734+
* This must only be used for flags which are changed with the folio
735+
* lock held. For example, it is unsafe to use for PG_dirty as that
736+
* can be set without the folio lock held. It can also only be used
737+
* on flags which are in the range 0-6 as some of the implementations
738+
* only affect those bits.
739+
*
740+
* Return: Whether there are tasks waiting on the folio.
741+
*/
742+
static inline bool folio_xor_flags_has_waiters(struct folio *folio,
743+
unsigned long mask)
744+
{
745+
return xor_unlock_is_negative_byte(mask, folio_flags(folio, 0));
746+
}
747+
729748
/**
730749
* folio_test_uptodate - Is this folio up to date?
731750
* @folio: The folio.

mm/filemap.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1508,7 +1508,7 @@ void folio_unlock(struct folio *folio)
15081508
BUILD_BUG_ON(PG_waiters != 7);
15091509
BUILD_BUG_ON(PG_locked > 7);
15101510
VM_BUG_ON_FOLIO(!folio_test_locked(folio), folio);
1511-
if (xor_unlock_is_negative_byte(1 << PG_locked, folio_flags(folio, 0)))
1511+
if (folio_xor_flags_has_waiters(folio, 1 << PG_locked))
15121512
folio_wake_bit(folio, PG_locked);
15131513
}
15141514
EXPORT_SYMBOL(folio_unlock);
@@ -1529,9 +1529,17 @@ EXPORT_SYMBOL(folio_unlock);
15291529
*/
15301530
void folio_end_read(struct folio *folio, bool success)
15311531
{
1532+
unsigned long mask = 1 << PG_locked;
1533+
1534+
/* Must be in bottom byte for x86 to work */
1535+
BUILD_BUG_ON(PG_uptodate > 7);
1536+
VM_BUG_ON_FOLIO(!folio_test_locked(folio), folio);
1537+
VM_BUG_ON_FOLIO(folio_test_uptodate(folio), folio);
1538+
15321539
if (likely(success))
1533-
folio_mark_uptodate(folio);
1534-
folio_unlock(folio);
1540+
mask |= 1 << PG_uptodate;
1541+
if (folio_xor_flags_has_waiters(folio, mask))
1542+
folio_wake_bit(folio, PG_locked);
15351543
}
15361544
EXPORT_SYMBOL(folio_end_read);
15371545

0 commit comments

Comments
 (0)