akaros.git
4 years agoUntangling the glibc header rat's nest (P.2) (XCC)
Barret Rhoden [Fri, 2 Oct 2015 14:14:04 +0000 (10:14 -0400)]
Untangling the glibc header rat's nest (P.2) (XCC)

This time around, we'll try and fix up the time headers.  Ideally,
anything that is part of the kernel interface is exposed via the kernel
headers.  For instance, struct timespec and maybe struct timeval (which
is just mentioned in a comment).

It's relatively easy to override timeval - that's what bits/time.h is
for (it gets included by sys/time.h).  However, timespec is a little
trickier, since it's defined directly in time.h, not bits/time.h that is
made to be sysdep-overrode.  (Note that timespec is available to
programs via #include time.h.  Timeval comes from sys/time.h...).
Overriding time.h required the same file twice:
sysdeps/akaros/time/time.h and sysdeps/akaros/time.h.

With this dive into the rats nest, our kernel header no longer needs the
mysterious #define __timespec_defined.

Rats' nest ref: 5b5cc8856

Rebuild glibc.

4 years agoRemove itimerspec from <ros/time.h> (XCC)
Kevin Klues [Wed, 30 Sep 2015 21:57:02 +0000 (14:57 -0700)]
Remove itimerspec from <ros/time.h> (XCC)

Its existence causes conflicts when both <ros/time.h> and <time.h> are
\#included in the same file. We will likely want to add support for an
itimer at some point in the future, but this will never be a kernel
construct, so it's fine to pull its definition straight from <time.h>
when we go to build it. Any implementation we build will sit on the
\#alarm device and just expose the itimer interface in userspace.

We already support something "sortof" like the itimer, except its on a
per-vcore basis, rather than a per-thread basis. We can think about
actually supporting the itimer interface similarly.

[brho: make timer_deps include <ros/time.h> to check for the conflict]

Reinstall your kernel headers.

4 years agoRemove dependency for {unistd,stdlib}.h in vcore.h (XCC)
Kevin Klues [Thu, 1 Oct 2015 02:24:22 +0000 (19:24 -0700)]
Remove dependency for {unistd,stdlib}.h in vcore.h (XCC)

We only had this dependency to include the prototype for _exit() so we
could override our exit() call with it.  We still need to do this
override, but there is no need to pollute the namespace of everything
that #includes vcore.h with all of the stuff from unistd.h and stdlib.h.
Just extern in the _exit() and exit() prototypes.

Removing this dependency meant that some of our .c files needed to
explicitly #include these files.  They are patched up accordingly.

Requires a rebuild of the cross compiler (XCC)

4 years agoFix warning in glibc-2.19/sysdeps/akaros/user_fd.c (XCC)
Kevin Klues [Thu, 1 Oct 2015 04:28:34 +0000 (21:28 -0700)]
Fix warning in glibc-2.19/sysdeps/akaros/user_fd.c (XCC)

We should explicitly return 0 at the end of this function.

4 years agoAdd PTHREAD_RWLOCK_INITIALIZER
Kevin Klues [Thu, 1 Oct 2015 02:50:17 +0000 (19:50 -0700)]
Add PTHREAD_RWLOCK_INITIALIZER

We currently just implement our rwlocks using a standard pthread_mutex.
For these locks to be usable, we also need to have an INITIALIZER that
matches the normal PTHREAD_MUTEX_INITIALIZER.  We should revisit this
soon and provide true rwlocks.

4 years agoMake --no-print-directory optional in MAKERULES
Kevin Klues [Thu, 1 Oct 2015 00:12:05 +0000 (17:12 -0700)]
Make --no-print-directory optional in MAKERULES

Allow people to override our setting of the --no-print-directory option
in their Makelocal. This is useful, for example, to allow emacs to find
the correct file when errors are encountered using its builtin 'M-x
compile' command. This also requires us to "cd' with our recursive makes
using the '-C' option rather than actually calling 'cd' before invoking
our recursive make.

4 years agoAdd user interface to #eventfd (XCC) [2/2]
Barret Rhoden [Tue, 22 Sep 2015 15:28:18 +0000 (11:28 -0400)]
Add user interface to #eventfd (XCC) [2/2]

The glibc eventfd headers are from the Linux port.

Rebuild glibc.

4 years agoAdd #eventfd [1/2]
Barret Rhoden [Tue, 22 Sep 2015 15:23:40 +0000 (11:23 -0400)]
Add #eventfd [1/2]

This is a kernel device for eventfd().  It differs slightly from Linux
in that the kernel interface is a string instead of a host-endian u64.

You can play with the raw interface by attaching an instance of #eventfd
to the namespace (just like #pipe).  For example:

/ $ bind \#eventfd /prog
bind #eventfd -> /prog flag 0
( attach an eventfd in counter mode )
/ $ echo 33 > /prog/efd
/ $ read_once /prog/efd
33/ $
( put in and extract 33 (decimal) )
/ $ read_once /prog/efd &
( read in the background.  will exit after one read syscall. )
/ $
/ $ echo 33 > /prog/efd
33/ $
( woke up the blocked read_once )

4 years agoAdd a helper: read_once
Barret Rhoden [Tue, 22 Sep 2015 15:40:49 +0000 (11:40 -0400)]
Add a helper: read_once

When dealing with devices, sometimes it's nice to be able to do exactly
one read syscall.

4 years agoFix minor u64 read-in issue in devalarm
Barret Rhoden [Tue, 22 Sep 2015 15:17:23 +0000 (11:17 -0400)]
Fix minor u64 read-in issue in devalarm

32 bits for buf is more than they should ever send in, but NUMSIZE64 is
more appropriate, now that it can handle leading "0x"es.  Also, we
should error out when n > sizeof, not >= sizeof.  This didn't matter
before we used NUMSIZE64.

These aren't a big deal, but since device code gets copied around, it's
worth fixing.

4 years agoAccount for 0x in NUMSIZE{32,64}
Barret Rhoden [Tue, 22 Sep 2015 15:12:04 +0000 (11:12 -0400)]
Account for 0x in NUMSIZE{32,64}

This makes it easier for us to use NUMSIZE for buffer sizes, without
worrying whether or not the format string is in decimal, hex, or hex
with a "0x" in front.

4 years agoProvide a more useful devpermcheck error
Barret Rhoden [Mon, 21 Sep 2015 22:48:02 +0000 (18:48 -0400)]
Provide a more useful devpermcheck error

Perms and rwxes are easier to read in octal.

4 years agoAllow openat() from any file type (XCC)
Barret Rhoden [Wed, 16 Sep 2015 17:36:15 +0000 (13:36 -0400)]
Allow openat() from any file type (XCC)

The kernel doesn't restrict openat()'s "dirfd" to be a directory, which
is why I call it fromfd.  That may be a bad idea; we'll see.

Since the kernel doesn't stop it, there's little reason to have glibc
stop it too.  Perhaps programs that expect to fail will now succeed, but
that's not worth the extra fstat for every file-relative openat().

Rebuild glibc if you want.

4 years agoReplaces SYS_open with SYS_openat (XCC)
Barret Rhoden [Tue, 15 Sep 2015 20:21:59 +0000 (16:21 -0400)]
Replaces SYS_open with SYS_openat (XCC)

openat() is now available as a syscall and through glibc's shims.

Rebuild glibc and anything that may have called open().  Go probably
needs changed too, since SYS_open is gone.

4 years agoImplement sys_open() with sys_openat() (XCC)
Barret Rhoden [Tue, 15 Sep 2015 20:00:13 +0000 (16:00 -0400)]
Implement sys_open() with sys_openat() (XCC)

With namec_from(), we can now build openat() for 9ns.  This commit
builds sys_openat (and the 9ns version), and uses that as a wrapper for
sys_open.  Userspace cannot access this call yet.  Our VFS does not have
support for openat at all.

Also, unlike Linux, we allow an openat from any type of chan, not just a
directory - at least that's the case within the kernel.  What userspace
does (like glibc) is its own thing.

This changes a kernel header, though it shouldn't affect you.

4 years agoSplit namec() into a start point and __namec_from
Barret Rhoden [Tue, 15 Sep 2015 19:10:56 +0000 (15:10 -0400)]
Split namec() into a start point and __namec_from

The first half of namec() figures out which chan we should start from,
whether that's a #device attach point, /, or DOT.  Then the rest does
the actual walk and other stuff.

This splits namec() such that we can eventually call the namec_from for
an implementation of openat().

AFAIK, things like prefix and the difference between name and aname is
mostly for debugging.  In namec(), aname was the original name asked for
(e.g. #root/foo/bar), and name gets advanced up to the path relative to
the starting point (e.g. /foo/bar).

namec_from() is a helper that just calls __namec_from, as if you already
had a real chan and were walking farther down the line (hence the
can_mount).  This should be the essence of an openat.

4 years agoChange namec() and walk()'s nomount to can_mount
Barret Rhoden [Tue, 15 Sep 2015 18:35:11 +0000 (14:35 -0400)]
Change namec() and walk()'s nomount to can_mount

The double-negative was ugly.  This changes the variable to a bool and
switches its value.

Note that the walk() changed here is 9ns's walk, not to be confused with
devtab's walk(), or any other walks.

4 years agoAllow 9ns clones of chans opened with O_PATH
Barret Rhoden [Wed, 16 Sep 2015 16:19:54 +0000 (12:19 -0400)]
Allow 9ns clones of chans opened with O_PATH

I've heard it's a bad idea to allow clones of opened chans.  I'd like to
do it for O_PATH (no I/O allowed) chans.

I don't know the reasons for not allowing the clone.  One thing is that
it appears that devices up their refcnts or otherwise keep objects
around based on an open - which stands to reason: even after you unlink,
open objects stay around.  When we devclone, we might be messing up
something where the device does not know about the cloned chan.
However, the new chan is not COPEN, so it's like one of what I call the
"kernel internal" chans.

This relates to the decision to have O_PATH actually call a device's
open.  The choices seem to be:

1) Don't call open.  The user has an FD that points to a chan that may
or may not point to an actual object (not super comfortable with that,
but it might be fine.  This is my original SYS_walk).  Devclone doesn't
allow any opened chans to be cloned (and therefore walked from), and no
O_PATHs are actually opened.  You can only openat() from one of these
O_PATHs.  FD taps (e.g. ipfdtap) will need to grab references to keep
the conversation alive (and there may be races/issues of tapping old
conversations).

2) Call open.  The user will only ever have FDs that point to opened,
possibly-refcnted objects (this might be unnecessary).  The device is
involved in an O_PATH open.  openat() can be called on any FD (we may
allow from non-dirs).  The downside is that we're cloning an open chan,
which may have bad side effects.

For now, I'll go with option 2.

4 years agoRemove unused error strings
Barret Rhoden [Tue, 15 Sep 2015 17:25:48 +0000 (13:25 -0400)]
Remove unused error strings

I noticed Ebadsharp wasn't used anymore, as of a couple commits ago, and
figured it was time to prune the list a little.

In general, if we're using a constant for an errstring, then we should
just be using errno.  If it's worth using errstr, then it's worth having
a custom, printf-style message.

4 years agoRemove old scripts from KFS
Barret Rhoden [Wed, 16 Sep 2015 16:09:43 +0000 (12:09 -0400)]
Remove old scripts from KFS

Both are unused, and in lieu of patching their device names, we're
removing them.  Trex is an unfinished ethermedium, and Ron doesn't use
runvm anymore.

4 years agoRemove struct dev's dc [3/3]
Barret Rhoden [Tue, 15 Sep 2015 15:47:51 +0000 (11:47 -0400)]
Remove struct dev's dc [3/3]

This was the field that identified the device with one char.

For the most part, this change was just removing dc and using name in
its place for some debugging.

The tricky stuff is that devmnt and devdir were putting the dc into the
struct dir (a D), I think.  We'll see if there are any harmful effects
of that.

4 years agoModify userspace to use device names [2/3]
Barret Rhoden [Tue, 15 Sep 2015 15:17:29 +0000 (11:17 -0400)]
Modify userspace to use device names [2/3]

This involved changing any #device from #DC to #name.

Anything outside the repo that accesses #devices, such as the Go port,
personal ifconfig scripts, etc, will need to be updated.

4 years agoIdenfity devices by name, not by char [1/3]
Barret Rhoden [Tue, 15 Sep 2015 15:09:07 +0000 (11:09 -0400)]
Idenfity devices by name, not by char [1/3]

Previously, all devices were one character, followed by a spec. (e.g.
 #l0, where # says it is a device, l says it is devether, and 0 is the
NIC).  Now, devices are referred to by their name, with the spec
separated from the name by a '.'.  So "#l0" is now "#ether.0".

Since we don't use UTF8, we have a limited number of device IDs, nor do
I want to type out the infinity symbol or something.  Plus, there is
high demand for popular letters.  Why was ether using 'l'?  Looking at
one character does not helpfully identify a device.  All of these issues
are solved by using a name.

This compiles, but userspace will have trouble with it since it still
uses the old chars (e.g. #I).

4 years agoFix strlen bug in devattach
Barret Rhoden [Wed, 23 Sep 2015 14:58:36 +0000 (10:58 -0400)]
Fix strlen bug in devattach

The length of the buffer is not the sizeof a char *.

4 years agoEnsure syspipe() catches error()
Barret Rhoden [Tue, 15 Sep 2015 14:46:13 +0000 (10:46 -0400)]
Ensure syspipe() catches error()

namec() can throw.  If we throw before the waserror, it'll propagate up
to the non-9ns code.

4 years agoFix namec() bug with # lookups
Barret Rhoden [Tue, 15 Sep 2015 14:39:19 +0000 (10:39 -0400)]
Fix namec() bug with # lookups

We shouldn't take sizeof(get_cur_genbuf()); we want the buffer's size,
not a char *'s size.

Also, the "n < 2" business seems to be allowing a #device named '/',
which I do not want.

4 years agoAdd epoll_server test
Barret Rhoden [Thu, 3 Sep 2015 18:53:51 +0000 (14:53 -0400)]
Add epoll_server test

It's a simple telnet server, using epoll for both the listen/accept and
the read-side of the data connection.

Similar to listener, it can use either the BSD sockets or the raw Plan 9
interface.

4 years agoTouch up a couple tests
Barret Rhoden [Thu, 3 Sep 2015 18:25:51 +0000 (14:25 -0400)]
Touch up a couple tests

Fixed the copyright, made listener's #define easier to work with, and
flushed the listener's output (otherwise it is buffered, due to the lack
of a \n).

4 years agoAllow epoll on listening sockets
Barret Rhoden [Thu, 3 Sep 2015 18:15:53 +0000 (14:15 -0400)]
Allow epoll on listening sockets

The user will ask to epoll on a socket FD for a listening socket.
However, that is a Qdata socket.  We need to translate that FD to the
Qlisten FD, and then add that FD to the epoll set.

If we ever change up the glibc helpers, such that close() just calls out
to something like _sock_closerock(int fd), then we can simplify this a
bit, and just do the translation at the top of epoll_ctl and not worry
about closing the FD.

4 years agoProvide a lookup for a socket's listen FD (XCC)
Barret Rhoden [Thu, 3 Sep 2015 18:08:26 +0000 (14:08 -0400)]
Provide a lookup for a socket's listen FD (XCC)

Due to the nature of Rocks, in that they basically multiplex the entire
conversation directory into one FD, we need a way to get certain parts
of the Rock from libraries/apps (e.g. epoll).

The listen fd is one of those things we need.  However, unlike with the
ctl file, we actually want the FD for Qlisten.  These functions will
create and return a listen FD on demand (the "get" function) and lookup
previously created FDs.  It is the job of the caller to close the FD
when it's done.

Ideally, I'd just have close() call out to the Rock code to close a
potential Rock.  Then we just store the FD in there, and don't really
worry about it.  However, close.c cannot link against the plan9_sockets,
due to the "multiple libcs" problem endemic to glibc.

Rebuild glibc.

4 years agoFix socket option bug in accept() (XCC)
Barret Rhoden [Wed, 2 Sep 2015 21:53:30 +0000 (17:53 -0400)]
Fix socket option bug in accept() (XCC)

We were carrying the listening socket's options through to the child.
These options include O_NONBLOCK and O_CLOEXEC.  Those are not supposed
to be inherited.  Instead the caller either does an fcntl() or uses
an accept4() shim (nonexistent at this point).

Rebuild glibc.

4 years agoClean up _sock_newrock()'s initialization (XCC)
Barret Rhoden [Wed, 2 Sep 2015 21:51:07 +0000 (17:51 -0400)]
Clean up _sock_newrock()'s initialization (XCC)

The initialization of certain fields was a bit sketchy.  Considering
that Rocks are reused, I want to proactively initialize bits, and not
rely on the caller to initialize the parts that _sock_newrock()
previously was ignoring.

Also, if _sock_findrock() succeeded, then we should know that the device
and inode match the old Rock.  Those asserts should never fire (hence
they are asserts).

4 years agoOptimize _sock_findrock() for the empty case (XCC)
Barret Rhoden [Wed, 2 Sep 2015 17:52:31 +0000 (13:52 -0400)]
Optimize _sock_findrock() for the empty case (XCC)

For programs that do not use the BSD socket shims, we still need check
if an FD is a socket or not in some places.  This requires an fstat to
identify the underlying device/file.  But if the list is empty (common
case for non-sockets programs), this syscall is a waste.

Note that _sock_newrock needs the fstat() done regardless, since it'll
use that info when making a new Rock.

Rebuild glibc if you want slightly better performance.

4 years agoHave #I show Qlisten FDs in chaninfo
Barret Rhoden [Thu, 3 Sep 2015 17:58:45 +0000 (13:58 -0400)]
Have #I show Qlisten FDs in chaninfo

Previously, no one could have an FD for a Qlisten, so this was unlikely
to come up, though it's possible to have a *chan* for Qlisten within the
kernel.

4 years agoAdd support for FD taps on Qlisten chans in #I
Barret Rhoden [Mon, 31 Aug 2015 18:43:35 +0000 (14:43 -0400)]
Add support for FD taps on Qlisten chans in #I

Applications can request an FD tap on a Qlisten file, e.g.
/net/tcp/0/listen.  The FDTAP_FILT_READABLE filter will fire when there
is a new connection.

Note that you must use open() with O_PATH to get a Qlisten FD.
Otherwise you'll block (or at least attempt) to get a new conversation.
After opening with O_PATH, you can either set up the Tap on your own, or
use epoll to find out about new conversations.

Right now, I have the Qlisten tap allow FDTAP_FILT_HANGUP requests,
mostly because epoll adds that in for every tap it uses.  Since there is
no distant end to the connection, hangup doesn't really make sense.
Maybe we'll find a use for it.

4 years agoAllow Qlistens to be partially opened with O_PATH
Barret Rhoden [Fri, 11 Sep 2015 16:01:16 +0000 (12:01 -0400)]
Allow Qlistens to be partially opened with O_PATH

This gives us an FD that actually points to Qlisten.  Otherwise, when
you do a full open of Qlisten, you get a chan that points to a new
conversation that you listened for.  With this FD, we'll be able to tap
Qlisten to find out about new conversations (epoll).

There's a few things I don't understand about how #I interacts with 9ns
and what the rules are.  For instance, you can namec to get a chan that
points to an object.  Now your chan has a QID and a device, uniquely
identifying the object.  Once you have that, are you supposed to have a
reference to the object that does not disappear until the chan is
released?  That would make sense.  Note that 9ns will call the device's
close() method on the chan, including chans that were not actually
opened.  #I deals with this by checking c->flags for COPEN so that it
only calls closeconv on chans that called ipopen().

That's also not what seems to happen with #I; there's no permanence
between gen and open.  ipgen will create conversation directories up to
"ac", which is the number of active conversations.  That seems to be the
only check in ipgen, and there's nothing that keeps those conversations
alive.  That's probably why we have a high water mark of conversations
in #I: once created, they are around forever.  Their status might just
change.

I think it is possible to namec/ipgen a chan for something like ctl,
data, or now listen and get the "wrong" conversation.  Say we gen a chan
for "data" for a conversation, but do not open it.  Then that
conversation closes (or it can even be closed already), and then a new
thread opens "clone" and gets a new conversation that has the same QID
as the genned chan.  (Here, Fsprotoclone checks inuse, but inuse is 0
still).  Then the genned chan is opened, and we now have an FD pointing
to a chan that is pointing to a conversation that wasn't the
conversation we originally asked for.

One way to think about this is "you asked for tcp/1/data, that's what
you get.  There's no guarantee that that conversation is the one you
actually want."

Anyway, you can now do that same thing with "listen".

Oh, and be careful if you try to hang refcnted blobs off c->aux.  I
tried that a while ago with #s and it was a nightmare.  Maybe it can
work, but again, the rules for how everything works are not clear.

4 years agoSupport O_PATH for open() (XCC)
Barret Rhoden [Thu, 10 Sep 2015 19:02:36 +0000 (15:02 -0400)]
Support O_PATH for open() (XCC)

Opening a path with O_PATH, which is also supported in Linux, walks to
an FD, grabs the chan, and refers to an object, but it does not fully
open the object for I/O.  Our O_PATH is similar to Linux's and can
eventually be used for openat().

The particular meaning of O_PATH will depend on the devices.  At a bare
minimum, FDs opened with O_PATH are not able to be used for I/O; they
have no access permissions.  They both refer to a location (path) in the
namespace, as well as refer to the object underneath.

In earlier versions of this code, I just did a namec() without the
device open or any device op.  You'd have an FD that pointed to a chan.
However, that chan was one of the kernel-only intermediate chans (9ns
uses them all the time).  The chan had a QID and a device ID, which
uniquely identifies the object, but that object had no permanence.  In
the case of #I, it did not grab a reference to the conversation, so it
was possible that the object would disappear!  (Or in the case of #I,
just be reused for another conversation).  Considering we are supposed
to be able to perform some non-I/O syscalls on the FD, e.g. fstat, that
seemed like a bad idea.  Plus, the reason I was doing this was to tap a
Qlisten FD (don't open it, since that'd give us a new conversation).

Calling the device open may be slightly different than the Linux
implementation, but it appears necessary due the 9ns device model.  See
https://lwn.net/Articles/356029/ for a discussion (and note the flag
where FSs could request an open op for O_NODE).

