On 27/10/2023 12:47, Matthew Wilcox wrote: > On Fri, Oct 27, 2023 at 10:03:15AM +0200, Pankaj Raghav wrote: >> I also noticed this pattern in fscrypt_zeroout_range_inline_crypt(). >> Probably there are more places which could use a ZERO_FOLIO directly >> instead of iterating with ZERO_PAGE. >> >> Chinner also had a similar comment. It would be nice if we can reserve >> a zero huge page that is the size of MAX_PAGECACHE_ORDER and add it as >> one folio to the bio. > > i'm on holiday atm. start looking at mm_get_huge_zero_page() Thanks for the pointer. I made a rough version of how it might look like if I use that API: diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c index bcd3f8cf5ea4..6ae21bd16dbe 100644 --- a/fs/iomap/direct-io.c +++ b/fs/iomap/direct-io.c @@ -236,17 +236,43 @@ static void iomap_dio_zero(const struct iomap_iter *iter, struct iomap_dio *dio, loff_t pos, unsigned len) { struct inode *inode = file_inode(dio->iocb->ki_filp); - struct page *page = ZERO_PAGE(0); + struct page *page = NULL; + bool huge_page = false; + bool fallback = false; struct bio *bio; - bio = iomap_dio_alloc_bio(iter, dio, 1, REQ_OP_WRITE | REQ_SYNC | REQ_IDLE); + if (len > PAGE_SIZE) { + page = mm_get_huge_zero_page(current->mm); + if (likely(page)) + huge_page = true; + } + + if (!huge_page) + page = ZERO_PAGE(0); + + fallback = ((len > PAGE_SIZE) && !huge_page); + + bio = iomap_dio_alloc_bio(iter, dio, BIO_MAX_VECS, + REQ_OP_WRITE | REQ_SYNC | REQ_IDLE); fscrypt_set_bio_crypt_ctx(bio, inode, pos >> inode->i_blkbits, GFP_KERNEL); + bio->bi_iter.bi_sector = iomap_sector(&iter->iomap, pos); bio->bi_private = dio; bio->bi_end_io = iomap_dio_bio_end_io; - __bio_add_page(bio, page, len, 0); + if (!fallback) { + bio_add_folio_nofail(bio, page_folio(page), len, 0); + } else { + while (len) { + unsigned int io_len = + min_t(unsigned int, len, PAGE_SIZE); + + __bio_add_page(bio, page, io_len, 0); + len -= io_len; + } + } + iomap_dio_submit_bio(iter, dio, bio, pos); } The only issue with mm_get_huge_zero_page() is that it can fail, and we need to fallback to iteration if it cannot allocate a huge folio. PS: Enjoy your holidays :)