14 months ago9ns: Fix dangling negative TFs
Barret Rhoden [Thu, 26 Jul 2018 20:55:35 +0000 (16:55 -0400)]
9ns: Fix dangling negative TFs

If you remove a directory that has negative entries (but not real children
- that would fail), those negative children would keep a reference on their
parent (the directory).  When you finally marked the directory
'disconnected', you'd have a positive refcnt, so we wouldn't free it.  We'd
have a ball of disconnected references, none of which would ever get freed.

Now that directory wasn't freed.  Same with its negative entries.  So far,
it's just wasted memory.  However, since we didn't __tf_free it, we also
kept a reference on *its parent.*  But that parent doesn't have a pointer
to the original directory (it is disconnected).  Now we're leaking
references on another directory.

Later, when you unmounted the filesystem and we tried to purge everything,
we'd hit that directory with the leaked references and panic.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
14 months ago9ns: Fix issues with can_have_children
Barret Rhoden [Thu, 26 Jul 2018 20:24:13 +0000 (16:24 -0400)]
9ns: Fix issues with can_have_children

Two things:
1) We cleared can_have_children even when an rmdir failed.  Then subsequent
renames would fail, since it thought the directory was being removed.
2) We never checked can_have_children when creating files.  Maybe I had a
good reason for this, but it's not apparent.  In this case, you might be
able to add a file (or a negative dentry) to a directory while it is being

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
14 months agomnt: Identify an RPC reader by kthread, not proc
Barret Rhoden [Wed, 25 Jul 2018 18:52:51 +0000 (14:52 -0400)]
mnt: Identify an RPC reader by kthread, not proc

This fixes the dreaded mnt mismatch, e.g.:

mnt: proc current->text 18446744072670166253: mismatch from /net/tcp/1/data
? rep 0x0xffff800009cee020 tag 4 fid 1625 T120 R117 rp 5

The old code assumed the struct proc pointer uniquely identified a kernel
thread that was trying to get a response from a mnt chan.  That was never
the case, since you could have the same proc issue multiple syscalls

We had this bug since the beginning, but it was hard to trigger.  Now that
we have RCU CBs to close chans, which kick off an RKM, the kthread that
actually closes the chan is much more likely to not be for the original
process.  In that case, we're able to get the RPC response from some other
kthread, resulting in the mismatch.

Using the struct kthread to identify the kthread that is waiting on an RPC
is much saner.

I left in using current->user.name for the auth/attach name.  In those
cases, we should be in a syscall (which I check for).  Similarly, when
aborting, we just need to bail out if we are handling a process's syscall -
not if we're some arbitrary kthread.  I think.  There might be issues with

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
14 months agocheckpatch: Don't check for the SPDX header
Barret Rhoden [Mon, 30 Jul 2018 15:55:45 +0000 (11:55 -0400)]
checkpatch: Don't check for the SPDX header

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
14 months agocheckpatch: Add a dummy const_structs
Barret Rhoden [Wed, 25 Jul 2018 19:07:44 +0000 (15:07 -0400)]
checkpatch: Add a dummy const_structs

If the file is empty, it warns whenever we use a struct.  I put a dummy one
in there and it seems to shut things up.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
14 months agovmm: x86: Set the reserved bits in rflags
Barret Rhoden [Tue, 24 Jul 2018 20:46:01 +0000 (16:46 -0400)]
vmm: x86: Set the reserved bits in rflags

Previously, the kernel was doing this for us, since it thought we were
attempting to give it a bad trapframe.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
14 months agoRemove "early routine kmsg" context
Barret Rhoden [Tue, 24 Jul 2018 17:47:04 +0000 (13:47 -0400)]
Remove "early routine kmsg" context

The purpose of was to detect if an RKM/kthread had blocked since we
launched the message.  If it did, then we could be on another core, and we
didn't want to continue checking routine messages from the *old* core.

This was a little hokey, and the intent was to keep us in the PRKM while()
loop for those messages that didn't block.  However, if we just call
smp_idle() after each KMSG, it is essentially the same code.  Both cases
would do the same thing: clear the kthread's flags, report a quiescent
state, disable IRQs, reread core_id/pcpui, then check for another message.

Just calling smp_idle() adds a function call or two to the loop, but it
removes the early RKM checks and clarifies the code.  I imagine the
performance is negligble either way.

The clarity is worth a lot more.  There was at least one bug with the old
code: when we set the pcpui->cur_kthread's flags, pcpui was stale.  That
means we could have clobbered another core's kthread's flags.  At worst,
that could turn off IS_KTASK and turn on SAVE_ADDR_SPACE.  I'm not sure how
that would break anything specifically.

We had a couple cases of RKMs getting ignored (sitting in the core's queue,
but the core had halted).  I don't see exactly how problems in this area
could have caused that, so we'll see.  So far so good.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
14 months agoPrint backtraces when we do a warn()
Barret Rhoden [Mon, 23 Jul 2018 19:15:06 +0000 (15:15 -0400)]
Print backtraces when we do a warn()

Helps syzbot and our own debugging.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
14 months agox86: Handle buggy user_contexts (XCC)
Barret Rhoden [Mon, 23 Jul 2018 18:54:28 +0000 (14:54 -0400)]
x86: Handle buggy user_contexts (XCC)

If the user gave the kernel garbage for the struct user_context, we could
trick the kernel into attempting to pop certain fields that trigger faults
in the kernel, resulting in all sorts of chaos.

While looking into this for hardware TFs, I noticed a few potential
problems for SW TFs and VM TFs.

Reinstall your kernel headers at your leisure.

Reported-by: syzbot+636de6080fc1a3016e08@syzkaller.appspotmail.com
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agoqio: Fix Qmsg panic in read_all_blocks()
Barret Rhoden [Fri, 20 Jul 2018 17:25:10 +0000 (13:25 -0400)]
qio: Fix Qmsg panic in read_all_blocks()

Qmsg queues will return a full block, regardless of the number of bytes.
Short reads on Qmsg queues will have BLEN > amt, which is fine.  Those
bytes are discarded, which is what you get with Qmsg.  We simply shouldn't
panic in those cases.

Reported-by: syzbot+2c8228df3c647d4f581e@syzkaller.appspotmail.com
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agoUpdate checkpatch
Barret Rhoden [Fri, 20 Jul 2018 17:51:55 +0000 (13:51 -0400)]
Update checkpatch