Anyway, the basic infrastructure is in place for O_PATH calls.  Devices
can do something special if they want.  If they do nothing, O_PATH will
be set, and there will be no ACC_MODE flags set on the file/chan.  The
same goes for the VFS, but I don't plan to do anything special there.

If a device does something weird on an open, such as opening a clone in
 #I, you'll get a conversation back and a chan for the Qctl, but the FD
for that chan will have no read or write permissions.

Reinstall your kernel headers.

4 years agoFix devip's permission conversion
Barret Rhoden [Fri, 11 Sep 2015 15:44:53 +0000 (11:44 -0400)]
Fix devip's permission conversion

Unfortunately, there are probably lots of conversions from omode to some
form of rwx permission, just like devpermcheck (probably due to the
independence and lack of sharing between device code).  All of these
will assume that 0 means O_READ.  In #I, they wanted just rwx, not
rwx------.  Oh well.

4 years agoRename various 9ns symbols to O_FOO (XCC)
Barret Rhoden [Thu, 10 Sep 2015 18:44:56 +0000 (14:44 -0400)]
Rename various 9ns symbols to O_FOO (XCC)

There are two sources of confusion here.  One minor one is that Plan 9
had open flags like OREAD, while we have O_READ.  Instead of #defining
them, we just use the same name.  We already were using the same value.
The other issue was the chan flags, such as CAPPEND.  Originally, these
values were not the same as their O_ counterparts, but they have been
for a little while.  There's no reason to use their old names, and doing
so was just a source of confusion.

