Message ID | 20200822042059.1805541-1-jhubbard@nvidia.com (mailing list archive) |
---|---|
Headers | show |
Series | bio: Direct IO: convert to pin_user_pages_fast() | expand |
On Fri, Aug 21, 2020 at 09:20:54PM -0700, John Hubbard wrote: > Direct IO behavior: > > ITER_IOVEC: > pin_user_pages_fast(); > break; > > ITER_KVEC: // already elevated page refcount, leave alone > ITER_BVEC: // already elevated page refcount, leave alone > ITER_PIPE: // just, no :) Why? What's wrong with splice to O_DIRECT file?
On Tue, Aug 25, 2020 at 02:54:28AM +0100, Al Viro wrote: > On Fri, Aug 21, 2020 at 09:20:54PM -0700, John Hubbard wrote: > > > Direct IO behavior: > > > > ITER_IOVEC: > > pin_user_pages_fast(); > > break; > > > > ITER_KVEC: // already elevated page refcount, leave alone > > ITER_BVEC: // already elevated page refcount, leave alone > > ITER_PIPE: // just, no :) > > Why? What's wrong with splice to O_DIRECT file? Sorry - s/to/from/, obviously. To spell it out: consider generic_file_splice_read() behaviour when the source had been opened with O_DIRECT; you will get a call of ->read_iter() into ITER_PIPE destination. And it bloody well will hit iov_iter_get_pages() on common filesystems, to pick the pages we want to read into. So... what's wrong with having that "pin" primitive making sure the pages are there and referenced by the pipe?
On 8/24/20 6:54 PM, Al Viro wrote: > On Fri, Aug 21, 2020 at 09:20:54PM -0700, John Hubbard wrote: > >> Direct IO behavior: >> >> ITER_IOVEC: >> pin_user_pages_fast(); >> break; >> >> ITER_KVEC: // already elevated page refcount, leave alone >> ITER_BVEC: // already elevated page refcount, leave alone >> ITER_PIPE: // just, no :) > > Why? What's wrong with splice to O_DIRECT file? > Oh! I'll take a look. Is this the fs/splice.c stuff? I ruled this out early mainly based on Christoph's comment in [1] ("ITER_PIPE is rejected іn the direct I/O path"), but if it's supportable then I'll hook it up. (As you can see, I'm still very much coming up to speed on the various things that invoke iov_iter_get_pages*().) [1] https://lore.kernel.org/kvm/20190724061750.GA19397@infradead.org/ thanks,
On 8/24/20 7:07 PM, Al Viro wrote: > On Tue, Aug 25, 2020 at 02:54:28AM +0100, Al Viro wrote: >> On Fri, Aug 21, 2020 at 09:20:54PM -0700, John Hubbard wrote: >> >>> Direct IO behavior: >>> >>> ITER_IOVEC: >>> pin_user_pages_fast(); >>> break; >>> >>> ITER_KVEC: // already elevated page refcount, leave alone >>> ITER_BVEC: // already elevated page refcount, leave alone >>> ITER_PIPE: // just, no :) >> >> Why? What's wrong with splice to O_DIRECT file? > > Sorry - s/to/from/, obviously. > > To spell it out: consider generic_file_splice_read() behaviour when > the source had been opened with O_DIRECT; you will get a call of > ->read_iter() into ITER_PIPE destination. And it bloody well > will hit iov_iter_get_pages() on common filesystems, to pick the > pages we want to read into. > > So... what's wrong with having that "pin" primitive making sure > the pages are there and referenced by the pipe? > (our emails crossed) OK, yes, let me hook that up. I was just unaware of that flow, I'll go off and figure it out. Thanks for looking at this! thanks,
On Mon, Aug 24, 2020 at 07:07:02PM -0700, John Hubbard wrote: > On 8/24/20 6:54 PM, Al Viro wrote: > > On Fri, Aug 21, 2020 at 09:20:54PM -0700, John Hubbard wrote: > > > > > Direct IO behavior: > > > > > > ITER_IOVEC: > > > pin_user_pages_fast(); > > > break; > > > > > > ITER_KVEC: // already elevated page refcount, leave alone > > > ITER_BVEC: // already elevated page refcount, leave alone > > > ITER_PIPE: // just, no :) > > > > Why? What's wrong with splice to O_DIRECT file? > > > > Oh! I'll take a look. Is this the fs/splice.c stuff? I ruled this out early > mainly based on Christoph's comment in [1] ("ITER_PIPE is rejected іn the > direct I/O path"), but if it's supportable then I'll hook it up. ; cat >a.c <<'EOF' #define _GNU_SOURCE #include <fcntl.h> #include <unistd.h> #include <stdlib.h> int main() { int fd = open("./a.out", O_DIRECT); splice(fd, NULL, 1, NULL, 4096, 0); return 0; } EOF ; cc a.c ; ./a.out | wc -c 4096 and you just had ->read_iter() called with ITER_PIPE destination.
On 8/24/20 7:22 PM, Al Viro wrote: > On Mon, Aug 24, 2020 at 07:07:02PM -0700, John Hubbard wrote: >> On 8/24/20 6:54 PM, Al Viro wrote: >>> On Fri, Aug 21, 2020 at 09:20:54PM -0700, John Hubbard wrote: >>> >>>> Direct IO behavior: >>>> >>>> ITER_IOVEC: >>>> pin_user_pages_fast(); >>>> break; >>>> >>>> ITER_KVEC: // already elevated page refcount, leave alone >>>> ITER_BVEC: // already elevated page refcount, leave alone >>>> ITER_PIPE: // just, no :) >>> >>> Why? What's wrong with splice to O_DIRECT file? >>> >> >> Oh! I'll take a look. Is this the fs/splice.c stuff? I ruled this out early >> mainly based on Christoph's comment in [1] ("ITER_PIPE is rejected іn the >> direct I/O path"), but if it's supportable then I'll hook it up. > > ; cat >a.c <<'EOF' > #define _GNU_SOURCE > #include <fcntl.h> > #include <unistd.h> > #include <stdlib.h> > > int main() > { > int fd = open("./a.out", O_DIRECT); > splice(fd, NULL, 1, NULL, 4096, 0); > return 0; > } > EOF > ; cc a.c > ; ./a.out | wc -c > 4096 > > and you just had ->read_iter() called with ITER_PIPE destination. > That example saves me a lot of time! Much appreciated. thanks,