mmu: introduce mmap_small flag

If the flags is set on vma it is backed by small pages only.

Signed-off-by: Gleb Natapov <gleb@cloudius-systems.com>
Reviewed-by: Glauber Costa <glommer@cloudius-systems.com>
arc: mark arc buffers as shared

A new (private) flag is added that marks a buffer as shared between
ZFS and the page cache. It indicates that before evicting this buffer,
ZFS will have to take some action. Right now no action is taken besides
clearing the flag.

Signed-off-by: Glauber Costa <glommer@cloudius-systems.com>
arc: unmap shared buffer when they are evicted.

This comes together with the placeholder in the mmu-side to get this
warning. The actual functionality is not yet implemented

Signed-off-by: Glauber Costa <glommer@cloudius-systems.com>
mmu: page out class

To avoid overloading "change_perm"'s meaning, and taking advantage of our nice
template based page walker, this patch creates another walker that will unmap
a range of pages, marking them all as non present.

Signed-off-by: Glauber Costa <glommer@cloudius-systems.com>
mmu: force shared mappings to use small pages

The underlying filesystem won't be able to back it with huge pages, so force
small.

Signed-off-by: Glauber Costa <glommer@cloudius-systems.com>
uio: super structure around uio

I am using the same name as solaris code expect. The first field is an uio,
and the rest is something that we will use in specialized functions.

Signed-off-by: Glauber Costa <glommer@cloudius-systems.com>
zfs: provide a dmu mapping function

That will allow us to read a dmu arc-backed buffer and acquire a pointer to it,
instead of copying it somewhere else. This function will both do mapping and
unmapping, depending on its last parameter.

Signed-off-by: Glauber Costa <glommer@cloudius-systems.com>
vfs: allow a mapping operation

We won't require all filesystems to implement it, those who don't should return
ENOSYS.

Signed-off-by: Glauber Costa <glommer@cloudius-systems.com>
zfs posix: map and unmap functions

Provide a map and unmap function that maps directly into the ARC cache.  Most
of the boilerplate code is inspired in the read function, but I have decided to
leave it separate to avoid complicating the original functions.

Signed-off-by: Glauber Costa <glommer@cloudius-systems.com>
map_file: expand parameters to get_page/put_page

To better deal with shared buffers, we should expand the interface to
get_page/put_page.  Three changes are needed: first, the start of the virtual
address is passed to both. Together with the offset, it can be used to uniquely
identify the virtual address being mapped. That will be used to manage the
mapping list.

Regarding the offset itself, there is need to also pass the file offset
downwards, the one specified by the mapping. Reading that from the file pointer
is not enough, because not only this is not what the user has asked for, but it
can change during the map's lifetime. It also should be a separate parameter
from the in-mapping offset, not summed together with it. Doing otherwise would
make impossible for the mapping function to differentiate between those two
concepts

Also, put_page is called from the free operation, but does not receive the
actuall address from it. Knowing the physical address will be important to shut
down our mapping list.

Signed-off-by: Glauber Costa <glommer@cloudius-systems.com>
mmu: avoid naked _range updates

The vma class has a method to update its range. Use it during split, instead
of naked coding it. It will be particularly important if we want to tag other
operations along the range update.

Signed-off-by: Glauber Costa <glommer@cloudius-systems.com>
mmu: call set unconditionally

Historically, we only call vma::set() for non-fixed mappings. The reason is
that for fixed mappings, we already know and set which address we are putting
the map at. However, now that we have more operations tagging along vma::set(),
it is better to call it unconditionally.

Signed-off-by: Glauber Costa <glommer@cloudius-systems.com>
mmu: map the underlying file directly from filesystem page cache

Signed-off-by: Glauber Costa <glommer@cloudius-systems.com>
mmu: handle multiple mappings to the same file

This case is not supposed to be utterly common, but we have to handle it
anyway.  This implementation is slightly naive, but it should be okay if the
number of mappings is small.  We should revisit it this number start growing
too much

Signed-off-by: Glauber Costa <glommer@cloudius-systems.com>
mmu: only handle page sized maps for buffer mappings

Gleb have noticed a problem with the buffer mapping logic, that would make
unrelated mappings that would be adjacent to the file mapping be invalidated as
well. This is because we were invalidated an area as large as the buffer.  If
the mapping would, for instance, end in the middle of the buffer, we would keep
invalidated adjacent regions.

The solution is to change the code to handle per-page, not per-buffer mappings.
We would likely need something like that anyway for COW maps, so let's just
start handling it now.

Signed-off-by: Glauber Costa <glommer@cloudius-systems.com>
tests: test for larger-than-memory mmaps.

It will create a file on-disk twice as large as memory, and then will map it entirely
in memory. The file is then read from using 3 different sequential patterns, and then
later on 2 threaded patterns.

This test does not handle writes.

It goes in misc because it takes a very long time to run (especially with a random pattern)

Example output:

Total Ram 586 Mb
Write done
Double Pass OK (13.6323 usec / page)
Recency OK (3.35954 usec / page)
Random Access OK (640.926 usec / page)
Threaded pass 1 address ended OK
Threaded pass many addresses ended OK
PASSED

Signed-off-by: Glauber Costa <glommer@cloudius-systems.com>