kstats: Initial implementation

It's important to make this initial implementation as arc_stats completely
relies on it to be exported to the outside world.

Reviewed-by: Glauber Costa <glommer@cloudius-systems.com>
Signed-off-by: Raphael S. Carvalho <raphaelsc@cloudius-systems.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
arc: Re-enable portions of code needed by reclaim thread

arc_reclaim_needed checks if reclaiming is needed by looking
at two possible conditions:
1) the variable needfree is set.
2) memory used is higher than 3/4 of the system memory.

The actual problem is that arc_reclaim_needed was completely
disabled. It would always return 0, i.e. reclaim not needed.

Add stub to vm_paging_needed to avoid an unneeded ifdef.

Reclaiming support is planned, so let's re-enable what's needed
and implement kmem_used which is used to determine the amount
of memory used so far.

Reviewed-by: Glauber Costa <glommer@cloudius-systems.com>
Signed-off-by: Raphael S. Carvalho <raphaelsc@cloudius-systems.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
bsd: Register ARC shrinker

This patch registers the ARC shrinker by using the event handler
list from BSD side. When ARC is initialized, it inserts the lowmem event
handler into an external event handler list. lowmem basically signals
the reclaiming thread which will then wake up to decide which approach
should be used to shrink the ARC.

The memory pressure on OSv is activated when the 20% watermark is
reached, so the shrink policy will decide which shrinker should
be called on such events.

bsd_shrinker_init is the responsible to find the lowmem event handler
from the external list, and integrate it into our shrinker infrastructure.

arc_lowmem needed few changes to return the amount of released memory
from the ARC.

Glauber and I tested the functionality by filling up the ARC up
to its target, then allocating as much memory as possible to see
if the ARC shrinker would take place to release memory back to
the operating system.

Signed-off-by: Glauber Costa <glommer@cloudius-systems.com>
Signed-off-by: Raphael S. Carvalho <raphaelsc@cloudius-systems.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
tests: testcase to reproduce a variety of IO workloads

Mainly created to be used as a tool that reproduces specific workloads,
so allowing us to understand how underlying components are performing,
e.g. Adjustable Replacement Cache (ARC) from ZFS.

Reviewed-by: Glauber Costa <glommer@cloudius-systems.com>
Signed-off-by: Raphael S. Carvalho <raphaelsc@cloudius-systems.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
tests: Add tool to analyze ARC and shrink functionality

The main purpose of this tool is to understand/analyze the ARC behavior/
performance on specific workloads.

$ scripts/run.py -e 'tests/misc-zfs-arc.so --help'
OSv v0.05-155-g1f04e49
Allowed options:
  --help                produce help message
  --set-max-target      set ARC max target to 80% of the system memory.
  --check-arc-shrink    check ARC shrink functionality
  --test arg            analyze ARC performance on a given testcase, e.g.
                        --test tst-001.so

* --set-max-target: Used to check performance when ARC max target is
higher than usual. Given that more data will be load into ARC, ZFS operations
that needs I/O would perform better. 80% was chosen as the low watermark
is 20%, so avoiding a bunch of memory pressure, thus more stability.

* --check-arc-shrink: Check the functionality of the function arc_shrink
from ARC.

* --test arg: Check ARC performance on a specified testcase, e.g.:
$ scripts/run.py -e 'tests/misc-zfs-arc.so --test tst-fs-link.so'

* Default run, i.e -e 'tests/misc-zfs-arc.so' provides four distinct
workloads:
1) Non-linear one where prefetch shouldn't be as effective.
2) Load all data into cache, then read it afterwards to check performance
on such cases, almost speed of main memory.
3) Linear workload where the amount of data is 1.5% the size of the system
memory, thus page replacement will be strongly used, and as the operation
is sequential, prefetch (readahead) must be effective. It leads to a high
cache hit ratio as blocks were read ahead of time.
4) Keep allocating memory through a populated anonymous mmaping to see
if shrink would take place to release memory back to the operating system.

Eventual reports and ARC stats are provided to ease the task of understanding
ARC performance on specific workloads.

Signed-off-by: Raphael S. Carvalho <raphaelsc@cloudius-systems.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>