hulk inclusion category: perf bugzilla: https://gitee.com/openeuler/kernel/issues/IAGIZR CVE: NA
--------------------------------
Commit '1cea335d1db1 ("iomap: fix sub-page uptodate handling")' fix a race issue when submitting multiple read bios for a page spans more than one file system block(which names state_lock now) by adding a spinlock to make the page uptodate synchronous. However, the race condition only happened between the read I/O submitting and completeing threads, it's sufficient to use page lock to protect other paths. So there is no need to add this spinlock in the write page uptodating path, drop it could reduce some unnecessary locking overhead.
Signed-off-by: Zhang Yi yi.zhang@huawei.com --- fs/iomap/buffered-io.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index b61b3e7ed3bd..a577fcdf20a6 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -73,14 +73,10 @@ static void iomap_set_range_uptodate(struct folio *folio, size_t off, size_t len) { struct iomap_folio_state *ifs = folio->private; - unsigned long flags; bool uptodate = true;
- if (ifs) { - spin_lock_irqsave(&ifs->state_lock, flags); + if (ifs) uptodate = ifs_set_range_uptodate(folio, ifs, off, len); - spin_unlock_irqrestore(&ifs->state_lock, flags); - }
if (uptodate) folio_mark_uptodate(folio); @@ -437,7 +433,18 @@ static loff_t iomap_readpage_iter(const struct iomap_iter *iter,
if (iomap_block_needs_zeroing(iter, pos)) { folio_zero_range(folio, poff, plen); - iomap_set_range_uptodate(folio, poff, plen); + if (ifs) { + /* + * Hold state_lock to protect from submitting multiple + * bios for the same locked folio and then get multiple + * callbacks in parallel. + */ + spin_lock_irq(&ifs->state_lock); + iomap_set_range_uptodate(folio, poff, plen); + spin_unlock_irq(&ifs->state_lock); + } else { + folio_mark_uptodate(folio); + } goto done; }