4 years agoConvert omode to 9p for devmnt [4/7]
Barret Rhoden [Tue, 15 Sep 2015 16:15:22 +0000 (12:15 -0400)]
Convert omode to 9p for devmnt [4/7]

9p expects the mode to match a format similar to POSIX, based on
http://man.cat-v.org/plan_9/5/open.  Since Akaros allows O_EXEC to be
or-ed with READ and WRITE, but 9p doesn't, we just treat O_EXEC as
O_READ for purposes of the conversion.

Note that we cannot express "no I/O permissions" across 9p.

4 years agoProperly convert open mode flags to rwx [3/7]
Barret Rhoden [Thu, 3 Sep 2015 22:32:03 +0000 (18:32 -0400)]
Properly convert open mode flags to rwx [3/7]

Plan 9's devpermcheck hard-coded the fact that O_RDONLY was 0 into its
"access" array.  It also didn't seem to deal with O_EXEC being OR-ed
into the flags, such that you could only have an 'x', not anything else.

The helper for this conversion is also useful in the VFS.

4 years agoSpecify a permission for do_file_open() [2/7]
Barret Rhoden [Thu, 3 Sep 2015 22:04:54 +0000 (18:04 -0400)]
Specify a permission for do_file_open() [2/7]

We had been getting away with passing 0, even though we needed at least
readable permission.

4 years agoMake O_RDONLY non-zero (XCC) [1/7]
Barret Rhoden [Thu, 3 Sep 2015 21:17:59 +0000 (17:17 -0400)]
Make O_RDONLY non-zero (XCC) [1/7]

O_RDONLY had the value of 0, which caused two problems.  A minor one was
that it was hard to check for readability or read-only-ness.  Another
was that it was impossible to have an FD that had no permissions.  You
were at least readable.  This was blocking some of our future plans.

As far as whether or not O_RDONLY must be zero:


In historical implementations the value of O_RDONLY is zero.
Because of that, it is not possible to detect the presence of
O_RDONLY and another option. Future implementations should
encode O_RDONLY and O_WRONLY as bit flags so that:


So it looks like we're on solid ground.  Internally, we can refer to
O_RDONLY as O_READ too, since it's a little weird to say RDONLY |
WRONLY, since then they aren't "only."

This compiles, but you'll have runtime issues with the kernel.  The
following patches in the 5-patch series will fix those issues.

Rebuild the world.

4 years agoProvide support for epoll
Barret Rhoden [Mon, 31 Aug 2015 03:14:45 +0000 (23:14 -0400)]
Provide support for epoll

We have rough support for epoll, built on top of FD taps, CEQs, and
uthreads blocking on event queues.

There are several outstanding issues, listed at the top of epoll.c.
I'll deal with them on a FCFS basis, based on which ones are actually
problems.  Things like growing the epoll set probably aren't too hard.
Things like epolling on an epoll (or other user FD) or closing an epoll
and dealing with INDIRs are probably harder.  (The latter seems like a
huge pain).

4 years agoMove register_evq to event.c
Barret Rhoden [Mon, 31 Aug 2015 03:08:23 +0000 (23:08 -0400)]
Move register_evq to event.c

Although it was originally used for uthread libraries when blocking
threads on syscalls, it's not particular to uthreads.

4 years agoImplement kthread_usleep() with a rendez
Barret Rhoden [Fri, 28 Aug 2015 20:55:05 +0000 (16:55 -0400)]
Implement kthread_usleep() with a rendez

kthread_usleep() is the underlying call for sys_block().  Using a rendez
here allows userspace to abort sys_block() syscalls.  Recall that we can
abort rendezes, but not arbitrary semaphores.

4 years agoHave rendez_sleep_timeout() take usec, not msec
Barret Rhoden [Fri, 28 Aug 2015 20:52:43 +0000 (16:52 -0400)]
Have rendez_sleep_timeout() take usec, not msec

This keeps the timeout more in line the alarm subsystem, which uses

4 years agoInstall Linux's epoll headers in glibc (XCC)
Barret Rhoden [Thu, 27 Aug 2015 20:52:34 +0000 (16:52 -0400)]
Install Linux's epoll headers in glibc (XCC)

Akaros can do epoll in userspace, though the .c files can't live in
glibc due to requiring parts of parlib and benchutil.

We use the same interface as Linux, so we can just use the same header.
bits/epoll.h is actually Linux's x86/bits/epoll.h, so if the packed
attribue causes trouble for RISCV, we can adjust it.

Rebuild glibc.

4 years agoAdd User FDs to glibc (XCC)
Barret Rhoden [Wed, 26 Aug 2015 21:11:31 +0000 (17:11 -0400)]
Add User FDs to glibc (XCC)

There are a bunch of Linux APIs that we can implement in userspace that
use FDs as a handle, e.g. epoll.  Eventually that handle gets passed to
close().  We need a way to intercept close() for these FDs.  It'd also
be nice to provide basic sanity checking too, so that if you pass the
wrong type of FD to something like epoll_ctl(), we can catch it.

User FDs are a chunk of reserved numbers in the space of FDs, used by
various userspace libraries that use FDs as their API.  The user FD
space starts where the kernel's leaves off.  Currently, the kernel
claims 19 bits of the 32 bit int for an FD.  The MSB flags whether it
is negative or not.  That leaves 12 bits for us.

Libraries just get an FD, which registers their struct user_fd.  Then
later they can lookup their user_fd for a given FD.  When the program
closes the fd, the user_fd's callback is called.

Rebuild glibc.

4 years agoMake backtraces more robust
Barret Rhoden [Fri, 28 Aug 2015 19:30:58 +0000 (15:30 -0400)]
Make backtraces more robust

It's always dangerous for the kernel to backtrace a user context, but it
is still useful.  On occasion, BTs will have bad, but not 0, frame
pointers.  This will crash the kernel.  Ensuring that the frame pointers
are at least in mmap-able space catches a bunch of these scenarios.

4 years agoFix syscall_async's signature
Barret Rhoden [Fri, 28 Aug 2015 19:32:27 +0000 (15:32 -0400)]
Fix syscall_async's signature

