Message ID | 20240605092455.20435-3-kundan.kumar@samsung.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | block: add larger order folio instead of pages | expand |
On Wed, Jun 05, 2024 at 02:54:55PM +0530, Kundan Kumar wrote: > - page = folio_page(fi.folio, fi.offset / PAGE_SIZE); > - nr_pages = (fi.offset + fi.length - 1) / PAGE_SIZE - > - fi.offset / PAGE_SIZE + 1; > - do { > - bio_release_page(bio, page++); > - } while (--nr_pages != 0); > + bio_release_page(bio, &fi.folio->page); > } Why can't we have ... bio_release_folio(bio, fi.folio, nr_pages); which is implemented as: static inline void bio_release_page(struct bio *bio, struct folio *folio, unsigned long nr_pages) { if (bio_flagged(bio, BIO_PAGE_PINNED)) gup_put_folio(folio, nr_pages, FOLL_PIN); } Sure, we'd need to make gup_put_folio() unstatic, but this seems far more sensible.
On Wed, Jun 05, 2024 at 10:22:11PM +0100, Matthew Wilcox wrote: > Why can't we have ... > > bio_release_folio(bio, fi.folio, nr_pages); > > which is implemented as: > > static inline void bio_release_page(struct bio *bio, struct folio *folio, unsigned long nr_pages) > { > if (bio_flagged(bio, BIO_PAGE_PINNED)) > gup_put_folio(folio, nr_pages, FOLL_PIN); > } > > Sure, we'd need to make gup_put_folio() unstatic, but this seems far > more sensible. Yes. Although maybe a unpin_user_folio wrapper that hides the FOLL_PIN which we're trying to keep private would be the slightly nicer variant.
diff --git a/block/bio.c b/block/bio.c index 7857b9ca5957..28418170a14a 100644 --- a/block/bio.c +++ b/block/bio.c @@ -1166,20 +1166,12 @@ void __bio_release_pages(struct bio *bio, bool mark_dirty) struct folio_iter fi; bio_for_each_folio_all(fi, bio) { - struct page *page; - size_t nr_pages; - if (mark_dirty) { folio_lock(fi.folio); folio_mark_dirty(fi.folio); folio_unlock(fi.folio); } - page = folio_page(fi.folio, fi.offset / PAGE_SIZE); - nr_pages = (fi.offset + fi.length - 1) / PAGE_SIZE - - fi.offset / PAGE_SIZE + 1; - do { - bio_release_page(bio, page++); - } while (--nr_pages != 0); + bio_release_page(bio, &fi.folio->page); } } EXPORT_SYMBOL_GPL(__bio_release_pages); @@ -1342,6 +1334,9 @@ static int __bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter) } else bio_iov_add_folio(bio, folio, len, folio_offset); + if (bio_flagged(bio, BIO_PAGE_PINNED) && num_pages > 1) + unpin_user_pages(pages + i, num_pages - 1); + /* Skip the pages which got added */ i = i + (num_pages - 1);
Unpin pages which belong to same folio. This enables us to release folios on I/O completion rather than looping through pages. Suggested-by: Keith Busch <kbusch@kernel.org> Signed-off-by: Kundan Kumar <kundan.kumar@samsung.com> --- block/bio.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-)