akaros.git
2 years agoEnable EFER NX bit and OSXSAVE bit in cr4
Zach Zimmerman [Thu, 24 Aug 2017 22:07:26 +0000 (15:07 -0700)]
Enable EFER NX bit and OSXSAVE bit in cr4

EFER_NX allows the guest to disable execute perms
on its pages.

OSXSAVE allows guest user applications to execute xsave.

Change-Id: Icb9920564ae07184dc9aa07cad2c79825d2adbad
Signed-off-by: Zach Zimmerman <zpzimmerman@gmail.com>
[ Compilation bug, missing ) on assert() ]
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoChanged BRK_END to 0x0000300000000000 (XCC)
Zach Zimmerman [Thu, 24 Aug 2017 21:37:28 +0000 (14:37 -0700)]
Changed BRK_END to 0x0000300000000000 (XCC)

Allows mmaps in the high EPT address space

Change-Id: I8f19f755708a8de455582a14964fb17d2751dc62
Signed-off-by: Zach Zimmerman <zpzimmerman@gmail.com>
[ XCC warning - rebuild glibc if you're paranoid ]
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoUpdate to linuxemu syscall structure
Zach Zimmerman [Thu, 17 Aug 2017 23:06:51 +0000 (16:06 -0700)]
Update to linuxemu syscall structure

Changed linuxemu to use array of function pointers
Changed dune test to use linuxemu by default
Modified linuxemu to use a shared library for syscall extensions

Signed-off-by: Zach Zimmerman <zpzimmerman@gmail.com>
Change-Id: Id4b7d86b5f9cc95b224ebe9e282a3973e80b9130
[ checkpatch warning ]
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoFix deadlock in __hpf()
Barret Rhoden [Wed, 23 Aug 2017 21:48:29 +0000 (17:48 -0400)]
Fix deadlock in __hpf()

When erroring out, we were not unlocking first.

As a side note, if you give the kernel a virtual address and tell it to use
it for an operation (e.g. read(fd, VIRT_ADDR, amt), that memory should be
anonymous memory.  At the very least, it must be soft-faultable (i.e.  not
a file that isn't in the page cache).  Considering there's limited control
over that, I currently don't allow that either.  So something like this
will fail:

va = mmap(..., fd, 0)
read(another_fd, va, amt);

This restriction is stricter than Linux, and is because of userspace's role
in managing its own memory - it's up to the user to know what is or isn't
resident.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoChange __blksize_t to be 64 bits
Dan Cross [Wed, 23 Aug 2017 21:24:26 +0000 (17:24 -0400)]
Change __blksize_t to be 64 bits

Change-Id: I03360a5e896fc53c16da521391ad1e4fd5d1067c
Signed-off-by: Dan Cross <crossd@gmail.com>
[ make this in sync with glibc ]
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoparlib: Fix "can't print 'ret'" bug
Barret Rhoden [Fri, 18 Aug 2017 20:21:44 +0000 (16:21 -0400)]
parlib: Fix "can't print 'ret'" bug

Thanks to nasty macros, if you tried to do something like:

int ret = 3;
printf("Return value is %d\n", ret);

You'd get "Return value is 0".  The problem was that the 'ret' variable
inside the macro would be the one printed, not the one passed in.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoparlib: Prevent running ctors twice
Barret Rhoden [Tue, 22 Aug 2017 18:21:23 +0000 (14:21 -0400)]
parlib: Prevent running ctors twice

Previously, we only were protecting vcore_lib_init() and
uthread_lib_init().  However, there are other ctors out there, some of
which have external effects (devalarm).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoparlib: Fix fake parlib detection for dlopen() (XCC)
Barret Rhoden [Fri, 18 Aug 2017 19:53:37 +0000 (15:53 -0400)]
parlib: Fix fake parlib detection for dlopen() (XCC)

This goes back to commit 2d0747b5a1f4 ("parlib: Don't run ctors in "fake
parlib"").

That commit worked if the library was loaded first, as is the case with
e.g. libelf.so.  However, if the library was loaded after the binary, it
might see the program binary's _start, and rightly notice it differs from
__fake_start.  To make matters worse, whether or not the library's _start
was overloaded depended on whether or not the binary accessed it.  It's a
mess that I never fully tracked down.

The current version does the trick, at least as long as we keep the binary
mapped below our anonymous mmaps.

If you're paranoid, rebuild the world, though that's probably unnecessary.
At least do this:

$ make install-libs
$ make apps-install

And then build any other shared libs.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoVmm file mmap ept fault fix (XCC)
Zach Zimmerman [Tue, 15 Aug 2017 21:27:39 +0000 (14:27 -0700)]
Vmm file mmap ept fault fix (XCC)

Modified vthreads to also check for EAGAIN (like uthreads) in the ept
fault handler. This allows vthreads that mmap with files to correctly
populate memory on an ept fault. Included a test (mmap_file_vmm) that
will check this condition is satisified.

Reinstall your kernel headers.

Change-Id: I09f7b70de98275ed8b9614f89179a0947ca35584
Signed-off-by: Zach Zimmerman <zpzimmerman@gmail.com>
[ XCC warning ]
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoChange map_memory and setup_paging to use virtual_machine struct
Ronald G. Minnich [Thu, 17 Aug 2017 23:13:40 +0000 (16:13 -0700)]
Change map_memory and setup_paging to use virtual_machine struct

The virtual machine struct now contains guest minphys and maxphys addresses.
Map_memory can be called multiple times.

Setup_page is called with a pointer to the virtual_machine, which sets up
the early 1:1 mapping for the entire range of minphys to maxphys.

This is essentially what we already did, but now we can call map_memory
more than once.

While it may seem odd to to map the whole range from minphys to maxphys,
it's basically ok:
- you rarely call map_memory more than once
- the real check is done in the EPT, not the GPT
- GPT is replaced by most kernels
- in the vthreads case, we will typically start the thread
  memory at 4G, and there will be no holes in that space

So it's probably fine.

Change-Id: I48311bea6f7ae102959247ccad3234a85665b187
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
[ 80 char line fix ]
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agovmm: Don't allow both greedy and SCP mode
Barret Rhoden [Mon, 14 Aug 2017 16:20:19 +0000 (12:20 -0400)]
vmm: Don't allow both greedy and SCP mode

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agovmm: Use relative alarms for periodic LAPIC timers
Barret Rhoden [Mon, 14 Aug 2017 16:06:28 +0000 (12:06 -0400)]
vmm: Use relative alarms for periodic LAPIC timers

With relative alarms, we'll try to inject another IPI in X ticks from now,
instead of X ticks from when we wanted the previous alarm to go off.

If the VMM is descheduled for a long time, perhaps due to being an SCP or
otherwise low-priority, the "incremental" alarms will build up, since we
don't run our alarm handler immediately.

If the guest clocks off the ticks, it'll have problems.  If that happens,
we can come up with something else.  I tested tinycore by giving it the
period it wanted * 2, and it thought time passed correctly (date).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agovmm: Prioritize task threads over guest threads
Barret Rhoden [Mon, 14 Aug 2017 16:01:09 +0000 (12:01 -0400)]
vmm: Prioritize task threads over guest threads

Originally, we had some task threads that would busy wait, so we had to
alternate between tasks and guests.  Otherwise, the task threads would
starve the guests.

However, with Gan's "thread per timer tick per core" change, multicore VMs
running on an SCP VMMs ran into problems.  The guest cores would starve out
the task threads.  Specifically, every guest LAPIC timer tick we'd create N
task threads.  We'd run one of them, then the next *vcore* tick we'd run a
guest thread - which would spin in Linux in smp_call_function().  The N-1
other alarms would wait.  By the time those threads got their chance to run
(vcore tick), we'd also have N more LAPIC timer threads created.  So we'd
grow the number of threads by N-1 every tick (1 msec).

Anyway, this turned out to be an easy fix: prioritize task threads, like I
originally wanted to.  The old task thread that was busy waiting was
replaced a while ago.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agocons: Clamp the amount written to the console
Barret Rhoden [Mon, 14 Aug 2017 13:45:21 +0000 (09:45 -0400)]
cons: Clamp the amount written to the console

Large writes to the console take a long time.  Serial writes of about a
page take O(100ms).  Our kernel is currently non-preemptive, which is
based on a model of syscalls not taking too long.

Limiting the write sizes to 80 (the width of an ancient console, which
Ron will love) cuts the syscall time down to a few ms, which is within
the quantum of a process.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agosched: Use a relative alarm
Barret Rhoden [Mon, 14 Aug 2017 13:42:52 +0000 (09:42 -0400)]
sched: Use a relative alarm

Some syscalls, notably writing to the serial console, take a very long
time.  If you cat a large file to the console, your other SCPs (notably
SSH and shells) get nearly no service.  The ksched backlogs about a
dozen ksched_ticks during the syscalls, which are O(100ms).  With this
change, those other processes get a little more attention.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agomm: Enforce MAP_PRIVATE xor MAP_SHARED (XCC)
Barret Rhoden [Tue, 1 Aug 2017 21:11:45 +0000 (17:11 -0400)]
mm: Enforce MAP_PRIVATE xor MAP_SHARED (XCC)

We're only supposed to accept PRIVATE xor SHARED, but we were allowing
neither, and possibly both.

Rebuild glibc.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agomm: Fix VMR merge issues
Barret Rhoden [Tue, 1 Aug 2017 21:01:13 +0000 (17:01 -0400)]
mm: Fix VMR merge issues

First, mprotect wasn't merging at all.  Glibc actually uses this a lot when
we allocate TLSs (grep grow_heap() and ignore that it is static).

Also we were failing to merge some mappings since we were keeping track of
useless flags.  For instance, MAP_POPULATE only matters when we create the
mapping.  We don't need to track that later on.  Flags like that were
preventing mergers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoslab: Properly account for allocs from slabs
Barret Rhoden [Tue, 1 Aug 2017 20:03:20 +0000 (16:03 -0400)]
slab: Properly account for allocs from slabs

Previously, we only counted the magazine allocations.  However, all of the
magazines are built from direct slab allocations, which we weren't
counting.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoperf: Fix off-by-one retval for write()
Barret Rhoden [Tue, 1 Aug 2017 15:48:32 +0000 (11:48 -0400)]
perf: Fix off-by-one retval for write()

kptr should only be advanced when we are reading the input.  We were
incrementing kptr for PERFMON_CMD_CPU_CAPS, resulting in returning '2' for
a write of '1'.

This managed to work for a while since we had another bug masking it, which
was fixed in commit 395ce5721d96 ("Fix Plan 9 partial write() return
values").

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoReduce mmaps from vfprintf (XCC)
Barret Rhoden [Mon, 31 Jul 2017 21:20:00 +0000 (17:20 -0400)]
Reduce mmaps from vfprintf (XCC)

It turns out that the do_positional case, which was supposed to be uncommon
and only used for positional arguments, is always used.  That's due to our
use of custom printf functions, which we use for every program.

This change wraps all of the mmaps in a helper function - both the ones for
the specs and for the buffered prints.  The important thing is that we
don't do large allocations from vcore context, so we can just check for it
and branch.  The allocas from an always_inline function seem safe, and the
assembly looks OK.

Rebuild glibc.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agovmm: Exit console input thread if we get EOF on stdin
Dan Cross [Mon, 14 Aug 2017 18:06:14 +0000 (14:06 -0400)]
vmm: Exit console input thread if we get EOF on stdin

If we read an EOF from standard input (that is,
read() returns 0) then take that as a signal that
we should exit the console input loop, instead of
injecting console input interrupts into the guest
when there is nothing to read.

Tested by booting Linux and seeing a reduction
from a core spending approximately 85% of its time
in hardware interrupt handling down to spending
a single-digit percentage of time handling
interrupts.

Change-Id: Idb0a82ab9eab86c10f0e2169c008de236fe4e71d
Signed-off-by: Dan Cross <crossd@gmail.com>
[Added vmm:]
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoeventfd: Use write_hex_to_fd() (XCC)
Barret Rhoden [Mon, 31 Jul 2017 20:23:25 +0000 (16:23 -0400)]
eventfd: Use write_hex_to_fd() (XCC)

It's faster, clearer, and avoids glibc, which currently is doing an mmap
for this call.

Rebuild glibc.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agovmm: Use a task_thread cache
Barret Rhoden [Mon, 31 Jul 2017 19:33:05 +0000 (15:33 -0400)]
vmm: Use a task_thread cache

We actually run a lot of tasks now - one for every timer tick on every
guest core.  That's a lot of thread creation/destruction - you can see the
mmaps and munmaps with strace, and each munmap involves a tlb_shootdown
broadcast.

With a slab allocator, we can avoid all of that, especially the thread
initialization that involves the stack mmap/munmap.  Object reuse is
basically the lesson of the slab allocator.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoparlib: slab: mmap with PROT_EXEC
Barret Rhoden [Mon, 31 Jul 2017 19:37:28 +0000 (15:37 -0400)]
parlib: slab: mmap with PROT_EXEC

We don't know what the user will do with the memory, so let's let them use
it for anything.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoparlib: slab: Use the modern ctor/dtor interface
Barret Rhoden [Mon, 31 Jul 2017 19:30:24 +0000 (15:30 -0400)]
parlib: slab: Use the modern ctor/dtor interface

obj_size was useless.  We want the same interface that we use in the
kernel's slab allocator.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agox86: Don't enter the monitor for invalid opcode
Barret Rhoden [Mon, 31 Jul 2017 19:47:25 +0000 (15:47 -0400)]
x86: Don't enter the monitor for invalid opcode

That looks like old debugging code.  To get out of it, you'd have to
manually exit the monitor.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoFix matrix bug in gethostbyname (XCC)
Barret Rhoden [Sun, 30 Jul 2017 19:45:09 +0000 (12:45 -0700)]
Fix matrix bug in gethostbyname (XCC)

I messed that up when making gethostbyname recursive.

Rebuild glibc.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoAdd trace_printf() stub to glibc (XCC)
Barret Rhoden [Sun, 30 Jul 2017 19:42:50 +0000 (12:42 -0700)]
Add trace_printf() stub to glibc (XCC)

This is a debugging aid.  You can now use trace_printf() in parlib, if
you include parlib/ros_debug.h.  You can see the prints in dmesg
(#prof/kptrace).

trace_printf() is in parlib.  When we link with the real app (and thus
parlib), the weak symbol will get overridden.

Rebuild glibc at your leisure.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agovmrunkernel: remove unused and uninitialized stack variable
Ronald G. Minnich [Fri, 28 Jul 2017 23:49:29 +0000 (16:49 -0700)]
vmrunkernel: remove unused and uninitialized stack variable

Since we don't like writing random places in the guest.
We leave it at 0xe0000 for bad guests (like older Linux) that
use %rsp before setting it.

Change-Id: I3c3e0af73b9bd2ec73f6a1d30a66e8726bd762cc
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agonet: tcp: Use timestamps for the RTTM
Barret Rhoden [Thu, 20 Jul 2017 19:25:48 +0000 (15:25 -0400)]
net: tcp: Use timestamps for the RTTM

This greatly increases the accuracy of our RTTM.  Our RTT granularity for
the non-TS case was 50 msec.  So for machines less than 50 msec away,
you're getting 50 as your srtt.

The one thing I'm dubious about is whether the expected_samples business is
worth the cost of the divides.  RFC 7323 said we should do something, not
must.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agonet: tcp: Don't scale SRTT and MDEV
Barret Rhoden [Thu, 20 Jul 2017 18:01:26 +0000 (14:01 -0400)]
net: tcp: Don't scale SRTT and MDEV

The old code was keeping the values of SRTT and MDEV (really RTTVAR)
scaled, as if they were multiplied by their alpha and beta (bravo) factors.
This will be a minor issue when we try to use TS for RTTM.

Also, we weren't scaling those values back, so if you looked at e.g.
/net/tcp/1/status, you'd get a scaled value for the RTT.

Also, the RTO calculation looked off slightly.  RFC 6298.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agonet: tcp: Remove the RETRAN flag
Barret Rhoden [Thu, 20 Jul 2017 15:46:46 +0000 (11:46 -0400)]
net: tcp: Remove the RETRAN flag

Use tcb->snd.recovery instead.  RETRAN actually only applied to one pass
through update(), so I don't know what exactly it was doing.

Regarding the RTTM, we're not supposed to use ACKs from retrans.  The
RETRAN flag would do that for one update() call, but not for any others.
Using snd.recovery does the trick.

Note that we will get SACKs for new data (beyond recovery_pt) during
recovery, and these will not be used to adjust the RTT.  That's probably
fine, and overall better than the RETRAN flag.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agonet: tcp: Fix up the receive window
Barret Rhoden [Tue, 18 Jul 2017 13:36:53 +0000 (09:36 -0400)]
net: tcp: Fix up the receive window

There are a few things involved:

1) Plan 9 had a bug setting tcb->window.  We need to use rcv.scale, not
snd.scale.

2) QIO limits do nothing for the TCP receive queue.  All that qsetlimit and
qopen business is just tricking us into thinking it does something.

3) Our window scale was based on the bandwidth.  You actually want the BDP,
but you can't know that early on, and it's all heuristics.  Just going with
'7' is fine.  '3' is way too low; it leads to at most 512 KB in flight,
which is practically nothing.  Maybe we'll revisit this.

We're still doing no real management of the maximum receive window.  Plan 9
never really did that either.  The downside to this is that we promise to
receive and buffer that much data in RAM until the application drains it.
If this becomes an issue, we can change or tune it.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agonet: tcp: Avoid SWS for the sender
Barret Rhoden [Mon, 17 Jul 2017 20:15:53 +0000 (16:15 -0400)]
net: tcp: Avoid SWS for the sender

RFC 813.  Note that if you just did usable < MSS, but didn't look at
snd.wnd, then you might get what qemu's user networking did to me.  A
usable < MSS, but because the application didn't drain the queue yet.
Everything was acked.  In that case, you'd stop short and never send that
last packet.

I don't know if that's the receiver's fault or not, but we (the sender
here) should be defensive.  After all, maybe we'll interact with a Plan 9
machine!

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agonet: tcp: Avoid SWS for the receiver
Barret Rhoden [Mon, 12 Jun 2017 18:13:37 +0000 (14:13 -0400)]
net: tcp: Avoid SWS for the receiver

See RFC 813 and 1122.  Basically, don't advertise very small increases in
the window.

The driver for this is actually qemu's user networking behavior.  If you
*almost* fill Akaros's receive window (qemu guest), but it is still not
fully closed, qemu will stop sending data.  It seems to happen once the
window is less than the MSS.  Qemu waits 5 seconds, then fills the window
completely.  That sounds like a possibly buggy implementation of the
recommended sender algorithm in RFC 813 (grep 'additional.*enhancement').
It wasn't a SWS issue, but this algorithm for fixing SWS forces an ACK when
becomes rcv.wnd >= MSS.  That additional enhancement *alone* seems to imply
window updates from the receiver that are not driven by anything sent by
the sender - not sure if that's legal or not.

Using the MSS as the cutoff for a small packet was recommended by RFC 1122.
Actually, they said min(BUF / 2, MSS), and for practical situations, the
MSS is always less than BUF / 2.

The important thing for us is to treat the window as closed and to update
the window when it opens back up.  Regardless of the SWS business, if we
happened to have closed the window fully on an ACK, we would never tell the
sender, since we were turning off the acktimer.  (Note from the future: if
this statement seems wrong from something you're seeing, reverify it.  We
definitely need to keep the acktimer going for Qemu to advertise rcv.wnd >=
tcb->mss).

Note that the TCP stack doens't get a callback or anything when the window
opens up - if we wanted to, we could set up qio callbacks to update the
window when the user drains the read queue.  It's a little trickier than
that, since we care about an edge at > MSS, not > 0.  That's independent of
this change, but figured I'd mention it.  Also, the whole tcptimer setup is
a bit hokey.  The acktimers are put in for 1 'count' (50 / 50, grep
MSPTICK), and the expected value for the first tick is 25ms.  Just from
looking at tcpdumps, I'll see Akaros waiting for about 25-50ms between the
window-closing ACK and the window update.  Presumably we could have opened
the window before that.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agonet: tcp: Support SACK
Barret Rhoden [Fri, 14 Jul 2017 20:38:56 +0000 (16:38 -0400)]
net: tcp: Support SACK

This uses Selective Acknowledgment for send and receive.

I also added something not in the RFC.  If we have multiple sacks and get
an update to a sack that isn't the last one, that is a sign of a lost,
retransmitted packet.  That way we don't need to wait for the retrans
timeout (RTO).  I see it kick in nearly as often as the RTO, though that's
just from glancing at netlogs.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agonet: tcp: Refactor in prep for SACKs
Barret Rhoden [Fri, 14 Jul 2017 19:59:34 +0000 (15:59 -0400)]
net: tcp: Refactor in prep for SACKs

There were various things with the old code that made it hard to extend.
I added helper functions, clarified how flgcnt sent/ssize works, and
pulled out the recovery code enough so that I can add SACKs.

I also renamed snd.ptr.  It still does mostly what it did before.  In the
future, it will be used for retrans, but now it is also used for the
'leading edge' of new packets.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agonet: tcp: Track ipht and resets as their own class
Barret Rhoden [Wed, 12 Jul 2017 18:06:40 +0000 (14:06 -0400)]
net: tcp: Track ipht and resets as their own class

These pop up a lot for conversations we're not using, such as attempted
connections to closed ports.  Resets happen both for established
connections and for closed ports, but for the most part we don't need to
see them.

Logtcpwin was unused, so I just replaced it.  I also added a 'verbose'
category, which I'll use for some extremely common logs.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agonet: Add timestamps to the netlog
Barret Rhoden [Wed, 12 Jul 2017 18:00:27 +0000 (14:00 -0400)]
net: Add timestamps to the netlog

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agonet: tcp: Be explicit about the max Window Scale
Barret Rhoden [Mon, 26 Jun 2017 16:39:30 +0000 (12:39 -0400)]
net: tcp: Be explicit about the max Window Scale

RFC 7323

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agonet: tcp: Advertise support for SACK
Barret Rhoden [Tue, 20 Jun 2017 19:58:40 +0000 (15:58 -0400)]
net: tcp: Advertise support for SACK

TCP Selective Acknowledgment.  We don't do anything with it yet.  We can
disable it at compile time (change SACK_SUPPORTED) if our support breaks
anything.  We can also add run-time support in the future.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agonet: tcp: Remove the Syn_received state
Barret Rhoden [Tue, 20 Jun 2017 19:05:18 +0000 (15:05 -0400)]
net: tcp: Remove the Syn_received state

I think Presotto's note was right: you should send a reset.  The situation
is when we sent a SYN, then we receive a SYN without an ACK.  That was the
only time we'd set Syn_received, and a reset is safer.  I think.

It also removes a bunch of code that pretty much never runs, except during
exceptions/attacks.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agonet: tcp: Support TCP timestamps
Barret Rhoden [Mon, 19 Jun 2017 19:40:00 +0000 (15:40 -0400)]
net: tcp: Support TCP timestamps

We don't do anything with the info yet - we just add them and respond to
them.  This helps our distant end with various things.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agonet: tcp: Refactor TCP6 and 4 common code
Barret Rhoden [Mon, 19 Jun 2017 19:22:36 +0000 (15:22 -0400)]
net: tcp: Refactor TCP6 and 4 common code

htontcp{4,6} and ntohtcp{4,6} have a lot of duplicate code.  This commit
pulls out the common option and block allocation code.  We might be able to
do something with checksum offload and other bits in the future.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agonet: tcp: Fix memory leak with tcpackproc
Barret Rhoden [Mon, 19 Jun 2017 18:40:01 +0000 (14:40 -0400)]
net: tcp: Fix memory leak with tcpackproc

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agonet: tcp: Account for TCP options when using MSS
Barret Rhoden [Mon, 19 Jun 2017 18:22:46 +0000 (14:22 -0400)]
net: tcp: Account for TCP options when using MSS

The advertised MSS reflects the MTU of the host.  It is the largest packet
we'll send out, not including MAC, default IP, and default TCP headers.  If
we have extra TCP options, like the timestamps or SACKs, then those bytes
count against the advertised MSS.

We have a couple uses of the MSS.  The typical_mss is used for cwnd
calculations - it's the amount of data (not options) we expect to send.
The payload_mss is the actual amount we send for a given packet.  This may
vary since some options are only added to some packets for a given stream.

This wasn't a problem before since we only sent TCP opts on SYN or SYN/ACK
packets, which weren't close to the MSS.  We don't use this feature in this
commit, but we will shortly.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agonet: tcp: Always set the retrans timer
Barret Rhoden [Mon, 19 Jun 2017 18:06:53 +0000 (14:06 -0400)]
net: tcp: Always set the retrans timer

The check was for the largest possible packet.  With TSO, we send a lot of
different packet sizes, so the largest-packet check doesn't make as much
sense.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agonet: tcp: Adjust the transmit queue limit
Barret Rhoden [Mon, 19 Jun 2017 15:18:37 +0000 (11:18 -0400)]
net: tcp: Adjust the transmit queue limit

If we don't grow the queue limit as the cwnd grows, TCP blocks on waiting
for more data from the user.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agonet: tcp: Fix cwnd and ssthresh for TSO and Reno
Barret Rhoden [Wed, 14 Jun 2017 19:22:21 +0000 (15:22 -0400)]
net: tcp: Fix cwnd and ssthresh for TSO and Reno

RFC 5681 suggests the ssthresh initially be arbitrarily high.  Older RFCs
suggested the old value of 64K.  This is the cutoff where slow-start stops
and we enter the congestion avoidance.

The cwnd (congestion window, managed by the sender) has been suggested to
start at 10 * MSS, instead of 1.  (https://lwn.net/Articles/427104/).

Also, we weren't growing our cwnd properly.  For every ACK, we'd increase
it by MSS.  That assumes an ACK only consists of one MSS (or less).  We
were handling the 'or less' case, but if an ACK covered 10 MSS, we'd only
advance by 1 MSS.  This is possible when using TSO.

If 'expanded = acked' seems too simple, consider we'd want this:

expanded = (acked / MSS) * MSS + acked % MSS;

which is just

expanded = acked;

Similarly, we weren't accounting for large packets during the congestion
avoidance phase.

Finally, I used the Reno algorithm for adjusting ssthresh and cwnd when we
have a loss.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agokprof: Allow clearing the kptrace buffer
Barret Rhoden [Tue, 11 Jul 2017 15:10:26 +0000 (11:10 -0400)]
kprof: Allow clearing the kptrace buffer

This also adds a slimmed down version of dmesg, which also supports -c.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoqio: Allow changing limits dynamically
Barret Rhoden [Mon, 19 Jun 2017 15:03:33 +0000 (11:03 -0400)]
qio: Allow changing limits dynamically

The queue's limit is the point at which writers get blocked.  Specifically,
they block once the qlen crosses the limit - the actual write succeeds.

The tricky bit is that if you increase the limit, some writers may become
unblocked.  Similarly, the queue may become writable, which requires us to
fire a tap.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoRemove the #define exit() _exit() hack (XCC)
Barret Rhoden [Thu, 8 Jun 2017 21:14:49 +0000 (17:14 -0400)]
Remove the #define exit() _exit() hack (XCC)

The atexit handlers might do dangerous things that can't be done in vcore
context.  The old note mentioned yielding, which we could work around, but
other handlers can block too. (confirmed by testing).

So we retain the "exit -> _exit" behavior for vcore context, but not for
uthreads.  Importantly, the change is done in glibc, instead of macro
nastiness.  This popped up when someone wanted to call a function pointer
named 'exit.'

Fun tidbit, this hack might have predated threads.  It came in less than a
week after the first pthread scheduler commit.

Rebuild glibc.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agomlx4: Fix NAPI polling
Barret Rhoden [Mon, 26 Jun 2017 16:26:12 +0000 (12:26 -0400)]
mlx4: Fix NAPI polling

I triggered this by trying to send a lot of packets at once, specifically
by removing the kthread_yield() from tcp.c.  When we poll and exceed the
budget, in Linux the NAPI code will call the poll function again.  We
weren't, and we weren't rearming the NIC's TX IRQ.  Then we'd never be able
to send another packet, since the transmit ring would always be full.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agomlx4: Fix transmit flow control and concurrency
Barret Rhoden [Thu, 22 Jun 2017 20:16:31 +0000 (16:16 -0400)]
mlx4: Fix transmit flow control and concurrency

We had no way to put backpressure on the network stack, and if you sent
packets fast enough, you'd overflow the NIC's TX queues, and get a "CQ
overrun".

Also, I noticed we had no protection for concurrency.  If we had two
concurrent transmitters, they would fight for slots in the ring.  The worst
I could come up with was one flow could get another's payload (consider
TSO'd packets, but someone else's packet replaces one of your frags).
That'd be another nightmare to debug.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoReplacing timer support for VM Guests (XCC)
Gan Shun [Tue, 11 Jul 2017 21:52:10 +0000 (14:52 -0700)]
Replacing timer support for VM Guests (XCC)

The old vm timer was a single thread that poked at all cores regardless
of the actual time the guest set the alarm for.

The new timers use the parlib alarm infrastructure, and actually sets up
independent timers for all cores so that we can properly emulate per-core
lapic timers.

Reinstall your kernel headers

Change-Id: I05bddbfb93b8ad62078e688175b54917b151cfaf
Signed-off-by: Gan Shun <ganshun@gmail.com>
[used gth_to_vmtf(), XCC warning]
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoRemove MWAIT functionality from the VM guest.
Gan Shun [Tue, 11 Jul 2017 21:14:04 +0000 (14:14 -0700)]
Remove MWAIT functionality from the VM guest.

Turns out linux uses MONITOR/MWAIT to wake up AP cores when they have
work. We don't support proper MONITOR/MWAIT for VM guests so our only
solution right now is to turn it off.

Turns out this is the reason SMP VM guests were slow. The issue wasn't
the timer at all, but my old implementation of the timer covered up the
bug as I rammed every core with timer interrupts. That masked the fact
that guest cores were waiting on some address that we never actually
monitored.

Signed-off-by: Gan Shun <ganshun@gmail.com>
Change-Id: Ie21f8137aa2ec2312f907b8fd4b6c9685fdf5a9d
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agovmm: Modifed load_elf to allow an offset
Zach Zimmerman [Fri, 30 Jun 2017 22:36:36 +0000 (15:36 -0700)]
vmm: Modifed load_elf to allow an offset

Change-Id: I897abff7b8bcbcaf9743eeed51d67da9a09a0afc
Signed-off-by: Zach Zimmerman <zpzim@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agodune: gettimeofday fix
Zach Zimmerman [Fri, 30 Jun 2017 22:05:58 +0000 (15:05 -0700)]
dune: gettimeofday fix

Change-Id: I5c14e66d7055c05b4838c8e3b1b7815fef8350bc
Signed-off-by: Zach Zimmerman <zpzim@google.com>
[minor formatting]
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agodune: working test with emulated syscalls
Ronald G. Minnich [Mon, 21 Nov 2016 22:09:46 +0000 (14:09 -0800)]
dune: working test with emulated syscalls

Dune is working with dune_test as a vm to test vmcall functionality

Change-Id: Iead546ccfb405519db525f4e5b81a1bb1e647517
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Signed-off-by: Zach Zimmerman <zpzim@google.com>
[minor formatting, removed redundant #defines for MiB and MinMemory]
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoAdding .travis.yml
Gan Shun [Wed, 14 Jun 2017 17:22:08 +0000 (10:22 -0700)]
Adding .travis.yml

This allows us to test automated builds on travis, and the results are
sent to akaros-travis@googlegroups.com

Signed-off-by: Gan Shun <ganshun@gmail.com>
Change-Id: I87e216346da0d99e67e428c4f056c67a904f96be
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoReduce verbosity of some make commands
Gan Shun [Fri, 9 Jun 2017 20:32:18 +0000 (13:32 -0700)]
Reduce verbosity of some make commands

Redirect the outputs of the toolchain build to
tools/compilers/gcc-glibc/build_logs and the outputs of make
apps-install and apps-clean to $AKAROS_ROOT/build_logs

This change also fixes a bug in unsetting multiline environment
variables.

Signed-off-by: Gan Shun <ganshun@gmail.com>
Change-Id: Iac496c3e01853e6e97f31345a86256ce7b2c1284
[for apps-targets, changed 'info' -> 'echo']
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoModify adt to use symbolic-ref
Gan Shun [Thu, 8 Jun 2017 21:35:04 +0000 (14:35 -0700)]
Modify adt to use symbolic-ref

Signed-off-by: Gan Shun <ganshun@gmail.com>
Change-Id: I941e805029753bf543a0f75876f3bbe4e32de7de
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoefence: clang-format
Barret Rhoden [Tue, 6 Jun 2017 21:13:50 +0000 (17:13 -0400)]
efence: clang-format

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoefence: Fix it all and add a test
Barret Rhoden [Tue, 6 Jun 2017 20:54:01 +0000 (16:54 -0400)]
efence: Fix it all and add a test

To use it, link with -lelectric-fence.  You can do this from your top-level
Makelocal.  e.g. CFLAGS_USER or _TESTS += -lelectric-fence.

This doesn't support C++.  For that, we can look into libduma or something.

The biggest pain was that gcc was optimizing away internalUse and other
flag variables.  That's because it knows about malloc(), but doesn't know
that we are overriding it.  So we have to disable that optimization.

The other thing was locking: first off, our trylock returns a bool (TRUE or
FALSE), not an int (0 or 1).  Second, malloc and free are called from vcore
context, so we can't use a mutex.  Much like with Glibc's malloc lock, we
need to use spin_pdr locks.  Finally, we need to lock inside memalign, not
in the outer functions.  Specifically, someone could be calling memalign
directly and be unprotected.  There's nothing in malloc/calloc/valloc/etc
that needs to be protected.

I also added wrappers for functions like posix_memalign(), and removed the
obnoxious version printing.  I removed tstheap, put its guts in one of our
utests, and added a test for catching faults.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoelectric-fence: builds and boots
Ronald G. Minnich [Wed, 31 May 2017 17:00:14 +0000 (10:00 -0700)]
electric-fence: builds and boots

tstheap fails:

Unhandled user trap from early SCP

in uthread_yield, some other dumb mistake I'm making.

Change-Id: Ib1428dcb2a8c1984352e2adc4c8dea050d497e48
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoelectric-fence: changed Makefile to Akaros style
Ronald G. Minnich [Tue, 30 May 2017 15:19:23 +0000 (08:19 -0700)]
electric-fence: changed Makefile to Akaros style

Change-Id: I3a8e699c4aadd4e12f13efb0de06f3410e42bc53
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoelectric fence: initial checkin
Ronald G. Minnich [Tue, 30 May 2017 15:17:30 +0000 (08:17 -0700)]
electric fence: initial checkin

This is from git@github.com:CheggEng/electric-fence
commit 7199c87ec6df05cff6b0faa0b7114b02b53dffe1

I did not include the debian/ directory.

Change-Id: If8a24910791fc469f4c51734cfc98471829f78d3
Signed-off-by: Ronald G. Minnich <rminnich@gmail.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agovmm: Fix use-after-free in load_elf()
Barret Rhoden [Tue, 6 Jun 2017 19:45:57 +0000 (15:45 -0400)]
vmm: Fix use-after-free in load_elf()

elf_end() frees various structures, so you can't access ehdr anymore.  This
was caught by electric fence.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoRemove pthread_lib_init() declaration
Barret Rhoden [Tue, 6 Jun 2017 19:45:26 +0000 (15:45 -0400)]
Remove pthread_lib_init() declaration

The function went away a month or two ago.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoFix a deadlock in mprotect()
Barret Rhoden [Fri, 2 Jun 2017 00:19:48 +0000 (20:19 -0400)]
Fix a deadlock in mprotect()

We wouldn't make forward progress if you tried to mprotect() a region
that already had those protections.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agomlx4: Support TSO/GSO/LSO
Barret Rhoden [Tue, 6 Jun 2017 17:01:42 +0000 (13:01 -0400)]
mlx4: Support TSO/GSO/LSO

The changes were taken from the Linux transmit function.  I added back in
the 'linear' checks (meaning, is there data in the block main body),
ignored the 'inline' stuff, and turned on LSO (a.k.a. TSO/GSO).

Also, there was a bug with the xsum flags.  Bipck is never set by the
stack, so we weren't setting a flag that Linux always sets.  We do the IP
header xsum in software - it's just 20 bytes.  However, the Bipck flag is
used by drivers to tell the stack that the NIC did the IP header xsum.
That's just the way it works for Plan 9.  This all popped up because LSO'd
packets had incorrect header xsums.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agonet: Add accounting to help TSO/LSO/GSO
Barret Rhoden [Fri, 2 Jun 2017 22:21:44 +0000 (18:21 -0400)]
net: Add accounting to help TSO/LSO/GSO

The NIC will need to know how big the transport headers are.  The easiest
way is to just have the protocol tell us.  I used the same style as the
checksum_start, where we track the relative value from bp->rp.

Note that although I track the transport_header_end in UDP, we don't have
UDP GSO support elsewhere in the stack.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoparlib: Expand our printf hacks
Barret Rhoden [Fri, 26 May 2017 19:23:46 +0000 (15:23 -0400)]
parlib: Expand our printf hacks

The hacked versions of printf() now return values and have a vfprintf()
variant.  Dropbear needed these.

Unfortunately, anyone who tries to printf from signal handlers, which are
currently executed in vcore context for IPC, will need to manually #include
<parlib/stdio.h>.  We might be able to get the regular stdio.h to include
it, but my feeble attempts couldn't get the toolchain to build.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agonet: Add a function to dump TCP's hash table
Barret Rhoden [Fri, 26 May 2017 19:22:00 +0000 (15:22 -0400)]
net: Add a function to dump TCP's hash table

Kfunc this from the monitor.  This was useful debugging failed TCP
connections.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoAdd a test for partial writes
Barret Rhoden [Fri, 26 May 2017 18:26:58 +0000 (14:26 -0400)]
Add a test for partial writes

This will catch the qio and Inferno rwrite() bugs.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoqio: Track the amount of bytes read
Barret Rhoden [Fri, 26 May 2017 16:49:33 +0000 (12:49 -0400)]
qio: Track the amount of bytes read

This was useful for debugging.  You can see the amount of bytes via 'pip'.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoqio: Fix potential memory leak in __qbread()
Barret Rhoden [Fri, 26 May 2017 16:41:11 +0000 (12:41 -0400)]
qio: Fix potential memory leak in __qbread()

The race could happen where we __try_qbread(), see we need a spare to split
the first block, but when we go in the next time the queue is empty or some
other condition that triggers an error().

Like with __qwrite(), only some callers are allowed to use waserror and
throw, so we need to be careful about when we do the error unwinding.

Also, for whatever reason, we need these volatiles when dealing with
waserror().  I checked the ASM again, and the compiler will not realize
that 'spare' could have changed, despite the "returns twice" attribute
deeper in waserror().

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoqio: Report partial progress for NONBLOCK queues
Barret Rhoden [Thu, 25 May 2017 20:10:45 +0000 (16:10 -0400)]
qio: Report partial progress for NONBLOCK queues

__qbwrite() can throw for many reasons, including EPIPE (closed queue),
EAGAIN (full for now), and EINTR (syscall aborted).  However, large
qwrites, meaning greater than Maxatomic, get broken into several block
writes.  Some could succeed before we catch the error, and we need to
report those successes as a partial write.

To make things a little trickier, __qwrite() is only allowed to throw based
on its qio flags.  Other times waserror() might be dangerous, such as in
irq context.

This came up by writing large blocks to a non-blocking pipe.  The writer
thought that none of the write made it, so it kept writing the same blocks
over and over.  However, each time the first block (at least) was actually
written.  The reader received that first block over and over.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoFix Plan 9 partial write() return values
Barret Rhoden [Thu, 25 May 2017 20:07:33 +0000 (16:07 -0400)]
Fix Plan 9 partial write() return values

We were returning the value that the user attempted to write, not the
amount that actually made it.

Note that the proper way for a device to return -1 is to throw an error(),
which we catch in rwrite().  If a device's write method actually returns
-1, that'll screw things up.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agonet: Improve a few netlogs
Barret Rhoden [Tue, 23 May 2017 18:09:53 +0000 (14:09 -0400)]
net: Improve a few netlogs

The ICMP and TCP log messages were a little sparse.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agonet: Support connects to 0.0.0.0
Barret Rhoden [Tue, 23 May 2017 18:07:48 +0000 (14:07 -0400)]
net: Support connects to 0.0.0.0

In Linux, 0.0.0.0 is translated to mean "this machine."  We can do the
same.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agomlx4: Advertise that the NIC pads to mintu
Barret Rhoden [Tue, 23 May 2017 18:00:58 +0000 (14:00 -0400)]
mlx4: Advertise that the NIC pads to mintu

The minimum ethernet packet is 60 bytes.  A TCP/IP packet with no options
and no data is 40 bytes.  The ethernet MAC is 14 bytes.  The extra 6 bytes
need to come from somewhere.

Some NICs will pad those bits in hardware, including the mlx4.  If we pad
them in software, the NIC can get confused.  This showed itself as TCP ACKs
with bad checksums when we used checksum offload.  The NIC computed a value
that was off by 6 - the size of the padding.  Not sure why, exactly.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agox86: Get the boot time from CMOS
Barret Rhoden [Wed, 10 May 2017 19:46:57 +0000 (15:46 -0400)]
x86: Get the boot time from CMOS

We read this once at boot.  All future time checks should be based on the
walltime_ns_last.  One of these days, we'll update that field when we get
info from e.g. NTP.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoSet the hostname, if provided, from ifconfig
Barret Rhoden [Wed, 10 May 2017 18:01:05 +0000 (14:01 -0400)]
Set the hostname, if provided, from ifconfig

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agox86: Fix KERNBASE mapping for > 512 GB RAM
Barret Rhoden [Wed, 10 May 2017 15:36:46 +0000 (11:36 -0400)]
x86: Fix KERNBASE mapping for > 512 GB RAM

The mapping was setting PTE_W, but not PTE_P.  This would have caused
faults whenever we tried to access those pages, which would have been
really nasty to track down.  I found this because of the panic in
__pte_to_epte_perm() (wasn't expected PTE_W only).

To be more clear in the code, we should be setting PTE_KERN_RW, which is
PTE_W | PTE_P.  Same goes for the VPT/UVPT mapping.  Those latter changes
were just in the naming of the flags.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoparlib: Write to FD 2 for akaros_printf()
Barret Rhoden [Thu, 4 May 2017 18:48:15 +0000 (14:48 -0400)]
parlib: Write to FD 2 for akaros_printf()

And be a little more careful with snprint().

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoFix getifaddrs (XCC)
Barret Rhoden [Thu, 4 May 2017 18:44:58 +0000 (14:44 -0400)]
Fix getifaddrs (XCC)

There were a bunch of problems.  First, there was a buffer overflow with
the etheraddr, which was being used for the pathname.  That always went
over.  Second, the for loop for freeing the ifaddrs was wrong, since it'd
access ifa->ifa_next after ifa was freed.

Next up, it wasn't reporting the ethernet address in a way that anyone knew
to look for, and it didn't support IP addresses.

All of that should work now, though I didn't test IPv6.

Rebuild glibc.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoAdd syscall tracing support to 'path' calls
Barret Rhoden [Wed, 3 May 2017 17:24:42 +0000 (13:24 -0400)]
Add syscall tracing support to 'path' calls

Syscalls like openat() already had their path argument added to the data
blob, but others like stat() and access() didn't.  I added support for all
of the syscalls that take path arguments.  This required adding a couple
helpers for building the trace data payload.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoFix snprintf() overflow issues
Barret Rhoden [Wed, 3 May 2017 16:25:08 +0000 (12:25 -0400)]
Fix snprintf() overflow issues

snprintf() is a pain.  Taking a 'negative' number for consecutive calls
after an overflow is a common pattern: see netif.c (derived from Plan 9)
and mlx4/mcg.c (from Linux).  We had been taking an int for the size, but
ought to be taking a size_t - if for nothing else than to make the change
now *and* adding the check, instead of later without the check.

On a similar note seprintf() was using its return value incorrectly.  The
uses of seprintf() seemed ok, since no one used "buf + rc" for anything
other than 'start' for another seprintf() call.  We could have seprintf()
do the same thing as snprintf(), but it seems a little dangerous to return
a pointer outside the [start, end) range.

One thing to remember is that if seprintf()/snprintf() overflowed, we
probably don't have a null-terminated buffer.  Some of our call sites might
not like that.

Similarly, the logic in parlib for detecting overflow was just wrong.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agopthreads: Remove sched_policy and sched_priority
Barret Rhoden [Fri, 28 Apr 2017 19:19:10 +0000 (15:19 -0400)]
pthreads: Remove sched_policy and sched_priority

We never actually supported this - we just faked it.  We'll continue to
fake it, but won't track the faked values in the thread struct.

If it turns out that the pthreads interface is the best way for apps to
influence a 2LS, then we can hook these functions up to real 2LS ops.
Until then, we'll go with the "application-specific" nature of the 2LS,
where the 2LS itself is made to work with a particular app.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agopthread: Make pthread barriers 2LS-independent
Barret Rhoden [Fri, 28 Apr 2017 16:36:44 +0000 (12:36 -0400)]
pthread: Make pthread barriers 2LS-independent

This is one step towards making pthreads a generic API that can be used
when *any* 2LS is used.  Long term, we'll need that so library code can
make pthread calls (e.g. pthread_create(), pthread_mutex_lock(), etc.) and
access the real 2LS.  The alternative is porting every POSIX library that
wants to grab a thread.

Thanks to the previous commits, we're able to swap in uthreads for pthreads
and use sync object with bulk wakeups directly.  The first couple
implementations of this didn't have bulk wakeups or called
uthread_has_blocked() while holding the barrier's lock.  Both of those
noticeably hurt performance.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoparlib: Add a thread_bulk_runnable() 2LS op
Barret Rhoden [Fri, 28 Apr 2017 16:31:29 +0000 (12:31 -0400)]
parlib: Add a thread_bulk_runnable() 2LS op

If the 2LS knows it is waking up N threads, it can make better decisions or
otherwise perform better.  This gives us a 3x improvement on
pthread barriers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoparlib: Add __uth_sync_swap and __uth_sync_is_empty
Barret Rhoden [Fri, 28 Apr 2017 16:14:19 +0000 (12:14 -0400)]
parlib: Add __uth_sync_swap and __uth_sync_is_empty

These are helper methods, useful for bulk wakeups.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoparlib: Tease out uth_sync_t from has_blocked()
Barret Rhoden [Fri, 28 Apr 2017 16:05:29 +0000 (12:05 -0400)]
parlib: Tease out uth_sync_t from has_blocked()

Some callers of uthread_has_blocked() might want to separate the blocking
on the sync from the notification to the 2LS - even though both of those
are 2LS ops.

The specific case is pthread_barriers (in an upcoming patch).  There, we
have an optimization where we don't hold the spinlock across
uthread_yield(), and instead reacquire it and double-check if we should
block.  In that case, we'd rather call the 2LS has_blocked *before*
grabbing the barrier's spinlock (> 25% performance improvement).  Other
sync primitives might want to do the same.

Overall, this is probably a better fit - it removes those has_blocked cases
that take NULL and provides a little more flexibility to the sync primitive
code.  It also gets rid of the slightly ugly __uth_default_sync_enqueue()
and provides a nicer sync object interface.  The downside is that the 2LS
gets its has_blocked info independent of the source of the blocking.
Probably doesn't matter.

Similar to the commit 'Make sync objects static', I considered rebasing
this change, but I didn't want to break git bisect or otherwise introduce
hard-to-debug problems, which I've already had a few of due to the
toolchain changes.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agopthread: Reimplement mutexes, CVs, and RW locks (XCC)
Barret Rhoden [Thu, 27 Apr 2017 19:19:13 +0000 (15:19 -0400)]
pthread: Reimplement mutexes, CVs, and RW locks (XCC)

Pthreads had its own older code.  Now, we just use the uthread code.  It's
mostly straightforward, except that pthread mutexes have a type that
determines whether or not they are recursive or not.

I also moved some of the older support code around, like spin_to_sleep().
That's still used by the barrier code.

If applications want to spin before sleeping on mutexes (adaptive mutex /
brewtexes), they can use their own primitives.  On a related note, if your
context switch overhead is lower, then lure of spinning isn't as strong,
and spinning deprives the 2LS of a scheduling opportunity.

Rebuild your toolchain.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoparlib: Make uth mutex/CV initializers C++ safe (XCC)
Barret Rhoden [Thu, 27 Apr 2017 19:11:53 +0000 (15:11 -0400)]
parlib: Make uth mutex/CV initializers C++ safe (XCC)

GCC C++ can't handle { { .field = value } }.  It can handle one {}, but not
two.  C doesn't have this problem.  The issue comes up when someone does
something like:

struct my_struct {
uth_mutex_t foo;
}
#define MY_INITIALIZER {UTH_MUTEX_INIT}

icu does this with their umutex.h implementation.  There it is for
pthreads.

For us, we can get away with the non-specific initializers, so long as we
put the parlib_once_t first.

Rebuild your toolchain.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoparlib: Add a rwlock test
Barret Rhoden [Thu, 27 Apr 2017 16:30:50 +0000 (12:30 -0400)]
parlib: Add a rwlock test

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoOverhaul glibc locking (XCC)
Barret Rhoden [Wed, 26 Apr 2017 19:18:49 +0000 (15:18 -0400)]
Overhaul glibc locking (XCC)

Previously, we were using the low-level locks (spin_pdr_locks) for almost
everything in glibc.  The libc_lock was a spinlock, etc.  It turns out, the
libc_lock is supposed to be a mutex.

I had a couple cases where the app would yield while holding a libc_lock,
which you cannot do if it is a spinlock.  Specifically, this happened when
calling fclose() on a FILE (holding the old libc_lock), which closed the
underlying FD, when we were using epoll.  The epoll close callback grabs a
uthread mutex.  The fix is to make the libc_lock a uthread mutex too.  No
problem, right?

The problem was malloc was also using those locks, and vcore context calls
malloc and free.  Vcore context code cannot use mutexes.  So our options
were either never to call malloc or free from vcore context, or to use a
different type of lock.  So far, we can get by with malloc using
spin_pdr_locks (the low-level lock (LLL)).

This all does mean that vcore context code cannot call some things from
glibc, such as close(), printf(), or anything using the libc_lock (a
mutex), including the _IO_lock (which is now explicitly a libc_lock (mutex)
and not a spinlock).  Currently, that includes interprocess signal
handlers, which are run from vcore context.  fprintf() to stderr and stdout
will work, but some other signal-safe functions might not.  close() doesn't
work, not because of the libc_lock (fclose() grabs that, not close()), but
because of the close callbacks, which *do* grab mutexes.  And you can't
grab a mutex from vcore context.

There are a few other implications.  malloc() (using a spinlock) relies on
sbrk(), which previously was a libc_lock.  That now needs to be a spinlock.
It is possible for the kernel to block the mmap() call.  If that happens,
userspace will spin until the call completes.  Oh well.

I also sorted out the rtld locks.  Previously, we were doing nothing for
the recursive locks.  If we had threads racing in dlopen(), then we could
corrupt the various data structures in ld.  Yikes!  There might be issues
with those locks still.  I made them spinlocks, since we can't access
parlib objects at all in that code.  (We can access headers).

Now that rtld isn't using the libc_locks, we no longer have anyone calling
into parlib-compat.c's spinlocks, and we can replace that thread-unsafe
code with asserts.

There's probably a few problems with all of this still.  For instance,
maybe we an do something different for ld.so compared to libdl.so.  Who
knows.  At least it's a little better than before.

Rebuild glibc.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoparlib: Make parlib printfs safe
Barret Rhoden [Tue, 25 Apr 2017 17:40:38 +0000 (13:40 -0400)]
parlib: Make parlib printfs safe

You can't call glibc's printf from certain contexts: notably vcore context
or when a uthread disabled notifications.  If you do, you'll grab a mutex
in glibc (the IO lock, which is changing in an upcoming patch), and we'll
panic - you can't block in those contexts.

But there's no need to manually call __vc_ctx_fprintf() - we can catch it
with a macro.  Yes, it's nasty.  And it works for both printf() and
fprintf(), but only for stdout and stderr streams.

Also, for this to work, any code that could be called from vcore context
should include parlib/stdio.h, not stdio.h.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
2 years agoHave all asserts call parlib's assert (XCC)
Barret Rhoden [Tue, 25 Apr 2017 17:20:17 +0000 (13:20 -0400)]
Have all asserts call parlib's assert (XCC)

Now all calls to assert() will print the same info and have a backtrace,
regardless of whether or not you included parlib/assert.h.

Rebuild glibc.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>