This change was made with spatch (plan9-defines.cocci), with manual
edits of the two header files and the struct in devip.c.

This changes a kernel header, but it shouldn't affect anyone.

4 years agoClean up usage of fcntl flags (XCC)
Barret Rhoden [Thu, 10 Sep 2015 18:22:23 +0000 (14:22 -0400)]
Clean up usage of fcntl flags (XCC)

The usage of O_FCNTL_FLAGS wasn't clear, nor was the distinction between
those flags (now with 'set' in the name) and the CEXTERNAL_FLAGS.  This
area needs a bit of work, especially since many of those flags aren't
supported.  Also, it's a little weird that 9ns tracks CLOEXEC on the
chan, instead of the FD, as was previously noted.

A kernel header changed, though it shouldn't affect anyone.

4 years agoFix 9ns FD access
Barret Rhoden [Wed, 9 Sep 2015 17:11:51 +0000 (13:11 -0400)]
Fix 9ns FD access

fdtochan takes the access mode, or -1 to mean "not being used for user
access, just give me the chan".  We were doing a few weird things here
that may have been wrong.

The biggest thing was the O_TRUNC business.  We had a check that was
essentially making sure the device cleared O_TRUNC in its open call.  It
makes more sense to do that right after the open, if at all.  Also, I
don't see how fdtochan would ever get called with O_TRUNC, legitimately.
(Note that -1 sets all flags, so don't check too early!).  As it is now,
the current check will work if for some reason we have an O_TRUNC in
fdtochan's mode parameter, or anything other than what the chan really
supports.

I also dropped the == O_RDWR shortcut, as that has assumptions baked in
to it that O_RDWR means "everything".  This might break some
applications, though in that case maybe the apps or other parts of the
kernel were doing something wrong.

4 years agoPerform basic mode checks for VFS I/O
Barret Rhoden [Wed, 9 Sep 2015 15:06:36 +0000 (11:06 -0400)]
Perform basic mode checks for VFS I/O

Prior to this, you could (probably) read and write to files that lacked
the appropriate permissions.

There is a rough sort of protection, in that certain file ops don't
exist.  For instance, there is no generic_dir_write(), so directories
are never writable.  But that doesn't help when a certain type of object
(e.g. file, dir) can be writable but happens to not be for a particular
FD / struct file.

4 years agoHave perror() save errstr (XCC)
Barret Rhoden [Wed, 9 Sep 2015 17:09:24 +0000 (13:09 -0400)]
Have perror() save errstr (XCC)

perror() was occasionally losing errstr info.  The reason was that
perror was internally making syscalls, some of which would clobber
errstr.  For this reason, which is the same reason to save errno early,
we also need to save errstr early.

Rebuild glibc if you want perror to work correctly.

4 years agoFix openmode O_EXEC check in namec() [7/7]
Barret Rhoden [Tue, 22 Sep 2015 18:03:53 +0000 (14:03 -0400)]
Fix openmode O_EXEC check in namec() [7/7]

Leftover from the the assumption that '3' is the access mode and that
O_EXEC is exclusive with other access types, which it is not for us.
Maybe the latter is a bad idea, but I'm going with it for now.

4 years agoChange omode() to not special-case O_EXEC [6/7]
Barret Rhoden [Tue, 8 Sep 2015 18:54:05 +0000 (14:54 -0400)]
Change omode() to not special-case O_EXEC [6/7]

Without this change, we don't save the O_EXEC bit.  There may be some
code that breaks that requests O_EXEC without O_READ.  This is yet
another example of O_RDONLY being implied.  It looks like Plan 9 might
have been using omode() to help with this conversion, depending on what
the actual value of OREAD was for them.

4 years agoReplace IS_READONLY with an O_WRITE check [5/7]
Barret Rhoden [Tue, 8 Sep 2015 18:03:34 +0000 (14:03 -0400)]
Replace IS_READONLY with an O_WRITE check [5/7]

When saying "IS_READONLY", we were really asking whether or not we could
write, given the O_* modes.  This was a vestige of always being
readable, with the option of writable.  Checking directly for O_WRITE is
also more clear than something like IS_WRITABLE too.

Note that no one uses kchanio().  It looks like we wanted to do kernel
I/O based on a flag.

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:

http://pubs.opengroup.org/onlinepubs/009695399/functions/open.html

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:

O_RDONLY | O_WRONLY == O_RDWR

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
usecs.

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
CEQs.

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")
print
}

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

@@
@@
-get_event_q
+get_eventq_slim
 (...)

@@
@@
-get_big_event_q
+get_eventq
 (...)

@@
@@
-get_big_event_q_raw
+get_eventq_raw
 (...)

@@
@@
-get_event_q_vcpd
+get_eventq_vcpd
 (...)

@@
@@
-put_event_q
+put_eventq_slim
 (...)

@@
@@
-put_big_event_q
+put_eventq
 (...)

@@
@@
-put_big_event_q_raw
+put_eventq_raw
 (...)

@@
@@
-put_event_q_vcpd
+put_eventq_vcpd
 (...)

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)]
Remove EVENT_NOMSG (XCC)

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
hurt.

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)]
Remove EVENT_JUSTHANDLEIT (XCC)

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
listed.

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
uthread.

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)]
Remove EVENT_SPAM_FLAGS (XCC)

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
that.

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

4 years agoRename EVENT_FALLBACK -> EVENT_SPAM_INDIR (XCC)
Barret Rhoden [Mon, 3 Aug 2015 22:41:09 +0000 (18:41 -0400)]
Rename EVENT_FALLBACK -> EVENT_SPAM_INDIR (XCC)

"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
queue.
- 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
commit).

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'.