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? > count_vm_events(PSWPIN, sio->pages); > } else { > 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); > > - SetPageError(page); > - ClearPageUptodate(page); > - unlock_page(page); > + folio_set_error(folio); > + folio_clear_uptodate(folio); > + folio_unlock(folio); Similar questions to the last patch -- who checks the error flag on this page/folio, and isn't the folio already !uptodate? > } > pr_alert_ratelimited("Read-error on swap-device\n"); > } > -- > 2.25.1 >