On Mon, Jul 17, 2023 at 02:40:24PM +0100, Matthew Wilcox wrote: > > 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. sio_read_complete is a kiocb.ki_complete handler. There is no coalesce going on for ITER_BVEC iov_iters, which share nothing but the underlying data structure with the block I/O path.