The diff is from Linux, with some minor merges needed for our
customizations.  We're now up to date with Linux's commit 28c20cc73b9c
("Merge tag 'drm-fixes-2018-07-20' of

git diff c6fa8e6de3dc..linus/master scripts/checkpatch.pl > ~/cp.patch
patch -p1 < ~/cp.patch

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agoDon't chan_release() from an RCU callback
Barret Rhoden [Fri, 20 Jul 2018 14:20:56 +0000 (10:20 -0400)]
Don't chan_release() from an RCU callback

RCU callbacks are not allowed to block.  chan_release(), which is triggered
by decreffing a chan, can be triggered from an RCU callback.

Here's an example of a callchain that would have panicked:

 #01 [<0xffffffffc200b7c2>] in sem_down  (block here)
 #02 [<0xffffffffc200c221>] in cv_wait
 #03 [<0xffffffffc204ee05>] in rendez_sleep (this actually panics now)
 #04 [<0xffffffffc2039fa4>] in __qbread
 #05 [<0xffffffffc207c014>] in doread
 #06 [<0xffffffffc207c901>] in mntrpcread
 #07 [<0xffffffffc207d1a5>] in mountio
 #08 [<0xffffffffc207d3b5>] in mountrpc
 #09 [<0xffffffffc207dbfd>] in mntclunk
 #10 [<0xffffffffc2031448>] in chan_release
 #11 [<0xffffffffc2030bcb>] in kref_put
 #12 [<0xffffffffc2078be0>] in gtfs_tf_free
 #13 [<0xffffffffc2042125>] in __tf_free
 #14 [<0xffffffffc204f7e2>] in rcu_mgmt_ktask
 #15 [<0xffffffffc200acc0>] in __ktask_wrapper
 #16 [<0xffffffffc205981f>] in process_routine_kmsg
 #17 [<0xffffffffc20534a8>] in __smp_idle

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agoUse run_as_rkm() for simple functions
Barret Rhoden [Fri, 20 Jul 2018 02:12:15 +0000 (22:12 -0400)]
Use run_as_rkm() for simple functions

These were a few places where the kernel message trampoline was just a
wrapper around a single function.  There are a bunch of places where
there is a separate function that does a bunch of things in the kmsg.
I'm fine with leaving them as-is for now.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agoAdd helper to run a function as a routine kmsg
Barret Rhoden [Fri, 20 Jul 2018 00:57:05 +0000 (20:57 -0400)]
Add helper to run a function as a routine kmsg

I often want to just create a kernel message that runs a particular
function that already exists.  This helper (and its associated magic)
will do that for you.

The one slightly nasty thing is that we pass the function pointer as the
first argument.  Kernel messages run functions of type amr_t, and those
functions first argument is the source of the message.  That means we
can't just pass an arbitrary function and run it.  We used to have to
make trampoline functions - now we have a generic trampoline.

If we ever drop the message source, then we could just cast the argument
'f' to an amr_t.

Gotta love the macros.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agoAdd a macro to count the number of args to a macro
Barret Rhoden [Fri, 20 Jul 2018 00:06:43 +0000 (20:06 -0400)]
Add a macro to count the number of args to a macro

assert(MACRO_NR_ARGS() == 0);
#define foo(...) printk("Got %d\n", MACRO_NR_ARGS(__VA_ARGS__))

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agorcu: Panic if a call_rcu() CB blocks
Barret Rhoden [Thu, 19 Jul 2018 21:14:54 +0000 (17:14 -0400)]
rcu: Panic if a call_rcu() CB blocks

RCU callbacks are not allowed to block.  Here's what Linux has to say:

... the callback function must be written to be called from softirq
context.  In particular, it cannot block.

Same goes for us.  If a CB blocks, then all further CBs will be blocked
too, and the code that will wake up the first CB could also be blocked on a
later CB.

Note the distinction between RCU callbacks and RCU threads.  The threads
are critical parts of implementing RCU; they are never allowed to block on
RCU primitives.  Yes, any RCU callback will be run by an RCU thread, but
the problem is slightly different.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agorendez: Make sure we can block before sleeping
Barret Rhoden [Thu, 19 Jul 2018 21:02:02 +0000 (17:02 -0400)]
rendez: Make sure we can block before sleeping

A lot of rendezvouses don't block, but any of them could.  By checking in
advance, instead of deep in sem_down(), we'll catch those cases where we
could have blocked but rarely do.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agoSerialize console prints with the print_lock
Barret Rhoden [Thu, 19 Jul 2018 20:06:23 +0000 (16:06 -0400)]
Serialize console prints with the print_lock

When userspace writes to the console, it bypasses printk and could
interleave with the rest of the kernel prints.  Now it won't, and we can
remove yet another lock.

Note that we still will have single printk lines intermixed with userspace
characters, since userspace could be writing one byte at a time, without a
\n.  However, these writes won't interfere with multi-line printks within
the kernel.  The first line could have junk in front of it, and if that
becomes a problem, we can start putting printk("\n") in front of larger
prints (such as trapframes), like we do for panic and warnings.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agoSerialize multiline printks
Barret Rhoden [Thu, 19 Jul 2018 19:59:48 +0000 (15:59 -0400)]
Serialize multiline printks

A lot of times the kernel will do a series of printks as part of a larger
call.  Backtraces, tabs for formatting, ASCII giraffes, you name it.

To prevent these prints from interleaving with other (atomic) printks, we
can use the print_lock().  There were at least two cases where the
print_lock() replaced an already-existing spinlock that served a similar

Additionally, there were a few places that just lacked a \n, which would be
hard to read.  Those usually needed to be warn() anyway.  And of course
there was a printk("YOU SHOULD PANIC (stuff)"), which is now a panic.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agox86: Don't turn off lock tracing in the console
Barret Rhoden [Thu, 19 Jul 2018 19:03:13 +0000 (15:03 -0400)]
x86: Don't turn off lock tracing in the console

It is unnecessary.  All callers already have the tracing disabled.  And if
we do want to turn it off further, the way to do that is to turn off the
pcpui variable.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agoSupport atomic printks
Barret Rhoden [Thu, 19 Jul 2018 18:54:09 +0000 (14:54 -0400)]
Support atomic printks

printk() was atomic at the granularity of a line - most of the time.  It
wasn't for kernel faults, which leads to inscrutable bug reports.  At the
time, I avoided the lock to avoid deadlocking.  Instead, we can use a
recursive lock, which I'm not normally a fan of.

Additionally, other callers can use print_lock() to atomically print
multiple lines.  The classic example is panic() and warn().  panic() has a
few issues of its own, so we have print_unlock_force().

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agoFix tracking of lock call sites
Barret Rhoden [Thu, 19 Jul 2018 18:49:00 +0000 (14:49 -0400)]
Fix tracking of lock call sites

If we don't inline post_lock(), the call site for a lock is just
spin_lock(), which is not what we want.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agoAdd panic_hwtf() for kernel faults
Barret Rhoden [Wed, 18 Jul 2018 02:12:00 +0000 (22:12 -0400)]
Add panic_hwtf() for kernel faults

When the kernel faults, we would print the HWTF and maybe a backtrace,
and then panic.  These prints were not serialized like other panic
prints.  The new panic() would also print a backtrace of whoever called
panic, which isn't useful for faults (the stack frame was just the

panic_hwtf() will take a trapframe and print + backtrace that hw_tf
instead of backtracing the calling context.  This output will be
serialized, so the debug output from concurrent faults across multiple
cores won't be interleaved.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months ago9ns: Fix concurrent TF removal bug
Barret Rhoden [Tue, 17 Jul 2018 17:03:06 +0000 (13:03 -0400)]
9ns: Fix concurrent TF removal bug

If you had two threads removing a child from a parent at the same time,
get_locked_and_kreffed_parent() would return a TF that was not the
parent of the child.  I think the check for child->parent was from before I
deferred clearning ->parent until __tf_free().

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agogtfs: Remove the EOF optimization
Barret Rhoden [Mon, 16 Jul 2018 23:47:34 +0000 (19:47 -0400)]
gtfs: Remove the EOF optimization

Turns out this is wrong for directories (and often device files).  The
ufs server reports a directory size of 4096, which is what Linux tells
it.  We'd read 4096 bytes worth of records, and then stop.

The 9p man page says:

 The length records the number of bytes in the file. Directories
 and most files representing devices have a conventional length
 of 0.

Instead of mucking around, we'll just issue the RPC for whatever offset
we're asked for.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agox86: Use a KERNBASE address for the bootstack
Barret Rhoden [Sat, 14 Jul 2018 03:02:28 +0000 (23:02 -0400)]
x86: Use a KERNBASE address for the bootstack

Since commit 20694dda54b5 ("x86: Put the boot PMLs and stacks in BSS"),
we have been unable to backtrace from kernel_init(), up until we are on
a stack from the kernel allocator.

The reason is that the kernel backtracer checks for framepointers above
KERNBASE.  When we used an address from within the boot section, those
addresses are at the bottom of the address space.  For instance, our
stack page was around 0x50f000.

We can still use that page, which isn't present in the binary - we just
need to use the KERNBASE mapping for it.

Note we can't use the normal BSS.  That gets zeroed out manually in
kernel_init(), which is after we start using the stack.

Also note that we don't need to set the stacktop for the IDT right away.
That code was from before we had the kernel stack allocator.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agoAttempt to fix recursive panics
Barret Rhoden [Sat, 14 Jul 2018 02:05:49 +0000 (22:05 -0400)]
Attempt to fix recursive panics

Some panics can still lock up and spew a lot of text.  This helps a

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agoSerialize printing during panic()
Barret Rhoden [Fri, 13 Jul 2018 21:43:50 +0000 (17:43 -0400)]
Serialize printing during panic()

When multiple cores panicked concurrently, their output would be garbled.
They also didn't have very useful info, and I almost always wanted a
backtrace.  Now we should get each core printing on its own, including a

The monitor() call needs to happen outside the lock, so we'll wait a little
till the other cores are likely done.  They just need to wait long enough
for another core to grab the lock and set 'panic_printing'.  500ms seems to
be enough, even on Qemu.

This is only lightly tested - crazy panics under insane conditions might
break a bit more than before.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agoDon't use kmalloc in get_fn_name()
Barret Rhoden [Fri, 13 Jul 2018 21:37:33 +0000 (17:37 -0400)]
Don't use kmalloc in get_fn_name()

Back in commit 290962da6e27 ("Reflects symbol table into the kernel"), we
changed from using the old debuginfo to a autogenerated table of strings.
Those new strings are null-terminated.  The old debuginfo wasn't.
get_fn_name() needed to add the trailing \0, but we don't need to anymore.

The end result is that debug code that looks up a function name for a given
symbol, such as backtrace(), won't need to kmalloc.  This will help when we
are trying to backtrace failures in the allocator.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agoDon't use the electric fence in multithreaded code
Barret Rhoden [Tue, 10 Jul 2018 19:51:38 +0000 (15:51 -0400)]
Don't use the electric fence in multithreaded code

The efence doesn't work with uthreads.  Efence intercepts malloc() et al.
When a uthread exits, its TLS is cleaned up.  Ultimately, this calls into
glibc, which calls free() on the TLS region in _dl_deallocate_tls(). That
region was allocated with __libc_memalign() in _dl_allocate_tls_storage().
efence can intercept the free(), but not the _libc function.

Pending other changes, we shouldn't use uthreads and the efence.  One
option would be to briefly disable the efence.  Another would be to not
actually free the TLS if the efence is linked in.  Neither are good

For now, we'd like to not crash our utests.  The only code using it was
utests - some of which would break in a somewhat racy manner.

You can still link in the efence on demand.  If you do, I'd hack up your
2LS to have threads sleep forever when they finish (pthread.c, look for the

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agopthread: Allow new threads in forked children
Barret Rhoden [Mon, 9 Jul 2018 20:20:23 +0000 (16:20 -0400)]
pthread: Allow new threads in forked children

Previously, after forking, a child could not use threads at all.  Any
threads other than thread0 were ignored.  Now, older threads will still be
ignored, but new threads will run.

fork() must still be called from thread0 and while the process is an SCP.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agogtfs: Support intra-directory rename
Barret Rhoden [Wed, 27 Jun 2018 18:48:31 +0000 (14:48 -0400)]
gtfs: Support intra-directory rename

9p can handle it.  This actually has a couple benefits apart from passing a
Go test:
- No needless copies for large files
- Atomic rename for intra-directory files, which is a common pattern for
  updating a file atomically.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agogtfs: Use a kernel message to destroy the gtfs
Barret Rhoden [Wed, 27 Jun 2018 17:55:12 +0000 (13:55 -0400)]
gtfs: Use a kernel message to destroy the gtfs

You can't use blocking RCU primitives, such as rcu_barrier(), from within
an RCU callback.  Release methods, such as gtfs_release(), are often called
from a lot of contexts - anywhere you might decref - including RCU

As they say, all problems in CS can be solved with a level of indirection.
Using a kernel message decouples the work we want to do from the current
thread context, which is unable to use RCU barrier et. al.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agogtfs: Fix has_children()
Barret Rhoden [Tue, 26 Jun 2018 22:36:56 +0000 (18:36 -0400)]
gtfs: Fix has_children()

Two problems: the assert was clearly backwards, and we were using the
locked gtfs_read().  As mentioned in tree_file.h, all ops that take a
parent TF have the file qlocked.  gtfs uses that qlock for its backend
operations.  When we called gtfs_read(), we would deadlock.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months agoparlib: Fix context detection in __prep_sighandler()
Barret Rhoden [Tue, 19 Jun 2018 17:51:07 +0000 (13:51 -0400)]
parlib: Fix context detection in __prep_sighandler()

In commit f3f00eeae350 ("parlib: Fix aggressively-saved FP state for
signals"), we were checking the wrong context.  If the uthread was not
saved, its context was in VCPD.  That's why we have the ctx variable.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months agoAllow fchdir() from non-O_PATH fds
Barret Rhoden [Tue, 19 Jun 2018 17:28:04 +0000 (13:28 -0400)]
Allow fchdir() from non-O_PATH fds

If you chdir to an open FD, later when you did something like create a
file from DOT, we'd panic.  The FD in current->dot was opened and not
O_PATH, which you can't walk from (see devclone()).

The regular sys_chdir does a namec(Atodir), which does not call the
device's open, so that chan is a kernel-internal, non-open chan (to use
the parlance of devclone()).

The current fix works for most cases.  If you do something like
dfd = open(some_dir, O_READ); unlink(some_dir); fchdir(dfd);, the lookup
will fail.  Using O_PATH instead of O_READ should work.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months agoparlib: Use a relative timer for abort_sysc
Barret Rhoden [Fri, 15 Jun 2018 21:30:34 +0000 (17:30 -0400)]
parlib: Use a relative timer for abort_sysc

The issue is that the timer goes off before the syscall could block.  If
the timer was very far in the past, such as due to a go test that put the
alarm 30 seconds in the past, we would do N loops, each of which fires
instantly, until we finally set an alarm for the future.

Using a relative timer fixes that.  Also, one second is a bit much - enough
that an interactive user might notice and wonder if something is broken.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months agoSet tchain earliest/latest on any removal
Barret Rhoden [Fri, 15 Jun 2018 21:27:05 +0000 (17:27 -0400)]
Set tchain earliest/latest on any removal

Alarm handlers can put themselves back on the tchain during their handler.
The logic for that involves the earliest/latest times.  Those times should
change since the old awaiter (which is running) was yanked off.

I didn't have any actual problems with this, but it popped up as a
potential issue.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months agoparlib: Fix potential alarm corruption
Barret Rhoden [Fri, 15 Jun 2018 21:21:33 +0000 (17:21 -0400)]
parlib: Fix potential alarm corruption

The user-level alarm service is based off an older version of
kern/src/alarm.c.  That had commit f46e3e7984fb ("Fixes tchain
corruption"), but the fix never propagated to the user-level side.

There are a bunch of other differences between the kernel and user version,
which could be addressed.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months agorcu: Fix quiescent state reporting deadlock
Barret Rhoden [Fri, 15 Jun 2018 20:33:54 +0000 (16:33 -0400)]
rcu: Fix quiescent state reporting deadlock

When a core is the last to report in, it will kick the gp_ktask's rendez
variable.  That will wake the gp_ktask, and waking a ktask is done with a
kernel message.  Currently, those messages are sent to the calling core.

When we reported *after* checking the RKMs, we'd halt.  Then the GP ktask
wouldn't run.  We wouldn't see it sleeping (e.g. with "db sem"), since it
was in the process of being awake.  We wouldn't see it running either,
since it was stuck as a KMSG.  With trace_printks, we could see it went
into the rendez (rcu.c L435), but never came out.

By kicking all the cores with "trace coretf -1", we woke the system up.
I thought to try that since it would trigger a QS, but in the trace also
spat out a message for the RKM that hadn't run yet.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months agoparlib: Always align the sigdata struct
Barret Rhoden [Fri, 15 Jun 2018 19:07:33 +0000 (15:07 -0400)]
parlib: Always align the sigdata struct

The two cases were very similar, but only one had the alignment check.
Odds are, that was an oversight.  When we handled the FP state separately
based on the UTHREAD_SAVED cases, this wasn't as clear.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months agoparlib: Fix aggressively-saved FP state for signals
Barret Rhoden [Fri, 15 Jun 2018 18:59:07 +0000 (14:59 -0400)]
parlib: Fix aggressively-saved FP state for signals

In commit 5562ccb05015 ("parlib: Aggressively save and restore the FPU"),
we did not fix up the signal handling code.

The old __prep_sighandler() code was assuming that if a uthread didn't have
its GP register state saved, then it had FP state in the hardware and the
FPSAVED was not set.  This would be for e.g. HW contexts that got

With the change to aggressively save the FPU, that was not true: it was
saved and the bit was set.  Your GP state could be not saved, but your FP
state would be.

That would lead to other sorts of confusion, since the FPSAVED flag was on
for the signal handler.  That was causing an assertion when we tried to
run_current_uthread, which was a SW ctx (the signal handler).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months agox86: Handle when the PLATFORM_INFO TSC freq = 0
Barret Rhoden [Wed, 13 Jun 2018 23:55:25 +0000 (19:55 -0400)]
x86: Handle when the PLATFORM_INFO TSC freq = 0

I noticed this with QEMU 2.11.1 on an x86_64 Gentoo skylake machine.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months agoFix binutils-2.30 port (XCC)
Barret Rhoden [Wed, 13 Jun 2018 23:41:14 +0000 (19:41 -0400)]
Fix binutils-2.30 port (XCC)

Commit d3d87f64cda1 ("Updating binutils to 2.30") removed the RISCV
patch, but didn't remove it from the Makefile recipe.

Additionally, the .gitignore was still tracking 2.24 instead of 2.30.

For those keeping score, this is what happens when you hit the 'merge'
button on Github instead of fetching the branch and looking at it
locally.  You'd only notice the .gitignore by running 'git status' after
having built the new toolchain.

Rebuild your toolchain, and remove your old binutils-2.24 files, which
you can see with a 'git status.'  Feel free to keep them if you plan to
git bisect anytime soon.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months agoFix exec's proc state / owning_proc invariant
Barret Rhoden [Wed, 13 Jun 2018 22:16:20 +0000 (18:16 -0400)]
Fix exec's proc state / owning_proc invariant

We had a binary that failed the load_elf() part of the mess.  That was
after owning_proc was cleared.  proc_destroy() sent the __death message,
since we were still RUNNING_S.  That was OK some of the time, but if we had
another process running, such as the parent of the
process-who-failed-to-exec, then *that* process would get hit with the
__death (which now panics).

To avoid that, we now enforce a previously unstated (and possibly
incorrect) invariant: RUNNING_S processes are the owning_proc.  I think
this is true.  If not, it warrants a closer look.

To do so, we change the process's state very early on, ideally before
blocking, such that we can save the context (in case of recoverable
errors).  We'll change the state too (to WAITING), in accordance with the
aforementioned invariant.  Since the owning_proc and the state are synced
up, we won't get any weird __death messages meant for other processes.

Since we're moving things around, including some checks that were
previously pre-goto-error-style, I attempted to clarify the error handling.
This includes setting the error codes for the load_elf, so we can get a
decent error.  (We had been getting ENOENT, which was generated inside 9ns
during the successful path walk).

It's still a nightmare, and I'll be happy the day we can get rid of exec.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months agoMake sure __death messages hit the correct proc
Barret Rhoden [Wed, 13 Jun 2018 22:12:49 +0000 (18:12 -0400)]
Make sure __death messages hit the correct proc

Similar to __preempt, we now track the process that the message is meant
for.  AFAIK, we should not be sending __death messages to a process that
isn't the owning_proc, though it might not be the current_proc.

We had a bug where owning_proc was cleared and the __death was getting sent
to the wrong process.  Hilarity ensued.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months agoUpdating binutils to 2.30
Brian Wheatman [Mon, 11 Jun 2018 20:23:17 +0000 (16:23 -0400)]
Updating binutils to 2.30

Updating binutils from 2.24 to 2.30
Includes patch and updates to Makefile

Change-Id: Ic7a7ac38069b4079175e3def04be179fb5ca0d18
Signed-off-by: Brian Wheatman <wheatman@google.com>
16 months agoFixed NO_CTORS_DTORS_SECTIONS (xcc)
Brian Wheatman [Mon, 11 Jun 2018 20:20:33 +0000 (16:20 -0400)]

Fixed issue with __libc_global_ctors being linked
Found when updating binutils

Change-Id: I54df22c1e55428dd2c324da19e19cf495a780d0c
Signed-off-by: Brian Wheatman <wheatman@google.com>
16 months agoMove linker PROVIDE statements inside sections
Barret Rhoden [Mon, 11 Jun 2018 20:01:14 +0000 (16:01 -0400)]
Move linker PROVIDE statements inside sections

Newer versions of binutils seem to require having the PROVIDE keyword
inside a specific section, instead of just floating between sections.

Specifically, on x86, binutils-2.30 was assigning all symbols outside a
section the value of the kernel load address (0xffffffffc2000000 or
whatever).  This included the linkerfuncs, the devtab, end, and etext.  The
bss symbols were OK.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months agoradix: Use call_rcu() to free r_nodes
Barret Rhoden [Fri, 8 Jun 2018 16:42:11 +0000 (12:42 -0400)]
radix: Use call_rcu() to free r_nodes

The radix code can be called from call_rcu().  That means it can't use
blocking RCU primitives, such as synchronize_rcu().  Alternatively, we
could have a racy destruction primitive, but that didn't seem worth the

For those curious, you could trigger this bug by deleting a moderately
sized file that was in the page cache.  e.g.

$ get_html; rm bin/get_html

You'll get a panic / BT similar to this:

 #02 [<0xffffffffc2058932>] in synchronize_rcu
 #03 [<0xffffffffc205741f>] in __radix_remove_slot
 #04 [<0xffffffffc2057566>] in rnode_for_each
 #05 [<0xffffffffc20574e8>] in rnode_for_each
 #06 [<0xffffffffc20578db>] in radix_for_each_slot
 #07 [<0xffffffffc204f9af>] in pm_destroy
 #08 [<0xffffffffc203fdcb>] in cleanup_fs_file
 #09 [<0xffffffffc204a418>] in __tf_free
 #10 [<0xffffffffc204a4a0>] in __tf_free_rcu
 #11 [<0xffffffffc2057f92>] in rcu_exec_cb
 #12 [<0xffffffffc2058232>] in rcu_mgmt_ktask

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months agorcu: Do not let RCU callbacks block on RCU
Barret Rhoden [Fri, 8 Jun 2018 16:11:12 +0000 (12:11 -0400)]
rcu: Do not let RCU callbacks block on RCU

The callbacks are run from a ktask.  If the callbacks attempt to block on
RCU with e.g. rcu_barrier() or synchronize_rcu(), we'll deadlock.  The
ktask blocks on RCU callbacks, but the ktask is the only thing that will
run the callbacks.

As far as I can tell, this is also illegal on Linux.  For instance, this
will throw a bunch of errors at runtime on Linux:

static void __cb(struct rcu_head *h)
    printk(KERN_INFO "about to sync\n");
    // works only if we comment this out, dies otherwise

static void foo(void)
    struct rcu_head head[1];

    call_rcu(head, __cb);

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months agoAdd the 'current_kthread' helper
Barret Rhoden [Fri, 8 Jun 2018 16:01:33 +0000 (12:01 -0400)]
Add the 'current_kthread' helper

Similar to current and current_ctx.  Those remain unchanged functionally,
but they now use the pcpui accessors.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months agoHandle threading after a fork() (XCC)
Barret Rhoden [Thu, 7 Jun 2018 18:59:28 +0000 (14:59 -0400)]
Handle threading after a fork() (XCC)

Threading and fork() do not go together well, especially user-level
threads.  The kernel won't let you fork() an MCP.  However, you can have a
threaded SCP - dropbear is one such example.  It uses the pthread 2LS, but
just happens to be on one core.

Dropbear uses threads internally in its implementation of tty.c.  There are
two threads: one for pushing inbound traffic and another for outbound
traffic between the network and the child's pipes.

Recall another pain in the ass with fork: duplicated state between the
child and parent.  We have a bunch of things implemented in userspace, such
as select() and an alarm service.  Those are FDs that get carried over to
the child.  We have the "fork callbacks" to clean that stuff up.

Now, what happens when you fork a threaded process?  Its forked thread
returns in the child, and the child also has all of the memory structures
for the other threads.  If you exec() immediately, that all gets blown
away.  However, if that thread happens to block on a syscall, then the 2LS
takes over and it can run those other threads.

In dropbear's case, it returns from the fork, it closes the tty threads'
FDs (in one of its functions, not in a fork-cb), does a few other things,
etc.  One of those things was chdir(), which happens to block.  The reason
for that is chdir() calls synchronize_rcu(), which can block until the GP
ktask runs, at least under the current settings.

Once the thread (thread0) blocks in chdir, the other threads run.  However,
their FDs were closed, so they'll return an error.  Depending on whether or
not you have the DB bug fix, it'll either segfault under some circumstances
or just error out with a data_flow error.

To fix this, we now require all 2LSs that want to support forking to have
explicit support.  The thread0 sched trivially supports this.  The pthread
2LS will allow you to fork only from thread0, and it will suspend threading
for the duration of the fork in both the parent and the child.  During that
time, only thread0 will run.  After the fork(), the parent will resume
threading.  In the child, we'll never thread.  Those other threads will sit
on the ready_queue forever and will never run.  In DB's case, we don't want
them to run, since their FDs are closed.

Also, note that this is only a problem for the child, not the parent.
Further, SYS_fork will never appear to block for the child.  The syscall is
marked 'finished' before the child is RUNNABLE_S.

In general, let's just try to stop using fork().

Rebuild glibc, your shells, and dropbear.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months agoparlib: Add the uthread_is_thread0() helper
Barret Rhoden [Thu, 7 Jun 2018 18:58:12 +0000 (14:58 -0400)]
parlib: Add the uthread_is_thread0() helper

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months agoFix __this_cpu_add() typo
Barret Rhoden [Tue, 29 May 2018 21:15:09 +0000 (17:15 -0400)]
Fix __this_cpu_add() typo

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agoAdd BSD's LIST_PREV
Barret Rhoden [Wed, 9 May 2018 19:23:13 +0000 (15:23 -0400)]

From commit aa34e24a277b ("Report TRAP_BRKPT for breakpoint traps on

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agoRemove 'fs' from the gitignore
Barret Rhoden [Thu, 3 May 2018 17:39:24 +0000 (13:39 -0400)]
Remove 'fs' from the gitignore

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agoPort Linux's percpu_counters
Barret Rhoden [Fri, 4 May 2018 22:33:17 +0000 (18:33 -0400)]
Port Linux's percpu_counters

Note the hokey per_cpu_ptr(x) -> _PERCPU_VARPTR(*x).

Also, these aren't as big as the WARNING says - neither are Linux's, I

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agoSpatch Linux's percpu_counter
Barret Rhoden [Thu, 3 May 2018 19:44:51 +0000 (15:44 -0400)]
Spatch Linux's percpu_counter

Some of these might have been done manually.  I was fixing up the cocci
files concurrently.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agoImport Linux's percpu_counter
Barret Rhoden [Thu, 3 May 2018 19:43:02 +0000 (15:43 -0400)]
Import Linux's percpu_counter

From commit 569dbb88e80d ("Linux 4.13").

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agoUpdate Linux's cocci files
Barret Rhoden [Thu, 3 May 2018 18:18:40 +0000 (14:18 -0400)]
Update Linux's cocci files

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agoUpdate per-cpu helpers in compat_todo
Barret Rhoden [Fri, 4 May 2018 22:32:10 +0000 (18:32 -0400)]
Update per-cpu helpers in compat_todo

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agoAdd support for dynamic per-cpu variables
Barret Rhoden [Fri, 4 May 2018 21:51:01 +0000 (17:51 -0400)]
Add support for dynamic per-cpu variables

They are a little hokey.  You get a pointer back, which you have to
dereference each time you use it, even when you want to get a pointer to
a specific core's pointer.  That's different than Linux.  e.g.

u64 *foo = percpu_alloc(u64, MEM_WAIT);
u64 *core_3_ptr = _PERCPU_VARPTR(*foo, 3);

This is because __PERCPU_OFFSET computes &(var), which is how the static
stuff works.  We need to compute the offset from whatever our allocator got
back, which foo, so we need to balance the & with the *.  Not ideal.

Also, there is a limited amount of space - 1024 for now.  We could do
better with a virtual memory region:
- alloc vaddrs for the right size (2x previous)
- map that to the paddr of the previous, existing space
- map the new space (1x previous) above the existing space
- WRITE_ONCE percpu_base.
- maybe free old vaddr after a grace period, which would imply all per-cpu
  accessors are RCU read-side critical sections.

Not worth doing, for now.  It might be a pain to shrink it too.

The right approach might be to port more of Linux's percpu mechanisms.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agoktest: Add minor fixes for kernel tests
Barret Rhoden [Fri, 4 May 2018 21:41:39 +0000 (17:41 -0400)]
ktest: Add minor fixes for kernel tests

The main thing is the convenience program 'ktest', which you can run via

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agorcu: Implement RCU
Barret Rhoden [Thu, 26 Apr 2018 19:57:09 +0000 (15:57 -0400)]
rcu: Implement RCU

Our RCU is similar to Linux's rcu_sched - we don't do the same things they

A lot of the changes to the Linux headers were me removing things I'm
fairly sure we won't need, so don't worry about that.  The bulk of this
commit is rcu.c, which implements call_rcu() and rcu_barrier() - which is
the heart of any RCU implementation.

Though note the locations in the rest of the kernel where we call
rcu_report_qs() - those are the locations where we know we aren't in a
read-side critical section.

The big difference between our RCU and Linux's implementation is that we do
not interfere with the CG cores.  We do not use softirq processing or timer
ticks for either callbacks or reporting quiescent states.

call_rcu() callbacks from CG cores do not run on the cores where they were
queued up.  There is a penalty for cache misses for this, but it prevents
us from interfering with the app.  Otherwise, once a grace period elapses,
we'd either have to wait for the user to enter the kernel or we'd have to
force them to.  You could imagine a middle ground where we let a callback
sit for a while or try to work-steal it.

We can check from a management core (core 0) to see if a CG core is in
userspace or idle.  This is similar to what Linux does with dynticks, I
think.  We also expedite the grace periods, though we can change that.

We use Linux's tree structure for tracking quiescent states, but all cores
use the global gpnum to find out which gpnum we're dealing with.  If that
turns out to be a scalability problem, then we can deal with it later.  I
didn't want to deal with certain cores having old gps.

As far as the timing parameters, I went with 25 msec since it wasn't a
multiple of the kernel scheduler tick.  If it is having an effect on FTQ
numbers, being at another frequency will make it stand out.

This hasn't been tested heavily; there are mostly likely bugs and almost
surely memory barrier problems that might require another architectures.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agorcu: Add Linux headers and helpers
Barret Rhoden [Thu, 19 Apr 2018 16:35:14 +0000 (12:35 -0400)]
rcu: Add Linux headers and helpers

These have more than we need, but a lot of it will be useful for us.

From commit 569dbb88e80d ("Linux 4.13").  rcu_helper.h was
kernel/rcu/rcu.h and rcu_tree_helper.c was from kernel/rcu/tree.c.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agoAdd a few smp_ helpers from Linux.
Barret Rhoden [Wed, 11 Apr 2018 20:47:01 +0000 (16:47 -0400)]
Add a few smp_ helpers from Linux.

I'll need these for RCU - at least to keep that code a little cleaner.

From commit 569dbb88e80d ("Linux 4.13").

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agoFix some minor Linux spatch / conversions
Barret Rhoden [Fri, 27 Apr 2018 20:50:43 +0000 (16:50 -0400)]
Fix some minor Linux spatch / conversions

I noticed these while attempting to port the RCU torture tests.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agoAllow PERCPU array types
Barret Rhoden [Fri, 27 Apr 2018 16:22:33 +0000 (12:22 -0400)]
Allow PERCPU array types

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agoAdd arch/membar.h
Barret Rhoden [Wed, 11 Apr 2018 20:30:03 +0000 (16:30 -0400)]
Add arch/membar.h

I have a few things I want to add that will be kernel-only for now.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agoAdd a bulk interface to sem_down()
Barret Rhoden [Thu, 26 Apr 2018 18:36:47 +0000 (14:36 -0400)]
Add a bulk interface to sem_down()

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agosched: Catch the lack of a scheduler type
Barret Rhoden [Wed, 11 Apr 2018 19:44:11 +0000 (15:44 -0400)]
sched: Catch the lack of a scheduler type

If this happens, it might be a Makefile bug or a buggy .config file.
The #error is a little easier to diagnose.  I got this when I screwed up
the Makefile and turned a CFLAGS -> FLAGS for the CONFIG_ vars.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agoRemove ONE_xBYTE #defines
Barret Rhoden [Wed, 11 Apr 2018 19:43:48 +0000 (15:43 -0400)]
Remove ONE_xBYTE #defines


Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agoFix "error macro requires 3 arguments" problem
Barret Rhoden [Thu, 19 Apr 2018 19:12:22 +0000 (15:12 -0400)]
Fix "error macro requires 3 arguments" problem

If you try to use the compile_time_assert, for whatever reason, some black
magic in the preprocessor thinks there's a call to error (standalone) in
there, which is the Plan 9 error throwing macro.  It breaks in a nasty way.

I don't know exactly what Linux is doing here, but renaming fixes it.  This
probably means we can't have a macro called error_foo() either.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agoUse Linux's compiler headers (XCC)
Barret Rhoden [Wed, 11 Apr 2018 19:29:16 +0000 (15:29 -0400)]
Use Linux's compiler headers (XCC)

This required a few things.  The easy ones were removing our old #defines
for things that Linux's compiler headers handle, e.g. unlikely.  The
tougher things included allowing the use of 'extern inline' and using
__percpu for our own use.  See k/i/compiler.h for details.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agoCopy Linux's compiler.h
Barret Rhoden [Wed, 11 Apr 2018 17:27:47 +0000 (13:27 -0400)]
Copy Linux's compiler.h

There are a couple things that Linux has that I'd like to use.  Plus, it's
just a matter of time until we have some horrible bug that we could have
caught by using the stuff instead of rolling our own.  The compiler headers
are less about the OS and more about using the compilers to write an OS.

From commit 569dbb88e80d ("Linux 4.13").

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agoUpdate Linux's list.h
Barret Rhoden [Mon, 9 Apr 2018 18:29:55 +0000 (14:29 -0400)]
Update Linux's list.h

Up to date with 569dbb88e80d ("Linux 4.13").

Basically generate a patch on Linux:

$ git diff bc208e0ee0f4..HEAD include/linux/list.h > ~/foo.patch

And apply it to Akaros:

$ cd kern/include/
$ patch -p3 < ~/foo.patch

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agoMove PASTE() to common.h
Barret Rhoden [Mon, 23 Apr 2018 17:32:58 +0000 (13:32 -0400)]
Move PASTE() to common.h

We had it defined in two locations.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agoAdd pcpui helpers
Barret Rhoden [Mon, 23 Apr 2018 17:14:38 +0000 (13:14 -0400)]
Add pcpui helpers

This commit adds minor helpers for managing per-cpu stuff in smp.h and
shows how to use some of the helpers in syscall.c.

We have two sets of per-cpu data: pcpui (the struct in smp.h) and PER_CPU,
which uses a special section.  Both are accessed by indexing off core_id,
which isn't ideal.  Each reference is a fresh core_id() call; it's fast
(especially now) but not free.

pcpui allows for easy reuse of the pcpui pointer, but all structures need
to be in smp.h.  Perhaps both systems should use gs-relative addressing.
For now, using one of the other is just a matter of convenience.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months ago9ns: Remove CCACHE
Barret Rhoden [Fri, 6 Apr 2018 19:36:37 +0000 (15:36 -0400)]
9ns: Remove CCACHE

That was a chan flag that said we were using #mnt's old cache.  It is
unused now, since #gtfs handles all the caching transparently.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months ago9ns: mnt: Don't use a 'bogus' struct
Barret Rhoden [Fri, 6 Apr 2018 19:34:13 +0000 (15:34 -0400)]
9ns: mnt: Don't use a 'bogus' struct

That struct we pass through is mntparams, and they should be kept in sync.
Not sure why Plan 9 / Inferno ever used that crappy bogus struct - maybe a
header problem.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months ago9ns: Support setting FD flags (XCC)
Barret Rhoden [Fri, 6 Apr 2018 19:14:52 +0000 (15:14 -0400)]
9ns: Support setting FD flags (XCC)

Similar to back in the VFS code, I'm not entirely happy supporting the
toggling of these flags.  Ideally, we wouldn't even have e.g. FD_CLOEXEC.

Reinstall your kernel headers

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months ago9ns: Implement fsync with chan_ctl
Barret Rhoden [Fri, 6 Apr 2018 18:27:02 +0000 (14:27 -0400)]
9ns: Implement fsync with chan_ctl

If you fsync on a directory, we'll sync the entire FS for the given device.
You can use the sync helper to cause fsyncs.

Note your bind order matters.  If you mount or bind with "-a", it'll be at
the bottom of the union mount list.  You probably want -b.  For example:

$ mount -a -c -C /srv/some_chan /mnt
$ sync /mnt  # this calls #kfs.chan_ctl

That will sync kfs's /mnt, not gtfs's, since both kfs and gtfs have a chan
at /mnt/ that can be opened.

$ mount -b -c -C /srv/some_chan /mnt
$ sync /mnt  # this calls #gtfs.chan_ctl

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months ago9ns: Make chan_ctl() mandatory
Barret Rhoden [Fri, 6 Apr 2018 15:55:48 +0000 (11:55 -0400)]
9ns: Make chan_ctl() mandatory

Previously, chan_ctl was optional; it was the device's opportunity to do
something, including say 'no', when we set the chan flags.  Instead,
devices must clearly say they will support it.

Part of the issue was the old chan_ctl didn't actually have multiple
operations.  The implied operation was 'set fl.'  That won't work for other
upcoming uses of chan_ctl, such as fsync.  Devices may support e.g. fsync
but not changing flags.

Note we don't have CCTL_GET_FL - the caller already has the chan and its
flags.  The device has nothing to do with it.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months ago9ns: Add a helper for getting chan's device's name
Barret Rhoden [Fri, 6 Apr 2018 15:24:58 +0000 (11:24 -0400)]
9ns: Add a helper for getting chan's device's name

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months ago9ns: kfs: Give the CPIO blob to the base arena
Barret Rhoden [Thu, 5 Apr 2018 20:58:20 +0000 (16:58 -0400)]
9ns: kfs: Give the CPIO blob to the base arena

The CPIO's contents are extracted and exist in KFS's structures.  It is
unused at this point, and unlike the old KFS, it won't be used during
regular operation.  The old KFS would use the CPIO as the backing store for

This might trigger a couple bugs, since the allocator will be handing out
more data that isn't already zeroed.  Perhaps there are other bugs with
memory being below _end (and below the boot allocator).  That should be
fine though, just be careful.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months ago9ns: Add #gtfs
Barret Rhoden [Thu, 5 Apr 2018 19:03:14 +0000 (15:03 -0400)]
9ns: Add #gtfs

gtfs is a generic tree file system that uses a somewhat arbitrary 9p device
for its backend - specifically #mnt.  #gtfs is the frontend caching layer
for the backend.  It has a page cache, a tree_file tree with RCU-protected
lookups, 'negative' entries, etc - all the things you'd expect.  If the
backend supports symlinks, then it would do that too.  Currently, #mnt does

With this in place, we can mount 9p servers and execute binaries over 9p
with mmap, which wasn't possible before.

The neat thing about it is that it required no changes to the mount driver.

Brief background: the #mnt device is given a channel to a 9p fileserver and
attaches itself in your namespace.  You do an 'ls', which gets converted
into a bunch of operations in the kernel, and the #mnt device converts
those ops to 9p RPCs.  End result: it looks like the remote filesystem is
in your namespace.

The #gtfs takes a channel to *another* device, in this case the #mnt from
above, and when the kernel wants to do a bunch of ops, #gtfs uses the
tree_file code and page cache as a cache.  When it is missing certain info,
it talks to #mnt and gets the info from the remote server.  It does the
same trick as #mnt: take a channel that speaks a version of the 9p
protocol, and convert between two interfaces.  The difference?  #mnt uses
the RPC interface for 9p.  #gtfs uses the in-kernel *functional* interface
for 9p - which is the function pointers in struct dev (e.g. open, close,
read, write, etc).

You can see the caching layer's effect by watching the RPCs to the
fileserver.  When you do an ls, you see a read of the directory (readdir)
followed by a bunch of stat calls, which is the essence of ls.  If you do a
subsequent ls, you just see the read again.  No need to do the stat, since
the frontend cache already has the info.  Why do you need the read again,
you ask?  Because the frontend is a partial cache, and it doesn't
necessarily know about every file in a directory/tree.  So it checks with
the backend (the 9p server).  But for the files it has, it has all of the

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agoUse READ_ONCE() for seq counters (XCC)
Barret Rhoden [Thu, 5 Apr 2018 17:37:14 +0000 (13:37 -0400)]
Use READ_ONCE() for seq counters (XCC)

READ_ONCE() is like ACCESS_ONCE(), just clearly a read.

There are concurrent writes to the field, ordering matters, etc.  In
seqctr_retry, it was possible for the compiler to generate two reads from
the data structure for the "is locked" and "!=" tests.  We might have had
strange results there.

The seq stuff might need a closer look.

Reinstall your kernel headers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months ago9ns: Clarify a couple struct dev fields
Barret Rhoden [Thu, 5 Apr 2018 16:46:06 +0000 (12:46 -0400)]
9ns: Clarify a couple struct dev fields

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agopm: Remove the venerable pm_remove_contig()
Barret Rhoden [Tue, 3 Apr 2018 19:42:44 +0000 (15:42 -0400)]
pm: Remove the venerable pm_remove_contig()

It did a lot, but was more complicated than we needed.  It also might have
been doing too much.

It was responsible for attempting to remove pages even if they were being
used by an active mmaping - shootdown, collect dirty bits, writeback, unmap
for real and catch any intermediate users, etc.  I'm not sure we need all
of that, and if we do, maybe we'll fix the PM / MM code before that (more
scalable structures, huge pages, etc).

It also was marking PTEs not present before checking their dirty bits.
That might not be necessary for all uses.  It looks like we wanted to force
any users to fault, which would trigger a pm_load_page, which would clear
the removal flag.  Not 100% on that.  Be careful if you use that old code.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agopm: Add pm_free_unused_pages()
Barret Rhoden [Tue, 3 Apr 2018 19:38:50 +0000 (15:38 -0400)]
pm: Add pm_free_unused_pages()

Devices can call this if they want to free a little memory.  It's a little
niche, since it only really helps with open files that are not mmapped.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agopm: Add pm_writeback_pages()
Barret Rhoden [Mon, 2 Apr 2018 18:58:23 +0000 (14:58 -0400)]
pm: Add pm_writeback_pages()

This allows a TFS/user to writeback an individual file.  It required a few
changes, mostly to buggy PM helpers.  I think pm_remove_contig() isn't
doing the right thing for ranges where index isn't in the VMR, but the
range is.  Not a huge deal - that code is going away soon.

Single-page WB is a little slow, though the real slowdown is using a 9p
server - individual writes take forever.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agoFix up bind and mount
Barret Rhoden [Mon, 2 Apr 2018 15:40:37 +0000 (11:40 -0400)]
Fix up bind and mount

mount was a copy-paste from bind, but it was improved over time to have
more than one flag; bind still couldn't.

Apart from that fix, I also touched up the formatting and trailing
whitespace a bit.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months ago9ns: Add MEM_WAIT in a few places
Barret Rhoden [Sun, 1 Apr 2018 23:37:22 +0000 (19:37 -0400)]
9ns: Add MEM_WAIT in a few places

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agomm: Hold the pte_lock when doing a memwalk
Barret Rhoden [Thu, 29 Mar 2018 21:33:50 +0000 (17:33 -0400)]
mm: Hold the pte_lock when doing a memwalk

I think all the callers hold that lock.  There are probably other places
that are messing that up.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agomm: Don't decref files while holding a lock
Barret Rhoden [Thu, 29 Mar 2018 21:33:16 +0000 (17:33 -0400)]
mm: Don't decref files while holding a lock

Yes, this code is nasty and needs an overhaul - notably the removal of that

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agoAdd pte_clear_dirty()
Barret Rhoden [Thu, 29 Mar 2018 21:32:40 +0000 (17:32 -0400)]
Add pte_clear_dirty()

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agomm: Catch allocation failure
Barret Rhoden [Thu, 29 Mar 2018 18:54:53 +0000 (14:54 -0400)]
mm: Catch allocation failure

Given all this code is hokey, at least we'll panic instead of crashing.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agopm: Allow RCU lookups and qlocked updaters
Barret Rhoden [Thu, 29 Mar 2018 18:42:22 +0000 (14:42 -0400)]
pm: Allow RCU lookups and qlocked updaters

We're going to need to do writeback, and the easiest way to do that is to
hold a qlock on our callback.  We can't just replace the old pm spinlock
with a qlock, since it is grabbed by other spinlock holders (old VMR code,
both for pm_add_vmr and for pm_load_page_nowait()).

Also, this allows lockless lookups, which is nice.

Overall, the VMR and PM/radix code still needs a lot of structural work,
possibly involving thinking more about huge pages.  For now, this is a
modest change and we'll keep the basic infrastructure in place - enough
that we can make progress with the TFS code.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
17 months agopm: Implement pm_remove_or_zero_pages()
Barret Rhoden [Thu, 29 Mar 2018 15:35:15 +0000 (11:35 -0400)]
pm: Implement pm_remove_or_zero_pages()

This is what truncate/hole-punch really wants - best effort, and zero if
all else fails.  pm_remove_contig() tries to do too much, and doesn't
handle the failure cases.

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