On Mon, Feb 03, 2014 at 03:41:55PM +0100, Miklos Szeredi wrote:
> > BTW, is there any reason why fuse/dev.c doesn't use atomic kmaps for
> > everything? After all, as soon as we'd done kmap() in there, we
> > grab a spinlock and don't drop it until just before kunmap(). With
> > nothing by memcpy() done in between... Miklos? AFAICS, we only win
> > from switching to kmap_atomic there - we can't block anyway, we don't
> > need it to be visible on other CPUs and nesting isn't a problem.
> > Looks like it'll be cheaper in highmem cases and do exactly the same
> > thing as now for non-highmem... Comments?
> We don't hold the spinlock. But regardless, I don't see any reason why it
> couldn't be atomic kmap.
Oh, right - lock_request() drops it. Still, I don't see anything other
than copying between map and unmap, and not a lot of it either...
As for get_user_pages_fast()... Why not do what mm/filemap.c does to
deal with the same issue? Prefault, then lock the destination page,
kmap_atomic() and do __copy_from_user_inatomic(). If that fails (i.e.
if something has raced with us and evicted the source from page table),
shrug, unlock and repeat.
I do realize that you want to share code between the read and write sides
of the whole thing, but I'm not sure it's worth doing. Almost everything
in that pile knows the direction - splitting a few low-level functions
into ..._in() and ..._out() variants (mostly along the checks already
in them) allows to separate these paths completely, at which point it
becomes possible to use copy-page-to-iov_iter, etc. to take care of
mapping, dealing with iovec components, etc.
What I want to do is to get a sane set of iov_iter primitives that could
be used for everything, without their users having to care about the
nature of iov_iter - iovec, array of <page,offset,size,how_to_steal>
quadruples, biovec, etc. The interesting part of it is how to make
that set expressive enough, while keeping it reasonably sane. And
fs/fuse/dev.c is one of the more interesting potential users out there...
I've a growing queue with the beginning of that stuff; so far it's mostly
preparatory bits and pieces. Currently being tested: copy_page_to_iter()
(more or less similar to iov_iter_copy_to_..., but with saner interface
and dealing with the kmap, atomics, etc. without forcing the callers do
do that) with conversion of generic_file_aio_read() and friends to it.
If it survives the local beating, I'll start pushing it out (as
vfs.git#iov_iter); that pile is getting to potentially interesting bits...