zfs: mmu: take vma_list_mutex before tearing down PT during ARC buffer eviction

Without the lock page mapping and buffer eviction can run in parallel
which may cause following race:

page mapper thread               thread calling arc_evict()
map_addr() {
  page = arc_get_page();
  add_mapping(page, ptep);
                                  evict(page) {
                                    ptep = get_mapping(page);
                                    ptep.write(0);
                                    free(page);
                                  }

  ptep.write(page);
}

ARC code has no well defined order for taking its mutexes. It uses trylock()
and skips a buffer if required locks cannot be acquired. This patch uses
same approach for vma_list_mutex: if evicted buffer is shared try to
lock vma_list_mutex and skip the buffer if this fails.

Signed-off-by: Gleb Natapov <gleb@cloudius-systems.com>
Signed-off-by: Avi Kivity <avi@cloudius-systems.com>
aarch64: fix up merge issues

lots of mmu related changes require fixups for AArch64.

Signed-off-by: Claudio Fontana <claudio.fontana@huawei.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
aarch64: stub new mmu functions in bsd

commit 82f881a2 "zfs: mmu: take vma_list_mutex"
introduces code that needs to be stubbed for now for AArch64.

Signed-off-by: Claudio Fontana <claudio.fontana@huawei.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
scripts: Add build-standalone-img to build images used without capstan

This script is similar to build-capstan-img. Later we can hook this
script to scripts/build-osv-release to build images used without
capstan. It takes the same args with build-capstan-img.

Example output:

   $ find build/standalone
   build/standalone/cloudius/
   build/standalone/cloudius/osv-iperf
   build/standalone/cloudius/osv-iperf/osv-iperf.esx.ova
   build/standalone/cloudius/osv-iperf/osv-iperf.qemu.qcow2
   build/standalone/cloudius/osv-iperf/osv-iperf.vbox.ova
   build/standalone/cloudius/osv-iperf/osv-iperf.vmw.zip
   build/standalone/cloudius/osv-iperf/osv-iperf.gce.tar.gz

Signed-off-by: Asias He <asias@cloudius-systems.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
build-osv-release: standalone image support

Make scripts/build-osv-release support both Capstan and standalone
images.

Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
Revert "build: Skip rebuild of usr.img on osv.vmdk and osv.vdi target"

This reverts commit df30ec8d32dac5ad72d71314ab327c48d4e8a054. It breaks
building "osv.vdi" altogether.

Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
build-standalone-img: Add version number to image filename

Add OSv version number to image filename so that we can actually have
more than one release available for download...

Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
build-standalone-img: Fix image versioning

