On Tue, Jul 18, 2023 at 08:58:17PM +0800, zhangpeng (AS) wrote: > On 2023/7/17 21:40, Matthew Wilcox wrote: > > > On Mon, Jul 17, 2023 at 09:25:58PM +0800, Peng Zhang wrote: > > > +++ b/mm/page_io.c > > > @@ -406,19 +406,19 @@ static void sio_read_complete(struct kiocb *iocb, long ret) > > > if (ret == sio->len) { > > > for (p = 0; p < sio->pages; p++) { > > > - struct page *page = sio->bvec[p].bv_page; > > > + struct folio *folio = page_folio(sio->bvec[p].bv_page); > > > - SetPageUptodate(page); > > > - unlock_page(page); > > > + folio_mark_uptodate(folio); > > > + folio_unlock(folio); > > > } > > I'm kind of shocked this works today. Usually bvecs coalesce adjacent > > pages into a single entry, so you need to use a real iterator like > > bio_for_each_folio_all() to extract individual pages from a bvec. > > Maybe the sio bvec is constructed inefficiently. > > > > I think Kent had some bvec folio iterators in progress? > > I'll convert bio_first_page_all() to bio_first_folio_all() in a v2. That isn't my point at all. What I'm saying is that when you call a function like bio_add_folio(), if @folio is physically adjacent to the immediately prior folio already in the bio, it will extend the bv_len instead of adding the new folio to the bvec. Maybe there's nothing like that for sio.