It's not actually returning anything.

4 years agoAdd I_AM_HERE to parlib
Barret Rhoden [Tue, 25 Aug 2015 18:47:09 +0000 (14:47 -0400)]
Add I_AM_HERE to parlib

It's incredibly useful, and took way to long to finally add it.

4 years agoExport NR_FILE_DESC_MAX to userspace (XCC)
Barret Rhoden [Thu, 20 Aug 2015 15:45:37 +0000 (11:45 -0400)]
Export NR_FILE_DESC_MAX to userspace (XCC)

Partitioning the FD space with NR_FILE_DESC_MAX will help userspace
emulate various Linux functions.  There's a class of facilities that we
can do in userspace, but expect to operate with the kernel via FDs.  For
instance, after an epoll_create(), you call close().  We'll need to
intercept that close() call in glibc and handle it accordingly.

Reinstall your kernel headers.

4 years agoAdjust the size of struct ucq (XCC)
Barret Rhoden [Wed, 19 Aug 2015 14:09:27 +0000 (10:09 -0400)]
Adjust the size of struct ucq (XCC)

The old one was taking up three cachelines.  A large part of it was the
u_lock, which was two cache lines on its own.  It used to be used for an MCS-PDR
lock, and very old versions of those were two cache lines.  Now it's a
spin-pdr lock.  Note that the size of spin-pdr depends on whether or not
CAS is supported.  We'll see how long that lasts (it was a RISC-V thing).

Reinstall your kernel headers and rebuild busybox.  The size change of
UCQ changed the size of the mbox and I needed to rebuild.  You probably
don't need to rebuild the toolchain.

4 years agoHook CEQs into the event infrastructure (XCC)
Barret Rhoden [Wed, 19 Aug 2015 13:53:46 +0000 (09:53 -0400)]
Hook CEQs into the event infrastructure (XCC)

CEQs are now an event mbox type.  You can get a basic one (128 elements)
when you get_eventq(), but if you want a different size (you probably
do), then you want a raw eventq and initialize it yourself.

Reinstall your kernel headers.  Probably don't need a compiler rebuild.

4 years agoAdd the CEQ mbox: Coalescing Event Queues (XCC)
Barret Rhoden [Wed, 19 Aug 2015 13:49:57 +0000 (09:49 -0400)]
Add the CEQ mbox: Coalescing Event Queues (XCC)

Coalescing Event Queues encapsulate the essence of epoll and kqueue in a
shared memory event mailbox: a dense array of stick status bits.

This commit adds the headers, producer, and consumer side of CEQs.

Reinstall your kernel headers.

4 years agoSpin with cpu_relax_vc() in BCQs (XCC)
Barret Rhoden [Tue, 18 Aug 2015 20:02:40 +0000 (16:02 -0400)]
Spin with cpu_relax_vc() in BCQs (XCC)

The consumer (user) is spinning on another vcore, which could be
preempted.  Whenever we wait on the user in vcore context, we need to
use cpu_relax_vc().

Reinstall your kernel headers.

4 years agoChange get_ucq_msg()'s return value to a bool
Barret Rhoden [Tue, 18 Aug 2015 19:55:11 +0000 (15:55 -0400)]
Change get_ucq_msg()'s return value to a bool

We're not passing any info with the -1, and it makes
extract_one_mbox_msg() nasty.

This is part of a general cleanup of the mailbox interface.

4 years agoAdd helpers to detect locked user spinlocks
Barret Rhoden [Tue, 18 Aug 2015 19:25:21 +0000 (15:25 -0400)]
Add helpers to detect locked user spinlocks

Similar to the kernel's functions.  I use these on the user side of

4 years agoMake user/vmm depend on parlib
Barret Rhoden [Tue, 18 Aug 2015 19:13:52 +0000 (15:13 -0400)]
Make user/vmm depend on parlib

vmm relies on parts of parlib.  Without this, a fast workstation could
build vmm concurrently and fail due to various changes in parlib not
being applied yet (e.g. header files).

4 years agoAdd parlib/common.h
Barret Rhoden [Tue, 18 Aug 2015 19:10:43 +0000 (15:10 -0400)]
Add parlib/common.h

Wrapper for ros/common.h, plus it has a few things of its own.  We need
to be somewhat careful about what goes in ros/common.h; I've had issues
in the past with things that aren't namespaced well that conflict with
various pieces of user-level software.

4 years agoRename event queue functions [2/2]
Barret Rhoden [Thu, 13 Aug 2015 17:40:47 +0000 (13:40 -0400)]
Rename event queue functions [2/2]