The typo in commit 425c5ce ("build-standalone-img: Add version number to
image filename") caused the shell script to evaluate "version" command
instead of expanding the "version" variable. Fix that.

Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
dhcp: remove lookup_opcode()

The lookup_opcode() function is incorrect. It was mishandling
DHCP_OPTION_PAD, which does not have a following length byte.

Also, the while condition is reading 'op' value which never
changes. This may result in reads beyond packet size.

Since this function is unused the best fix is to remove it.

Reveiwed-by: Vlad Zolotarov <vladz@cloudius-systems.com>
Signed-off-by: Tomasz Grabiec <tgrabiec@cloudius-systems.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
dhcp: fix parsing of DHCP options

There are several issues with current code. Firstly, the LENGTH_OK
macro was used in the condition in while(). This macro was checking if
options + op_len does not exceed packet limit. This macro works fine
when used from PARSE_OP() inside the switch, but because 'options' is
bumped up by op_len at the end of the loop body, use of this macro in
the while condition may result in premature exit of the loop. This was
causing that some times OSv was not parsing network mask and gateway
leaving them at 0.0.0.0 when started on Goodle Compute Engine. As a
result OSv was not responding over network. See issue #254.

Another issue was that the stop condition which checks for op ==
DHCP_OPTION_END was using 'op' from the outer context, which was never
overwritten. The actual variable which was changed based on the packet
content was redeclared inside the loop.

A third problem, spotted by Vlad, is that the code was not handling
DHCP_OPTION_PAD properly. This option has only opcode byte and no
following length byte. Currrent code would attempt to read the length
byte and skip by that amount, which would yiled incorrect parsing
result.

Reviewed-by: Vlad Zolotarov <vladz@cloudius-systems.com>
Signed-off-by: Tomasz Grabiec <tgrabiec@cloudius-systems.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
zfs: spa_zio_taskq[ZIO_TYPE_FREE][ZIO_TASKQ_ISSUE]->tq_lock contention

Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: George Wilson <george.wilson@delphix.com>
Reviewed by: Christopher Siden <christopher.siden@delphix.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Approved by: Richard Lowe <richlowe@richlowe.net>

Reference: https://illumos.org/issues/3581

Patch taken from Illumos and slight changes were needed to port it to OSv.

This patch targets improvement on taskq lock contention by dispatching work
over independent task queues. ZFS on Linux devops mention that it's not clear
whether or not this issue affects their port, but profile results showed that
time spent on taskq_thread() was reduced by about 11%.
Apart from getting performance benefits, the number of threads in OSv was
nicely reduced (from ~344 threads to ~224; so possibly saving a good amount
of memory footprint).
Also good for stepping towards our synchronicity with ZFS upstream.

Addressing the issue #247.

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>
jvmballoon: fix _soft_max_balloons check

Number of to be released balloons is calculated as a difference between
current number of balloons and sof max. If they are equal no balloons
are released and the loop repeats.

Signed-off-by: Gleb Natapov <gleb@cloudius-systems.com>
Signed-off-by: Avi Kivity <avi@cloudius-systems.com>
sched: fix waitqueue race causing failure to wake up

When waitqueue::wake_all() wakes up waiting threads, it calls
sched::thread::wake_lock() to enqueue those waiting threads on the mutex
protecting the waitqueue, thus avoiding needless contention on the mutex.
However, if a thread is already waking, we let it wake naturally and acquire
the mutex itself.

The problem is that the waitqueue code (wait_object<waitqueue>::poll())
examines the wait_record it sleeps on and see if it has woken, and if not,
goes back to sleep.  Since nothing in that thread-already-awake path clears
the wait_record, that is what happens, and the thread stalls, until a timeout
occurs.

Fix by clearing the wait record.  As it is protected by the mutex, no
extra synchronization is needed.

Observed with iperf -P 64 against the guest.  Likely triggered by net channels
waking up the thread, and then before it has a chance to wake up, a FIN
packet arrives that is processed in the driver thread; so when the packets
are consumed the thread is in the waking state.

Reviewed-by: Nadav Har'El <nyh@cloudius-systems.com>
Signed-off-by: Avi Kivity <avi@cloudius-systems.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
mgmt: update to latest

Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
vfs: fix partial non-blocking write

Our read() and write(), and their variants (pread, pwrite, readv, writev,
preadv, pwritev) all shared the same bug when it comes to a partial read or
write: they returned EWOULDBLOCK (EAGAIN) instead of returning successfully
with the number of bytes actually written or read, as they should have.

In the internals of the BSD read and write operations (e.g., sosend_generic)
each operation returns *both* an error number and a number of bytes left.
But at the end, the system call is expected to return just one of them -
either an error *or* a number of bytes. The existing read()/write() code,
when it saw the internals returning an error code, always returned it and
ignored the number of bytes. This was wrong: When the error is EWOULDBLOCK
and the number of bytes is non-zero, we should return this number of bytes
(i.e., a successful partial write), *not* the EWOULDBLOCK error.

This bug went unnoticed almost since the dawn of OSv, because partial reads
and writes are not common. For example, a write() to a blocking socket will
always return after the entire write is successful, and will not partially
succeed. Only when we write to an O_NONBLOCK socket, will it be possible to
see a partial write - But even then, we would need a pretty large write()
to see it only partially succeeding.

But this bug is very noticable when running the Jetty Web server (see issue
At some point it's like the response was restarted (complete with a second
copy of the headers). In Jetty's demo this was seen as half-shown images,
as well as corrupt output when fetching large text files like /test/da.txt.

Turns out that Jetty sends static responses in a surprisingly efficient
(for Java code...) way, using a single system call for the entire response:
It mmap()s the file it wishes to send, and then uses one writev() call to
send two arrays: The HTTP headers (built in malloc()ed memory), and the
file itself (from mmapped memory). So Jetty tries to write even a 1MB file
in one huge writev() call. But there's an added twist: It does so with the
socket configured to O_NONBLOCK. So for large writes, the write will only
partially succeed (empirically, only about 50KB will succeed), and Jetty
will notice the partial write and continue writing the rest - until the
whole file is sent. With the bug we had, part of the request will have been
written, but Jetty still thought the write didn't write anything so it would
start writing again from the beginning - causing the weird sort of response
corruption we've been seeing.

This patch also includes a test case which confirms this bug, and its fix.
In this test (tst-tcp-nbwrite), two threads communicate over a TCP socket
(on the loopback interface), one thread write()s a very large buffer and
the other receives what it can. We try this two times - once on a blocking
socket and once on a non-blocking socket. In each case we expect the number
of bytes written by one thread (return from write()) and the number read
by the second thread (return from read()) to be the same. With the bug we
had, in the non-blocking case we saw write() returning -1 (with
errno=EWOULDBLOCK) but read returned over 50,000 bytes, causing the test
to fail.

Fixes #257.

Signed-off-by: Nadav Har'El <nyh@cloudius-systems.com>
Signed-off-by: Avi Kivity <avi@cloudius-systems.com>
release-ec2: trivial: help screen enhancements

Help screen enhanced to make parameters syntax clear

Signed-off-by: Dmitry Fleytman <dmitry@daynix.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
release-ec2: Introduce AWS regions list parameter

Parameter --override-regions added

Signed-off-by: Dmitry Fleytman <dmitry@daynix.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
release-ec2: Base released images on Linux AMI

Linux AMI suits OSv better because of default settings
instances inherit on creation - mainly preconfigured SSH
access and open SSH ports.

Signed-off-by: Dmitry Fleytman <dmitry@daynix.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
upload-ec2: Introduce script for images upload

Introduce script upload-ec2.sh that gets prebuilt
OSv images from S3 and converts them to EC2 AMIs.

Signed-off-by: Dmitry Fleytman <dmitry@daynix.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
Merge branch 'ec2-release-scripts'