Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

iomap: hold state_lock over call to ifs_set_range_uptodate()

Patch series "Add folio_end_read", v2.

The core of this patchset is the new folio_end_read() call which
filesystems can use when finishing a page cache read instead of separate
calls to mark the folio uptodate and unlock it. As an illustration of its
use, I converted ext4, iomap & mpage; more can be converted.

I think that's useful by itself, but the interesting optimisation is that
we can implement that with a single XOR instruction that sets the uptodate
bit, clears the lock bit, tests the waiter bit and provides a write memory
barrier. That removes one memory barrier and one atomic instruction from
each page read, which seems worth doing. That's in patch 15.

The last two patches could be a separate series, but basically we can do
the same thing with the writeback flag that we do with the unlock flag;
clear it and test the waiters bit at the same time.


This patch (of 17):

This is really preparation for the next patch, but it lets us call
folio_mark_uptodate() in just one place instead of two.

Link: https://lkml.kernel.org/r/20231004165317.1061855-1-willy@infradead.org
Link: https://lkml.kernel.org/r/20231004165317.1061855-2-willy@infradead.org
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: "Theodore Ts'o" <tytso@mit.edu>
Cc: Andreas Dilger <adilger.kernel@dilger.ca>
Cc: Richard Henderson <richard.henderson@linaro.org>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: Matt Turner <mattst88@gmail.com>
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Paul Walmsley <paul.walmsley@sifive.com>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Albert Ou <aou@eecs.berkeley.edu>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
Cc: Christian Borntraeger <borntraeger@linux.ibm.com>
Cc: Sven Schnelle <svens@linux.ibm.com>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Matthew Wilcox (Oracle) and committed by
Andrew Morton
279d5fc3 116d5730

+11 -9
+11 -9
fs/iomap/buffered-io.c
··· 57 57 return test_bit(block, ifs->state); 58 58 } 59 59 60 - static void ifs_set_range_uptodate(struct folio *folio, 60 + static bool ifs_set_range_uptodate(struct folio *folio, 61 61 struct iomap_folio_state *ifs, size_t off, size_t len) 62 62 { 63 63 struct inode *inode = folio->mapping->host; 64 64 unsigned int first_blk = off >> inode->i_blkbits; 65 65 unsigned int last_blk = (off + len - 1) >> inode->i_blkbits; 66 66 unsigned int nr_blks = last_blk - first_blk + 1; 67 - unsigned long flags; 68 67 69 - spin_lock_irqsave(&ifs->state_lock, flags); 70 68 bitmap_set(ifs->state, first_blk, nr_blks); 71 - if (ifs_is_fully_uptodate(folio, ifs)) 72 - folio_mark_uptodate(folio); 73 - spin_unlock_irqrestore(&ifs->state_lock, flags); 69 + return ifs_is_fully_uptodate(folio, ifs); 74 70 } 75 71 76 72 static void iomap_set_range_uptodate(struct folio *folio, size_t off, 77 73 size_t len) 78 74 { 79 75 struct iomap_folio_state *ifs = folio->private; 76 + unsigned long flags; 77 + bool uptodate = true; 80 78 81 - if (ifs) 82 - ifs_set_range_uptodate(folio, ifs, off, len); 83 - else 79 + if (ifs) { 80 + spin_lock_irqsave(&ifs->state_lock, flags); 81 + uptodate = ifs_set_range_uptodate(folio, ifs, off, len); 82 + spin_unlock_irqrestore(&ifs->state_lock, flags); 83 + } 84 + 85 + if (uptodate) 84 86 folio_mark_uptodate(folio); 85 87 } 86 88