The common event queue is one with a mailbox, even if it is bigger.  So
the slim (no mailbox) is the special case.  Likewise, a raw eventq has a
mailbox, but the mailbox has not been initialized yet (used for UCQs and
later for CEQs).  And finally, the vcpd option remains a special case
(it's slim btw).

Nasty Awk for the function prototypes:

gsub(/get_event_q_vcpd/, "get_eventq_vcpd")
gsub(/get_event_q/, "get_eventq_slim")
gsub(/get_big_event_q_raw/, "get_eventq_raw")
gsub(/get_big_event_q/, "get_eventq")
gsub(/put_event_q_vcpd/, "put_eventq_vcpd")
gsub(/put_event_q/, "put_eventq_slim")
gsub(/put_big_event_q_raw/, "put_eventq_raw")
gsub(/put_big_event_q/, "put_eventq")

And spatch for the function calls.  I couldn't get spatch to change the









4 years agoReorganize event_queue helpers [1/2]
Barret Rhoden [Thu, 13 Aug 2015 15:43:22 +0000 (11:43 -0400)]
Reorganize event_queue helpers [1/2]

Moved them and added a "put" for the VCPD type, even though it's the
same as the slimmer ev_q put.

I'll rename all of these next patch.

4 years agoSpecify an mbox type when getting an event queue
Barret Rhoden [Wed, 12 Aug 2015 22:33:32 +0000 (18:33 -0400)]
Specify an mbox type when getting an event queue

This common helper allocates an event queue and initializes the mailbox.
As a stopgap, I was assuming it was a UCQ.  Let's let the caller decide.

Note that the thread0 scheduler doesn't actually need a UCQ.  It knows
what thread unblocked.  There probably are other testing functions that
don't care about UCQs vs bits, but it's not worth messing with them.

4 years agoRemove EVENT_NOMSG (XCC)
Barret Rhoden [Wed, 12 Aug 2015 22:12:35 +0000 (18:12 -0400)]

EVENT_NOMSG used to give you a bit in the bitmap instead of a UCQ
message.  Now that there are the evbitmaps, we don't want EVENT_NOMSG.
mhello and the other test aren't a big deal.  The simple_evq used by
glibc and by SCPs in VC ctx was a bigger deal, and needed to be
converted to the evbitmap mbox.

When removing the #define for NOMSG, I opted to change all the flags to
not leave a hole.  You need to rebuild the world anyway, so this doesn't

Rebuild the world.

4 years agoSplit ev_mbox into a union of mbox types (XCC)
Barret Rhoden [Wed, 12 Aug 2015 19:55:45 +0000 (15:55 -0400)]
Split ev_mbox into a union of mbox types (XCC)

Previously, an event mailbox consisted of a UCQ for messages with
payloads and a bitmap for the "NOMSG" events.  In general, we want to
support different types of mailboxes, with the functionality switched on
by type.

The rule is that all mboxes must know how to handle an event_msg, in an
mbox-specific manner.  For bitmaps, it's to just send the type.  If the
user screws up and loses the payload, that's on them.

There is one usage of NOMSG at the moment - the simple_evq.  What's
happening now is that the mbox is being treated as a UCQ, and in
early-scp context may eventually overflow if there are enough syscalls
before initializing the uthread library.

Also note that you can still do the 'raw' initialization of mailboxes.
For instance, with UCQs, you may want to do one big mmap for the UCQ
pages, instead of two mmaps per initialization.  You can still do this,
if you know you're dealing with a UCQ.

Rebuild the world.

4 years agoRemove EVENT_JUSTHANDLEIT (XCC)
Barret Rhoden [Wed, 12 Aug 2015 16:20:43 +0000 (12:20 -0400)]

The existence of ev_handler is a sufficient signal to override the
default ev_q handling.

Technically this is a kernel header change.  Feel free to ignore it.

4 years agoRemove the option to spawn_thread for an evq (XCC)
Barret Rhoden [Wed, 12 Aug 2015 16:08:47 +0000 (12:08 -0400)]
Remove the option to spawn_thread for an evq (XCC)

This is unused and unnecessary.  If an application wants a thread to
handle a message (and therefore in uthread context, which is what
spawn_thread provided), then just block a uthread on the event queue.
You don't need a 2LS op for that.

Technically this is a kernel header change.  Feel free to ignore it.

4 years agoAdd support for uthreads blocking on event queues
Barret Rhoden [Tue, 11 Aug 2015 21:12:44 +0000 (17:12 -0400)]
Add support for uthreads blocking on event queues

The generic problem is that we have M uthreads and want to block on a
subset of N event queues.  This is similar to Go's select call.  The
uthread will eventually return with a message from one of the queues.
In the case that multiple evqs fire before the uthread checks the
queues, it'll attempt to extract a message in the order the queues were

We do this by bypassing the default event handler, which means event
queues that are used for uthreads must be used exclusively for uthreads.
Though technically you can read from the mbox concurrently, a
handle_events() call won't handle any of the messages: that's up to the

4 years agoUse thread0_thread_has_blocked for syscalls
Barret Rhoden [Tue, 11 Aug 2015 19:49:34 +0000 (15:49 -0400)]
Use thread0_thread_has_blocked for syscalls

Using thread0_info.is_blocked is clearer than before, especially without
the blob hack.  Though it is slightly slower, due to the evq processing.
We could also send the evq to VCPD0, but this is fine.

4 years agoAllow thread0 uthreads to block
Barret Rhoden [Tue, 11 Aug 2015 19:17:20 +0000 (15:17 -0400)]
Allow thread0 uthreads to block

Thread0 uthreads could block on syscalls, but they couldn't block on
things like mutexes or other constructs that are outside the 2LS, such
as event queues.

The initialization of thread0_info from uthread_lib_init() could be done
statically, but we'll need this init function at some point.

4 years agoExport uthread_has_blocked()
Barret Rhoden [Tue, 11 Aug 2015 19:15:42 +0000 (15:15 -0400)]
Export uthread_has_blocked()

And make the existence of a 2LS op mandatory.  I was tempted to remove
this completely, but I like hiding the sched ops and enforcing that
there was a has_blocked op, just like with uthread_runnable() (it caught
a bug).

4 years agoDetach devalarm helpers from the user alarm tchain
Barret Rhoden [Tue, 11 Aug 2015 15:41:55 +0000 (11:41 -0400)]
Detach devalarm helpers from the user alarm tchain

The low-level helpers for devalarm were conflated with the user alarm
tchain service.

This way, someone can make their own #A alarm easily, without repeating
the "open a clone" dance and the other write() commands.

4 years agoAdd a helper to extract mbox messages
Barret Rhoden [Mon, 10 Aug 2015 20:28:37 +0000 (16:28 -0400)]
Add a helper to extract mbox messages

This hides the fact that we're using a UCQ from most of the code.
Later, we'll extract a message based on the type of mbox.

4 years agoAdd post-and-poke synchronization to parlib
Barret Rhoden [Sun, 9 Aug 2015 19:59:36 +0000 (15:59 -0400)]
Add post-and-poke synchronization to parlib

Adapted from the kernel's version.  You can use this in any user
context; no one ever actually waits on someone else.

4 years agoAdd ev_udata to struct event_queue (XCC)
Barret Rhoden [Sun, 9 Aug 2015 19:33:43 +0000 (15:33 -0400)]
Add ev_udata to struct event_queue (XCC)

This allows userspace to hook a blob of data on event queues.  I'll use
this shortly in parlib.

Reinstall your kernel headers.

4 years agoAllow all event queue functionality for SCPs (XCC)
Barret Rhoden [Tue, 4 Aug 2015 18:00:32 +0000 (14:00 -0400)]
Allow all event queue functionality for SCPs (XCC)

Previously, SCPs event delivery would be short-circuited.  Regardless of
where you wanted the event to go, we'd just spam it to vcore 0.  This
would bypass whatever ev_q you set up, including its mailbox and custom
handlers.  It worked if all you do is use a UCQ.

With this change, SCPs have full access to the ev_q functionality,
including INDIRs, spam requests, and wakeups.  Since SCPs are no longer
short-circuited, they need to use EVENT_WAKEUP to ensure they wake up
and receive the message, if that is desired.

Spamming works, e.g. for indirs or public messages; the message goes to
the only vcore: VC 0.  It's unnecessary for the common case.  If you use
an INDIR and WAKEUP, you'll wake up and see the INDIR in VC 0 - no need
to spam.  But code that is used for both MCPs and SCPs can safely use
EVENT_SPAM_* without worry.

Rebuild everything. (make xcc-upgrade-from-scratch)

4 years agoDifferentiate between EVENT_SPAM* and wakeup (XCC)
Barret Rhoden [Tue, 4 Aug 2015 21:14:23 +0000 (17:14 -0400)]
Differentiate between EVENT_SPAM* and wakeup (XCC)

Spamming is getting the message to some vcore that is guaranteed to
eventually receive the message (in a VCPD mbox).  Previously, this also
implied waking up the process.

This is slightly problematic, since spamming is tied to the VCPD mboxes.
If you want to wake up, you had to involve a VCPD mbox.  It ties the
wakeup to a *specific type* of mbox - in this case, the VCPD is a UCQ.
In the future, I'd like other mbox types, such as the "bitmap" type used
by the __ros_scp_simple_evq.

This commit splits the wakeup functionality into a new flag:
EVENT_WAKEUP.  Conceptually, it might be easier to follow the code this
way too.  Want a wakeup (from WAITING)?  Use EVENT_WAKEUP.

Almost all use cases that use some form of SPAM (public message or
indir) will also want a wakeup.  Maybe someone wants to be sure to hear
about something (spammed message), but don't care enough to wake up -
sort of a "if I happen to be running, I need to know FOO".

It's more plausible that an MCP could want a wakeup without the spam.
You could have a process-wide ev_q that was polled in a 2LS sched_entry.
There's no need for a spammed INDIR in this case.

Reinstall your kernel headers.

4 years agoHave make fill-kfs depend on tests
Barret Rhoden [Tue, 4 Aug 2015 17:54:28 +0000 (13:54 -0400)]
Have make fill-kfs depend on tests

Minor thing: this change brings 'tests' into line with 'install-libs' as
a dependency of fill-kfs.

If you did "make tests fill-kfs", you'd actually make tests twice,
concurrently.  Try touching tests/hello.c and running that command.

4 years agoRemove EVENT_SPAM_FLAGS (XCC)
Barret Rhoden [Tue, 4 Aug 2015 17:43:38 +0000 (13:43 -0400)]

The spam flags were meant to capture the options relevant to actually
sending / spamming messages.  This was a little messed up.

First, there is no real reason to filter out all of the flags.  It's not
like EVENT_FOOBAR is going to be misinterpreted.  This had the effect of
dropping EVENT_NOMSG, so if you tried to SPAM_PUBLIC a NOMSG, you
actually would spam a UCQ of that bit value!  Luckily, no one did this.

But there is a case where we don't want to pass all of the flags:
INDIRs.  When we spam an INDIR, we do not want to pass NOMSG.  We're
sending a new message, telling userspace to look at another ev_q.  The
distinction is that SPAM_PUBLIC sends the original message, while
SPAM_INDIR sends an indir message.  I considered making a
"EVENT_MSG_FLAGS", but it's just NOMSG, and I'm hoping to get rid of

Technically this changed a kernel header; feel free to ignore it.

Barret Rhoden [Mon, 3 Aug 2015 22:41:09 +0000 (18:41 -0400)]

"Fallback" was the original name for it, since it was the back-up plan
when a vcore was offline.  Once SPAM_PUBLIC came out, it was more clear
that it's really spamming an INDIR.  This came out of trying to explain
it: http://www.eecs.berkeley.edu/Pubs/TechRpts/2014/EECS-2014-223.pdf.

Other than comments and the rename, the only functional change is the
removal of a printk.  For now, it's possible to have an INDIR without
spamming the INDIR.  I have a couple half-baked use cases for it.

Reinstall your kernel headers (make xcc-install-headers)

4 years agoForce all conversations to have a write queue
Barret Rhoden [Mon, 3 Aug 2015 19:35:09 +0000 (15:35 -0400)]
Force all conversations to have a write queue

Some parts of #I seem to think that it is possible to not have a write
queue.  However, these checks are spotty.  For instance, there are calls
to qreopen(c->wq).  If there is no wq, that will PF.

It's up to the protocol to establish rq and wq.  All of our protocols
do.  If we need to handle some protocol that doesn't allow sending or
something in the future, then we can deal with it.  Incidentally, an
easy way to do it would be to set up a qbypass that errors out (and
probably frees the block).

4 years agoSupport FD taps in #I on data files
Barret Rhoden [Mon, 3 Aug 2015 17:14:02 +0000 (13:14 -0400)]
Support FD taps in #I on data files

With this commit, users can put FD taps on data files (e.g.
/net/tcp/0/data).  We'll get a callback from qio whenever a READABLE,
WRITABLE, or HANGUP filter occurs.  fire_tap() will send an event, if
the tap filter matches the event.

Notice that we ignore certain events on the 'wrong' queue.  For
instance, we don't care when the wq becomes READABLE.  In fact, #I is
responsible for that event.  It'd be like firing a tap to tell someone
that they just performed a write and a packet is ready to move *deeper*
into the network stack.

Another thing to be aware of is qio bypass.  This feature allows a queue
to have its write method bypassed.  Check out qbwrite().  This means
that some protocols with bypass might not be tapable.

One user of bypass is UDP: its wq has a bypass set to udpkick().  Since
UDP's wq bypasses the usual qbwrite(), it will not receive wake
callbacks when the write queue is drained and becomes *readable*.  But
we don't care about those anyways; we care when the write queue becomes
writable.  So in this case, there's nothing to worry about, but there
could be issues in the future.  Stay alert.

As a side note, udp's write bypass also means that the Qnonblock setting
is not necessarily checked or honored.  If udpkick decides to block,
then too bad for the conversation's non-blocking status.  Bypass methods
ought to honor those settings.  In this case, udpkick doesn't block
within the protocol processing (like TCP does), so it's not a concern.

4 years agoqio: Ensure qwait() sets Qstarve
Barret Rhoden [Mon, 31 Aug 2015 20:51:46 +0000 (16:51 -0400)]
qio: Ensure qwait() sets Qstarve

Qstarve tracks the status of the queue.  When the flag is set, the queue
was checked and was found empty.  All of the wakeup code (grep dowakeup)
will check Qstarve.

A couple things to note:
- Qstarve is an optimization.  You should be able to just call
  rendez_wakeup and whatever else.  However, those can be expensive.
- This is false: "The queue is empty only if Qstarve is set".  It is
  possible for the queue to have been drained to 0, but not all the way,
and Qstarve is not set.  It will be set when some thread attempts to
extract data.

Ideally, this would be merged with the (already pushed)
3e0ae7c72ced ("qio: Add non-blocking queues")

4 years agoqio: Add callbacks for unblocking queues
Barret Rhoden [Mon, 3 Aug 2015 16:03:00 +0000 (12:03 -0400)]
qio: Add callbacks for unblocking queues

When queues want to wake up any waiters is an edge-triggered event.  If
we would have done a rendez, then presumably userspace could be
interested in that event.

This commit adds callbacks triggered by these events, such that other
systems (e.g. #I) can support FD taps.  The callback takes an FD tap
filter, and uses that space of flags to express its events.

I considered hooking the taps directly into the queues, instead of in
the conversation.  Two things make that difficult:
- Not all queues are equal.  Conversations have two queues: send (wq)
  and receive (rq).  #I's FD taps only care about when the read queue
becomes readable, not when it becomes writable.  Likewise with the write
- Putting the tap in two places in the qio code is more complicated than
  keeping it in one place in the conversation - especially when we'd
like to support modifying taps in the future.

4 years agoAdd FD tap infrastructure (XCC)
Barret Rhoden [Thu, 30 Jul 2015 20:18:01 +0000 (16:18 -0400)]
Add FD tap infrastructure (XCC)

FD taps allow the user to receive events when certain things happen to
an FD's underlying disk/device file.  Think epoll/kqueue.  The specific
filters and commands are subject to change.

This commit adds a syscall and the device-independent infrastructure to
pass the command to the device and to deal with all of the issues
related to registration, removal, and other concurrent operations.

Unlike epoll, the FD tap is tracked on the FD and within the device (if
the device so chooses), and this leads to a certain amount of
complexity.  Check out the documentation for details.

Reinstall your kernel headers (make xcc-install-headers).

4 years agoReorganize the scheduler __core_request() loop
Valmon Leymarie [Wed, 23 Sep 2015 00:09:46 +0000 (17:09 -0700)]
Reorganize the scheduler __core_request() loop

Previously there was duplicated code to first loop through a proc's
prov_not_alloc list, and then loop through the idlecore list to find an
available core and allocate it to a proc. This commit consolidates these
loops into a single loop. It works by having a function called
find_best_core(), which always pulls from the prov_not_alloc list
first, only falling back to the idlecore list if the prov_not_alloc list
becomes empty.

The logic to preempt a core stays the same because we know that the
spc_i->alloc_proc field will *only* be set if the core we are
considering is provisioned to the proc, but allocated to someone else
(due to the invariant maintained by the proc's prov_not_alloc list). In
all other cases, we want to simply take the core selected by
find_best_core() and allocate it to the proc using the same logic
regardless of whether it was pulled from its prov_not_alloc list or the
idlecore list.

4 years agoConsolidate track_(de)alloc() with idlecore mgmt.
Valmon Leymarie [Wed, 23 Sep 2015 00:09:38 +0000 (17:09 -0700)]
Consolidate track_(de)alloc() with idlecore mgmt.

Every instance of __prov_track_alloc() and __prov_track_dealloc() were
previously called with a subsequent call to REMOVE a core from the idle
core list or INSERT a core to the idle core list respectively.  This
commit consolidates these calls such that __prov_track_alloc() and
__prov_track_dealloc() now manage adding and removing cores from the
idle core list themselves.

As part of this, the internal __put_idle_cores() function can be
removed, because it was always called in sequence with a call to
__prov_track_dealloc_bulk(), which reinserts the cores into the idlecore
list itself now.

This consolidation helps to narrow the interface for providing alternate
core allocation strategies (which will be forthcoming in a future

4 years agoRename get_this_idle_core ->get_specific_idle_core
Valmon Leymarie [Mon, 21 Sep 2015 22:22:23 +0000 (15:22 -0700)]
Rename get_this_idle_core ->get_specific_idle_core

The name get_specific* is more understandable than get_this* (especially
when compared to the get_any* function it is paired with).

This change is in preparation for a refactoring of the scheduler code
that will come in a subsequent commit.

4 years agoClean up awkward code sequences in ether driver.
Dan Cross [Thu, 24 Sep 2015 01:20:06 +0000 (21:20 -0400)]
Clean up awkward code sequences in ether driver.

Rework two awkward code sequences in the ethernet driver to
make the logic easier to follow.

In the first case, put explicit freeb() and early returns
into etheroq in the cases where we are looping a frame back
up the stack.

In the second, change the loop in etheriq to use 'guard'
conditions and early continues to make the logic linear.

4 years agoAdd a monitor command gfp to get free pages
Xiao Jia [Thu, 17 Sep 2015 03:38:45 +0000 (20:38 -0700)]
Add a monitor command gfp to get free pages

This was useful in debugging buffer allocations in the mlx4 driver.

4 years agoAdd name to pci_device
Xiao Jia [Thu, 17 Sep 2015 03:34:17 +0000 (20:34 -0700)]
Add name to pci_device

4 years agoAllow check_poison() to be called w/o cur_kthread
Barret Rhoden [Wed, 23 Sep 2015 20:04:30 +0000 (16:04 -0400)]
Allow check_poison() to be called w/o cur_kthread

If you called snprintf() or any other function that calls check_poison()
before smp init occurs, then we'd fail the assertion.  It's reasonable
to make those checks early on, so the assertion is now part of the 'if'.

4 years agomlx4: RX path
Xiao Jia [Thu, 17 Sep 2015 03:27:08 +0000 (20:27 -0700)]
mlx4: RX path

After this change, ping works!

4 years agomlx4: TX path
Xiao Jia [Thu, 17 Sep 2015 03:17:16 +0000 (20:17 -0700)]
mlx4: TX path

Critical path was copied from mlx4_en_xmit() to mlx4_send_packet() as a
separate function so we only port what we actually need.

After this change, ifconfig can complete.

4 years agomlx4: Implement ether_attach to start port
Xiao Jia [Thu, 17 Sep 2015 03:09:19 +0000 (20:09 -0700)]
mlx4: Implement ether_attach to start port

4 years agomlx4: Add ether callbacks
Xiao Jia [Thu, 17 Sep 2015 03:01:41 +0000 (20:01 -0700)]
mlx4: Add ether callbacks

4 years agomlx4: Initialize ConnectX HCA Ethernet driver (mlx4_en)
Xiao Jia [Thu, 17 Sep 2015 02:58:08 +0000 (19:58 -0700)]
mlx4: Initialize ConnectX HCA Ethernet driver (mlx4_en)

4 years agomlx4: Initialize ConnectX core driver (mlx4_core)
Xiao Jia [Thu, 17 Sep 2015 01:19:20 +0000 (18:19 -0700)]
mlx4: Initialize ConnectX core driver (mlx4_core)

4 years agomlx4: Clean up to make it compile
Xiao Jia [Thu, 17 Sep 2015 00:58:00 +0000 (17:58 -0700)]
mlx4: Clean up to make it compile

4 years agomlx4: Clean up #include's in headers
Xiao Jia [Thu, 17 Sep 2015 00:15:12 +0000 (17:15 -0700)]
mlx4: Clean up #include's in headers

4 years agoClean up imported rdma headers to compile mlx4
Xiao Jia [Thu, 17 Sep 2015 00:09:01 +0000 (17:09 -0700)]
Clean up imported rdma headers to compile mlx4

4 years agomlx4: Exclude en_ethtool.c for now
Xiao Jia [Thu, 17 Sep 2015 00:05:03 +0000 (17:05 -0700)]
mlx4: Exclude en_ethtool.c for now

4 years agoAdd to_delayed_work() to taskqueue.h
Xiao Jia [Thu, 17 Sep 2015 00:02:21 +0000 (17:02 -0700)]
Add to_delayed_work() to taskqueue.h

4 years agoFix a typo in taskqueue.h
Xiao Jia [Thu, 17 Sep 2015 00:01:59 +0000 (17:01 -0700)]
Fix a typo in taskqueue.h

4 years agoPort scatterlist from Linux
Xiao Jia [Thu, 17 Sep 2015 00:01:18 +0000 (17:01 -0700)]
Port scatterlist from Linux

[brho: added the copyright from Linux's lib/scatterlist.c]

4 years agoPort dmapool from Linux
Xiao Jia [Thu, 17 Sep 2015 00:01:02 +0000 (17:01 -0700)]
Port dmapool from Linux

4 years agoAdd compat layer for mlx4 driver
Xiao Jia [Wed, 16 Sep 2015 23:33:56 +0000 (16:33 -0700)]
Add compat layer for mlx4 driver

Currently I put this compat layer at linux/compat_todo.h so it's treated
as a large piece of hack.  As the mlx4 driver becomes more stable, I'll
gradually move from this file to linux_compat.h in small pieces.

I tested that bnx2x still compiles after this change.

[brho: added copyright header]

4 years agoUpdate linux_compat.h so mlx4 could compile later
Xiao Jia [Wed, 16 Sep 2015 23:23:29 +0000 (16:23 -0700)]
Update linux_compat.h so mlx4 could compile later

I tested that the bnx2x driver still compiles after this change.

4 years agoImport errno.h from Linux 4.1
Xiao Jia [Wed, 16 Sep 2015 23:16:02 +0000 (16:16 -0700)]
Import errno.h from Linux 4.1

The file is actually a result of concatenating multiple files to avoid
pulling in the whole directory structure of Linux.  The file is simply
a series of #define's, so there's no need to spatch it.

[brho: edited to use ros/errno.h for the common #defines]

4 years agomlx4: Apply spatch to files imported from Linux
Xiao Jia [Wed, 16 Sep 2015 23:08:11 +0000 (16:08 -0700)]
mlx4: Apply spatch to files imported from Linux

The following commands were executed repeatedly until convergence.

scripts/spatch/spatch-me.sh scripts/spatch/linux/scalar.cocci yes kern/drivers/net/mlx4/
scripts/spatch/spatch-me.sh scripts/spatch/linux/scalar.cocci yes kern/include/linux/
scripts/spatch/spatch-me.sh scripts/spatch/linux/sync.cocci yes kern/drivers/net/mlx4/
scripts/spatch/spatch-me.sh scripts/spatch/linux/sync.cocci yes kern/include/linux/
scripts/spatch/spatch-me.sh scripts/spatch/linux/memory.cocci yes kern/drivers/net/mlx4/
scripts/spatch/spatch-me.sh scripts/spatch/linux/memory.cocci yes kern/include/linux/
scripts/spatch/spatch-me.sh scripts/spatch/linux/funcs.cocci yes kern/drivers/net/mlx4/
scripts/spatch/spatch-me.sh scripts/spatch/linux/funcs.cocci yes kern/include/linux/
scripts/spatch/spatch-me.sh scripts/spatch/linux/io_funcs.cocci yes kern/drivers/net/mlx4/
scripts/spatch/spatch-me.sh scripts/spatch/linux/io_funcs.cocci yes kern/include/linux/

4 years agoUpdate spatch/linux/*.cocci
Xiao Jia [Wed, 16 Sep 2015 22:53:43 +0000 (15:53 -0700)]
Update spatch/linux/*.cocci

4 years agoImport rdma headers from Linux 4.1
Xiao Jia [Wed, 16 Sep 2015 22:47:54 +0000 (15:47 -0700)]
Import rdma headers from Linux 4.1

4 years agoAdd mlx4 to build process
Xiao Jia [Fri, 26 Jun 2015 00:12:04 +0000 (17:12 -0700)]
Add mlx4 to build process

4 years agoImport mlx4 files from Linux 4.1
Xiao Jia [Tue, 8 Sep 2015 23:26:58 +0000 (16:26 -0700)]
Import mlx4 files from Linux 4.1

4 years agoAdd fls_long() to bitops
Xiao Jia [Fri, 26 Jun 2015 00:10:23 +0000 (17:10 -0700)]
Add fls_long() to bitops

4 years agoUpdate GETTING_STARTED for the new mailing list
Barret Rhoden [Tue, 22 Sep 2015 19:45:15 +0000 (15:45 -0400)]
Update GETTING_STARTED for the new mailing list

The minor ugliness is due to Github/markdown not dealing the the +
nicely.  If you just do <akaros+subscribe@googlegroups.com>, you'll get
nothing.  If you do <mailto:akaros+subscribe@googlegroups.com>, you'll
get a nice looking link, but some browsers will turn the + into a ' '
when sending it to your mail client.  This way looks right (for
copy/paste) and works when I click on it.

4 years agox86: Change idt_init() to not clobber num_cores
Barret Rhoden [Tue, 15 Sep 2015 18:11:09 +0000 (14:11 -0400)]
x86: Change idt_init() to not clobber num_cores

idt_init() uses some Plan 9 techniques to check the MP tables and ACPI
to determine the number of cores.  It was clobbering the value computed
by the topology.  These values should not differ - if they do, there may
be something wrong with MP/ACPI, or we're lacking ACPI at all.

4 years agoUpdate akaros to hook in the new topology stuff
Kevin Klues [Mon, 14 Sep 2015 21:04:50 +0000 (14:04 -0700)]
Update akaros to hook in the new topology stuff

To test the topology you can kfunc print_cpu_topology

[brho: touched up a foo(void) ]

4 years agoBuild topology from cpuid in topology.c
Kevin Klues [Thu, 3 Sep 2015 23:09:01 +0000 (16:09 -0700)]
Build topology from cpuid in topology.c

This is the first commit to introduce the notion of CPU toology in
Akaros. Previously we relied on a flat topology of cores, with no
concept of hierarchy between hyperthreaded cores, sockets, or numa
domains.  With this commit we begin using the x86 cpuid instruction to
build out structures that are aware of the actual topology underneath.
We also use the ACPI tables to detect our numa structure.

Nothing is actually hooked in yet. We just bring the files in.

[brho: minor touchups, foo(void)s and comments ]

4 years agotlb_flush_global() needs to call core_id_early()
Kevin Klues [Tue, 4 Aug 2015 03:30:32 +0000 (20:30 -0700)]
tlb_flush_global() needs to call core_id_early()

Previously it just called core_id(), but it is used inside vm_init()
early on in the boot process. As we begin to upgrade the way we discover
our topology, it is important to make sure we use the core_id_early() to
make sure we read 0 early on, and not some bogus value from our
topology data structure if it has not yet been properly initialized.

4 years agoRename node_id -> numa_id
Kevin Klues [Tue, 4 Aug 2015 00:26:25 +0000 (17:26 -0700)]
Rename node_id -> numa_id

It's less confusing to talk about a numa id than a node id.  Node
implies a completely different machine and has connotations with a
datacenter node rather than a single machine.

4 years agoPut a safety catch in compat_todo.h
Barret Rhoden [Mon, 14 Sep 2015 17:47:18 +0000 (13:47 -0400)]
Put a safety catch in compat_todo.h

It should only ever be included from linux_compat.h, directly.  This
catch won't catch everything (you could include it manually after
including linux_compat), but it might catch casual users.

4 years agoMake akaros_compat.h a kernel header
Barret Rhoden [Mon, 14 Sep 2015 17:39:31 +0000 (13:39 -0400)]
Make akaros_compat.h a kernel header

And renames it to linux_compat.h.  This way, other Linux drivers or code
can benefit from the compatibility shims.

I also moved the compat_todo.h, which is basically an even hackier part
of linux_compat.h - the things that are *really* bad.

4 years agoAdd disable-canonical flags for cross-compiler build.
Dan Cross [Mon, 14 Sep 2015 15:57:23 +0000 (11:57 -0400)]
Add disable-canonical flags for cross-compiler build.

This is used in some environments to avoid canonicalizing
programs the compiler invokes to an absolute directory path.

4 years agoFix LICENSE-plan9 hlink in README.md
Barret Rhoden [Wed, 9 Sep 2015 15:27:26 +0000 (11:27 -0400)]
Fix LICENSE-plan9 hlink in README.md

4 years agoRename LICENSE-PLAN9 -> LICENSE-plan9
Barret Rhoden [Tue, 8 Sep 2015 17:40:52 +0000 (13:40 -0400)]

4 years agoClean up licensing
Barret Rhoden [Tue, 8 Sep 2015 15:37:08 +0000 (11:37 -0400)]
Clean up licensing

At the very least, we should have an explanation of how the software is
licensed and provide copies of the licenses in the repo.

4 years agoAdd top level README file
Kevin Klues [Thu, 3 Sep 2015 04:03:56 +0000 (21:03 -0700)]
Add top level README file

This file is markdown compliant and links to our GETTING_STARTED and
Contribution files.  It also gives a brief overview of Akaros includes
instructions on our mailing list, the contribution process, etc.

4 years agoMake *.md files markdown compliant
Kevin Klues [Thu, 3 Sep 2015 04:02:33 +0000 (21:02 -0700)]
Make *.md files markdown compliant

4 years agoRename Contributing and GETTING_STARTED files
Kevin Klues [Thu, 3 Sep 2015 04:01:01 +0000 (21:01 -0700)]
Rename Contributing and GETTING_STARTED files

Add *.md extensions in preparation fo a subsequent commit where I make
these files markdown compliant.

4 years agoAdd static storage for bounded # of dtls keys/vals
Kevin Klues [Tue, 25 Aug 2015 01:18:27 +0000 (18:18 -0700)]
Add static storage for bounded # of dtls keys/vals

Storage for up to NUM_STATIC_KEYS is now statically allocated for dtls
keys. Likewise, per-thread storage for the values associated with these
keys is allocated as part of a thread's static TLS data (in an array
called 'early_values').  By statically allocating this data, we avoid
having to dynamically allocate memory for a small number of DTLS keys
and their associated values.  Moreover, we have a faster lookup time for
these key/value pairs because we know exactly where to look for their
values by indexing into an array instead of searching through a linked

Realistically, dtls keys will likely go unused in most apps today, in
favor of compiler supported TLS via __thread. For this reason, we chose
to only optimize for a small number of keys since it's likely that we
won't every go beyond this value in a real application.  If we do, we
can revisit this implementation and do something more sophisticated
along the lines of what glibc does in its pthread_key_create() and
pthread_get/setspecific() calls (i.e. use a 2-level array structure with
a finite bound on the number of keys).  For now, what we have is
sufficient for the apps we've encountered.

Overall, it may seem weird to store the dtls early_values array inside
of a __thread variable (since the whole point of dtls is to enable
dynamically allocated TLS when compiler supported TLS is unavailable),
but we mostly only provide dtls for backwards compatibility and plan to
always enable compiler supported TLS for apps that require TLS of any

4 years agoImplement __set_dtls() in terms of __get_dtls()
Kevin Klues [Tue, 25 Aug 2015 00:49:11 +0000 (17:49 -0700)]
Implement __set_dtls() in terms of __get_dtls()

The functionality contained in __get_dtls() was being duplicated in
__set_dtls().  This commit consolidates them.

4 years agoRename dtls_lib_init() -> dtls_cache_init()
Kevin Klues [Mon, 24 Aug 2015 22:42:27 +0000 (15:42 -0700)]
Rename dtls_lib_init() -> dtls_cache_init()

The only initialization that needs to happen here is in support of
allocing/freeing from the caches, so it's not really a "lib" init in
that sense (it's more of a cache init). As part of this, we make sure
that __alloc_dtls_key() call triggers the initialization rather than the
dtls_key_create() call.

4 years agoAbstract out alloc/free from the key/value caches
Kevin Klues [Mon, 24 Aug 2015 22:35:11 +0000 (15:35 -0700)]
Abstract out alloc/free from the key/value caches

Now none of the core logic cares about how the keys are alloced or
freed, it just uses the keys/values handed to it by these helper
functions.  This will become important in a subsequent commit that
optimizes the process of allocating keys/values for a small number of

4 years agoRemove all spinlocks
Kevin Klues [Mon, 24 Aug 2015 21:42:57 +0000 (14:42 -0700)]
Remove all spinlocks

The spinlock in the dtls struct is unnecessary, because the only field
it matters for is the refcount, which we can increment and decrement
using atomic ops.  The setting of the valid field to false (which was
previously protected by the lock) is inherently racy when used to decide
whether a destructor function should be run. Removing the lock when
setting this value doesn't make it any less racy. As the comment
suggests though, any reasonable usage of DTLS should not be deleting a
key until it knows that all threads have ran their destructors anyway
(or at least aren't currently in the process of running their

Moreover the global __dtls_lock is unnecessary, as it only protects
access to the slab allocator functions, which have pdr locks

As part of this, we are now able to move the atomic decrement into our
call for __maybe_free_dlts_key(), fixing a race condition on reading the
keys refcount in the process. We use a __sync_add_and_fetch instead of a
__sync_fetch_and_add to grab the new value atomically, before comparing
it to 0.

4 years agoFix do_mkdir on root directories
Barret Rhoden [Thu, 27 Aug 2015 02:58:15 +0000 (22:58 -0400)]
Fix do_mkdir on root directories

mkdir / should fail with EEXIST, not ENOENT.  The problem, pointed out
by Kevin, was that the parent check happened before the existence check,
and root directories (also for chroots) do not have parents.

This failure caused things like mkdir -p /foo/bar to fail.

Note that the VFS stack is racy, and concurrent mkdirs will probably
cause a lot of trouble.

4 years agoAtomically set current_uthread and a 2LS sched ops
Barret Rhoden [Mon, 24 Aug 2015 14:05:22 +0000 (10:05 -0400)]
Atomically set current_uthread and a 2LS sched ops

When initializing a 2LS, we are setting up both a current_uthread and a
2LS sched ops.  These must be in sync any time that a 2LS op is called.

Say we change the sched ops, but not the pointer, and then we receive a
notif (or do anything that triggers a 2LS op).  Then we're using the
sched_ops sched_entry on the wrong type of uthread.  If we have the
pointer change first, then the sched_ops operation is performed on the
wrong uthread (even if it's a thread0 op, we could be have the wrong
values or something).

This change splits manage_thread0 into its two components: init and
track.  Tracking the uthread in the vcore's current_uthread is done
"atomically" with setting the sched ops, with respect to notifs and
blocking syscalls.  These are the source of unexpected scheduler ops
calls.  If there are more sources in the future, we'll have to disable
them here.

4 years agoPass sched_ops to uthread_2ls_init()
Barret Rhoden [Mon, 24 Aug 2015 14:03:21 +0000 (10:03 -0400)]
Pass sched_ops to uthread_2ls_init()

This is necessary so that in a later commit we can "atomically" set the
2LS ops and change current_uthread.  Ops like signal_ops aren't as
critical in this regard.