On Fri, Apr 12, 2019 at 09:14:43AM +1000, Dave Chinner wrote: > On Thu, Apr 11, 2019 at 05:08:31PM -0400, jglisse@xxxxxxxxxx wrote: > > From: Jérôme Glisse <jglisse@xxxxxxxxxx> > > > > We want to keep track of how we got a reference on page when doing DIO, > > ie wether the page was reference through GUP (get_user_page*) or not. > > For that this patch rework the way page reference is taken and handed > > over between DIO code and BIO. Instead of taking a reference for page > > that have been successfuly added to a BIO we just steal the reference > > we have when we lookup the page (either through GUP or for ZERO_PAGE). > > > > So this patch keep track of wether the reference has been stolen by the > > BIO or not. This avoids a bunch of get_page()/put_page() so this limit > > the number of atomic operations. > > Is the asme set of changes appropriate for the fs/iomap.c direct IO > path (i.e. XFS)? Yes and it is part of this patchset AFAICT iomap use bio_iov_iter_get_pages() which is updated to pass down wether page are coming from GUP or not. The bio you get out of that is then release through iomap_dio_bio_end_io() which calls bvec_put_page() which will use put_user_page() for GUPed page. I may have miss a case and review are welcome. Note that while the convertion is happening put_user_page is exactly the same as put_page() in fact the implementation just call put_page() with nothing else. The tricky part is making sure that before we diverge with a put_user_page() that does something else that put_page() we will need to be sure that we did not left a path that do GUP but does call put_page() and not put_user_page(). We have some plan to catch that in debug build. In any case i believe we will be very careful when the times come to change put_user_page() to something different. Cheers, Jérôme