akaros.git
15 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
think.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 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>
15 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>
15 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>
15 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>
15 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>
15 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
ssh.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 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
do with CONFIG_PREEMPT.

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>
15 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>
15 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>
15 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>
15 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>
15 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>
15 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>
15 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>
15 months agoRemove ONE_xBYTE #defines
Barret Rhoden [Wed, 11 Apr 2018 19:43:48 +0000 (15:43 -0400)]
Remove ONE_xBYTE #defines

Unused.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 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>
15 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>
15 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>
15 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>
15 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>
15 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>
15 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>
15 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>
15 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>
15 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>
15 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>
15 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>
15 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
readpage().

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>
15 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
not.

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

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 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>
15 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>
15 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>
15 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>
15 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>
15 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>
15 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>
15 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>
15 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
spinlock.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 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>
15 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>
15 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>
15 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>
15 months agopm: Implement pm_destroy()
Barret Rhoden [Thu, 29 Mar 2018 15:33:57 +0000 (11:33 -0400)]
pm: Implement pm_destroy()

We had been just leaking memory.  Though it is hard to see this, since all
of the pages are actually just sitting in slab magazines, and not freed all
the way back to the arenas.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agoradix: Implement radix_tree_destroy()
Barret Rhoden [Wed, 28 Mar 2018 20:33:38 +0000 (16:33 -0400)]
radix: Implement radix_tree_destroy()

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agoradix: Add for_each iterators
Barret Rhoden [Wed, 28 Mar 2018 20:32:36 +0000 (16:32 -0400)]
radix: Add for_each iterators

These will help with implementing various page cache helpers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months ago9ns: Allow racy truncations
Barret Rhoden [Tue, 27 Mar 2018 22:27:28 +0000 (18:27 -0400)]
9ns: Allow racy truncations

I'm relaxing the consistency guarantees during truncate/hole_punches.  If
you do concurrent reads, writes, or mmaps during truncate, you might get
weird data: old, new, or a combination of the two.

My primary desire for this is to avoid qlocking the file during what could
be parallel operations: reading or writing to non-overlapping parts of a
file.

Part of this is that the qlock is not held during pm_load_page, especially
for mmap faults.  In an alternate version of this code, pm_load_page held
the qlock, the PM op didn't need to grab the lock, and every mmap hard
fault (i.e. not the nowait, the one with pm_load_page that blocks) would
qlock.  Soft faults (the read fast-path) wouldn't qlock.

I'm not 100% on this, so I haven't squashed this into the original FS file
work.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agomm: Mark dirty pages when we munmap
Barret Rhoden [Mon, 26 Mar 2018 16:06:44 +0000 (12:06 -0400)]
mm: Mark dirty pages when we munmap

The page cache will need to know which pages are dirty.  I might
overhaul the PM code, but regardless this is a bug and needs to be done
- one way or another.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months ago9ns: Add LRU support to tree filesystems
Barret Rhoden [Mon, 26 Mar 2018 14:11:51 +0000 (10:11 -0400)]
9ns: Add LRU support to tree filesystems

Any non-RAMFS will want some form of access to the LRU list.  These
devices will use tree files as caches, referred to as the frontend.  The
"real" filesystem will be elsewhere: typically on a 9p server, though a
disk FS would work as well.

Since the tree_file tree is a cache, both the TFs and the page cache for
the files, devices may want to shed their caches when memory becomes
tight.

Similarly, devices may want to perform their own work on the LRU list.
For instance, the #gtfs device, which fronts #mnt, will want to
periodically prune its open FIDs to the backend 9p server.  Stay tuned.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months ago9ns: Make QTFILE == 0. Goddamn 9p
Barret Rhoden [Tue, 20 Mar 2018 19:55:00 +0000 (15:55 -0400)]
9ns: Make QTFILE == 0.  Goddamn 9p

This is annoying, but translating qids back and forth just for one bit
isn't worth the bugs.

Zero wouldn't be as bad if there were a bunch of *values* for qid.type, so
that we're just doing == checks or switches  (still, don't use zero).  But
it's bits!  The worst possible decision.

This is OK, and you see it everywhere:

c->qid.type & QTDIR

this isn't, since QTFILE has the value 0:

c->qid.type & QTFILE

This is the same shit with O_READ modes.

Goddamn.

Told-off-by: Barret Rhoden <brho@cs.berkeley.edu>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agoexec: Clear owning proc earlier
Barret Rhoden [Tue, 20 Mar 2018 19:47:13 +0000 (15:47 -0400)]
exec: Clear owning proc earlier

We're supposed to clear as soon as we could block, but foc_open() can block
(as the comment says).

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months ago9ns: Add the cache option (-C) to mount
Barret Rhoden [Fri, 16 Mar 2018 20:02:47 +0000 (16:02 -0400)]
9ns: Add the cache option (-C) to mount

That needs cleaned up a bit, including exporting the mount flags in the
kernel interface.  Same probably goes for bind.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months ago9ns: Remove the old mnt cache
Barret Rhoden [Fri, 16 Mar 2018 19:59:19 +0000 (15:59 -0400)]
9ns: Remove the old mnt cache

Plan 9 had a write-through, data only cache.  It would speed up reads,
and it assumed no one else was writing to the server, which is fine.
Since it was write-through, it never needed to sync to the backend.

The tree_file version of #mnt will use the TFS for its caching, so we
don't need the older caching layer - which actually didn't do anything
on Akaros.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months ago9ns: Clean up the dir->mode bits
Barret Rhoden [Thu, 15 Mar 2018 15:32:16 +0000 (11:32 -0400)]
9ns: Clean up the dir->mode bits

The lower 9 bits are the classic rwxrwxrwx bits.  The upper bits contain
things like "is a directory."

'mode' is a bit confusing, especially if you are familiar with the
POSIX/glibc world.  dir->mode is the permissions, which we get from the
'perm' argument to create (i.e. SYS_openat with O_CREATE).  That is
different from the 'mode' argument to open(), which is the e.g. O_RDWR
flags for the *chan* (file in Unix) - not the filesystem file (inode in
Unix).

Good times.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agostrace: Report errno and errstr on failure
Barret Rhoden [Wed, 14 Mar 2018 19:40:44 +0000 (15:40 -0400)]
strace: Report errno and errstr on failure

I got tired of looking at straces, knowing there was an error, and
wondering what the errno/errstrs were.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months ago9ns: Support rename
Barret Rhoden [Wed, 14 Mar 2018 17:27:37 +0000 (13:27 -0400)]
9ns: Support rename

Devices without a rename operation just get an EXDEV.  Usually userspace
can handle that (e.g. busybox's mv).

I added rename to the struct dev ops since it should be a 9p operation,
allowing renames across directories.  9p wstat does allow an
intra-directory rename, but that's not really what you want.  By giving
the device the old chan, the parent chan, and the name, it can
atomically perform the rename.  Atomicity is a critical part of rename.

Previously, we tried mucking around with rename and wstat, and it was
missing some of the namec-magic associated with Acreate (findmounts and
other stuff).  The device wasn't given the parent chan - it had to find
that on its own, and I was worried that there were some TOCTTOU races if
we just gave it the path.

Additionally, the device may need to do various "version" checks, which
can be done in a dev.rename op, but are harder to do generically.  See
tmpfs for an example.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months ago9ns: Add #tmpfs
Barret Rhoden [Tue, 13 Mar 2018 21:43:16 +0000 (17:43 -0400)]
9ns: Add #tmpfs

The tmpfs device can have many instances, each of which are separate
filesystem trees.  When you close the last chan into the instance,
whether that was by unmounting it or by closing an open FD, it will
destroy itself.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agopm: Track the fs_file instead of the inode/blockdev
Barret Rhoden [Tue, 20 Mar 2018 19:53:11 +0000 (15:53 -0400)]
pm: Track the fs_file instead of the inode/blockdev

This is somewhat left over from the VFS removal.  The 9ns devices (ramfs)
were just zeroing memory, so they didn't care.  But we'll eventually need
the actual fs_file.

The PM code needs a much bigger overhaul, but this is the minimum to get
things working.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agokfs: Remove a few old debugging files
Barret Rhoden [Mon, 12 Mar 2018 17:52:41 +0000 (13:52 -0400)]
kfs: Remove a few old debugging files

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agovfs: Remove vfs.h
Barret Rhoden [Mon, 12 Mar 2018 17:49:15 +0000 (13:49 -0400)]
vfs: Remove vfs.h

e.g. this, plus a few missing #includes.

find kern/ -name '*.c' -exec sed -i '/#include <vfs.h>/d' '{}' \;

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agovfs: Move FD management code to 9ns
Barret Rhoden [Mon, 12 Mar 2018 17:56:37 +0000 (13:56 -0400)]
vfs: Move FD management code to 9ns

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agovfs: Remove the last references to struct file *
Barret Rhoden [Thu, 8 Mar 2018 02:06:17 +0000 (18:06 -0800)]
vfs: Remove the last references to struct file *

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agovfs: Remove the guts of the VFS
Barret Rhoden [Thu, 8 Mar 2018 01:32:01 +0000 (17:32 -0800)]
vfs: Remove the guts of the VFS

Left the FD stuff around.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agovfs: Remove misc tests
Barret Rhoden [Mon, 12 Mar 2018 00:48:40 +0000 (20:48 -0400)]
vfs: Remove misc tests

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agovfs: Remove monitor functions
Barret Rhoden [Wed, 7 Mar 2018 22:00:20 +0000 (14:00 -0800)]
vfs: Remove monitor functions

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agovfs: Remove KFS, blockdev and devfs
Barret Rhoden [Wed, 7 Mar 2018 21:57:24 +0000 (13:57 -0800)]
vfs: Remove KFS, blockdev and devfs

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agovfs: Remove fs_env from struct proc
Barret Rhoden [Wed, 7 Mar 2018 21:26:18 +0000 (13:26 -0800)]
vfs: Remove fs_env from struct proc

Part of removing the VFS.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agovfs: Remove ext2 support
Barret Rhoden [Wed, 7 Mar 2018 21:04:04 +0000 (13:04 -0800)]
vfs: Remove ext2 support

It only half worked, and only for the VFS.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agovfs: Remove syscall access to the VFS
Barret Rhoden [Wed, 7 Mar 2018 20:48:16 +0000 (12:48 -0800)]
vfs: Remove syscall access to the VFS

At this point, everything should be going through 9ns.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months ago9ns: Add get_cwd()
Barret Rhoden [Wed, 7 Mar 2018 19:02:13 +0000 (11:02 -0800)]
9ns: Add get_cwd()

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months ago9ns: Remove #root
Barret Rhoden [Wed, 7 Mar 2018 01:10:25 +0000 (17:10 -0800)]
9ns: Remove #root

Everything it did is done better by #kfs.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months ago9ns: kfs: Add root entries
Barret Rhoden [Wed, 7 Mar 2018 01:08:44 +0000 (17:08 -0800)]
9ns: kfs: Add root entries

These are directories that our init scripts expect to exist.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months ago9ns: Add #kfs
Barret Rhoden [Wed, 7 Mar 2018 00:47:23 +0000 (16:47 -0800)]
9ns: Add #kfs

It's a tree_filesystem.  There is a single instance, and the contents
are populated from the CPIO, which is still used by the VFS's KFS.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agoExtract parse_cpio_entries() from KFS
Barret Rhoden [Tue, 6 Mar 2018 22:18:00 +0000 (14:18 -0800)]
Extract parse_cpio_entries() from KFS

Moves it from KFS to cpio.c, so we can use it in other places.  I
attempted to update it a bit, including size checks.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months ago9ns: allow 'current-less' operations in 9ns
Barret Rhoden [Wed, 7 Mar 2018 00:48:21 +0000 (16:48 -0800)]
9ns: allow 'current-less' operations in 9ns

This can pop up if you walk from a device init function or from any sort
of kernel function during boot, such as mon_bin_run().

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months ago9ns: Implement chdir/fchdir
Barret Rhoden [Tue, 6 Mar 2018 19:20:55 +0000 (11:20 -0800)]
9ns: Implement chdir/fchdir

You won't be able to use it easily, since the VFS will still get first
dibs on lookups.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agoAdd atomic_swap_ptr()
Barret Rhoden [Tue, 6 Mar 2018 19:12:13 +0000 (11:12 -0800)]
Add atomic_swap_ptr()

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months ago9ns: Remove support for SYS_rename
Barret Rhoden [Thu, 1 Mar 2018 20:47:16 +0000 (15:47 -0500)]
9ns: Remove support for SYS_rename

The current approach won't work.  I think we'll need namec support for
rename.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months ago9ns: Support SYS_rmdir
Barret Rhoden [Thu, 1 Mar 2018 20:46:35 +0000 (15:46 -0500)]
9ns: Support SYS_rmdir

Just another remove.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months ago9ns: Support SYS_access (XCC)
Barret Rhoden [Thu, 1 Mar 2018 20:37:48 +0000 (15:37 -0500)]
9ns: Support SYS_access (XCC)

Reinstall your kernel headers.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agomm: 9ns: Add support for mmap
Barret Rhoden [Thu, 1 Mar 2018 19:29:32 +0000 (14:29 -0500)]
mm: 9ns: Add support for mmap

I'm not 100% on it, but I think the device mmap op will return an fs_file,
and once the VFS is out, we can integrate that more tightly with the mmap
code.

For instance, the assumption of the existence of the page cache can get
pushed into the fs_file and hidden behind ops, so that we can mmap
arbitrary objects.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agoSet O_EXEC when the kernel opens a file for exec
Barret Rhoden [Thu, 1 Mar 2018 18:58:43 +0000 (13:58 -0500)]
Set O_EXEC when the kernel opens a file for exec

Not a huge deal, but if we're going to have the flags, then we should use
them.  This popped up when doing permission checks on mmap on chans.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months ago9ns: Add error_jmp(): jump with an existing error
Barret Rhoden [Thu, 1 Mar 2018 16:43:04 +0000 (11:43 -0500)]
9ns: Add error_jmp(): jump with an existing error

Some parts of the code set errno and errstr, but defer the jumping.

This is what that old dev.c code wanted to do: set the error, but not
actualy jump.  That is a common pattern in walk code: it's only an error()
for the first name in a walk.  There can be errors on later names that
don't result in a long jump, but we do want to record the errno/errstr.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months ago9ns: Add fs_files and tree_files
Barret Rhoden [Thu, 1 Mar 2018 02:23:40 +0000 (21:23 -0500)]
9ns: Add fs_files and tree_files

fs_files are a basic structure that any 9ns device can use for a file
that contains data.  It's mostly a struct dir and a pagemap, though
future versions might not have a page mapping.  fs_files also come with
a set of operations, which will grow over time.

tree_files are fs_files that are arranged in a hierarchy consisting of
parents and children.  There are no hardlinks, but there are symlinks.
tree_files also come with a set of operations, which a device can use to
perform its role in operations such as lookups and creation.

Both fs_files and tree_files come with a collection of helper utilities,
such as fs_file_stat(), which a device can call.  The helpers handle the
various races and whatnot.

Devices do not need to use these at all, though my long term plan is to
replace all of the struct dirtabs with fs_files.  The dirtab is
basically a dir, but with the storage for the name built-in.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agopm: Add a stub for pm_destroy()
Barret Rhoden [Thu, 1 Mar 2018 19:31:38 +0000 (14:31 -0500)]
pm: Add a stub for pm_destroy()

The lack of a pm_destroy() was a little disturbing.  The PM code needs an
overhaul, which I'll get to later.  This stub is needed for the fs_file
work.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months agoAdd a garbage RCU implementation
Barret Rhoden [Thu, 1 Mar 2018 02:10:35 +0000 (21:10 -0500)]
Add a garbage RCU implementation

It's a placeholder for now while I build the tree_file code.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
15 months ago9ns: Fix devtab function pointer signatures
Barret Rhoden [Thu, 1 Mar 2018 04:07:39 +0000 (23:07 -0500)]
9ns: Fix devtab function pointer signatures

The signatures had the wrong signedness for some of the types.  It had
been an ongoing annoyance for every new device we create.  I pulled off
the bandaid.

Returning negative values for e.g. dev.read() will decrement the chan's
offset!  See rread() for details.  It's unlikely, but we shouldn't be
propagating errors like that, and the type ought to tell us what the
function should do.

Note that SYS_read returns an ssize_t.  dev.read() does not.  It should
throw for errors.

When I noticed device-internal functions with similar problems, for
instance helper functions like mntrdwr() or some of the functions in
sd.c, I fixed those too.  But this was far from exhaustive.

I did notice that pipebwrite() returns the retval from qio functions, but
ipbwrite() just returns n.  Those qio functions could return -1, maybe,
since they are ssize_t.  That needs some work still.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months agomm: Allow dev.mmap() to block
Barret Rhoden [Thu, 22 Mar 2018 18:39:33 +0000 (14:39 -0400)]
mm: Allow dev.mmap() to block

This is a bit hokey.  I'd like the dev.mmap function to be able to block.
Previously, that was called while holding the vmr spinlock.  This shrinks
the time that the spinlock is held by setting up a lot of the VMR in
advance of inserting it in the list.  Thus I split the allocation from
insertion and attached the file first.

The one complication is that the PM pruner code might look at the VMR while
vm_base and vm_end are being set.  To avoid issues, I added the racy ready
bool.

All of this is screaming for a rewrite.  At the very least, we could
separate out the address allocation to be an arena.  Though any major
changes should involve reading Austin's RadixVM paper.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months agomm: Clean up the functional interface
Barret Rhoden [Thu, 22 Mar 2018 16:26:20 +0000 (12:26 -0400)]
mm: Clean up the functional interface

I have a few changes to make, and there's no need for the rest of the
kernel to know about it.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months agomm: Call dev.mmap before checking the file
Barret Rhoden [Wed, 28 Feb 2018 22:19:37 +0000 (17:19 -0500)]
mm: Call dev.mmap before checking the file

Not all files in 9ns will be mmappable.  Check with the device first, which
will determine if you can mmap it or not and also make available the
various structures (e.g. fs_file) for the foc ops.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months agomm: Use struct file_or_chan for VMR files
Barret Rhoden [Wed, 28 Feb 2018 21:52:00 +0000 (16:52 -0500)]
mm: Use struct file_or_chan for VMR files

As they say, all problems in CS can be solved with a layer of indirection.
The file_or_chan struct hides the details of whether or not we're talking
to a file or a chan.  This will ease the transition from the VFS to 9ns.

The chan stuff isn't implemented yet - that'll require a few more changes.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months agomm: Ignore the FD on MAP_ANON mmaps
Barret Rhoden [Wed, 28 Feb 2018 16:46:51 +0000 (11:46 -0500)]
mm: Ignore the FD on MAP_ANON mmaps

Linux lets you do this.  Portable apps should set FD to -1 when they don't
have a file, i.e. anonymous maps, but we can be liberal in what we receive.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months agomm: Fix permission checks
Barret Rhoden [Wed, 28 Feb 2018 16:43:28 +0000 (11:43 -0500)]
mm: Fix permission checks

Our checks are based on the file's open mode, not on the underlying inode
permissions.  Note that the VFS currently stores its open mode (e.g.
O_READ) as an rwx.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months agomm: Stop leaking refs on mmap() errors
Barret Rhoden [Wed, 28 Feb 2018 16:42:29 +0000 (11:42 -0500)]
mm: Stop leaking refs on mmap() errors

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months agomm: Fix type bug
Barret Rhoden [Wed, 7 Mar 2018 23:21:53 +0000 (15:21 -0800)]
mm: Fix type bug

That looks like it was a copy-paste bug from a long time ago.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months ago9ns: Allow binds on symlinks
Barret Rhoden [Tue, 27 Feb 2018 23:04:00 +0000 (18:04 -0500)]
9ns: Allow binds on symlinks

We'll see if this is a good idea or not.  It does increase the cost of
following symlinks a little, though we already do a lot of findmounts for
every point.  That whole mess could get sped up with RCU.

Note: the "ntry - 1" on a WQ result doesn't check the last qid returned
from dev.walk.  The last one gets checked during domount(), which is
selectively done.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months ago9ns: Sort out when to not follow symlinks
Barret Rhoden [Tue, 27 Feb 2018 19:13:28 +0000 (14:13 -0500)]
9ns: Sort out when to not follow symlinks

The classic example is unlink/remove: the operation targets the symlink
itself, not its target.

I figure any of the bind/mount family of calls also want to target the
symlink.  They are changing the namespace, and operate on names, regardless
of directories/files/whatever.

Note that if you try to remove a symlink with a trailing slash with our
busybox, it *won't* fail.  e.g.

$ rm some_link_to_dir/

That should fail, but busybox won't send the trailing slash.  If you
manually call unlink/remove, we'll catch it and you'll get an error.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months ago9ns: Fix a couple namec() error cases
Barret Rhoden [Tue, 27 Feb 2018 17:35:46 +0000 (12:35 -0500)]
9ns: Fix a couple namec() error cases

Those errors were being written to the tmperrorbuf, but that wasn't being
used for anything.  Instead, you'd often get whatever other errstr was
previously set.  I'd often get ones from devdir "tell brho you saw this."
The namec error handling has always been a bit crazy, but at least now it's
a little better.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months ago9ns: Make walk() follow symlinks
Barret Rhoden [Mon, 26 Feb 2018 21:55:29 +0000 (16:55 -0500)]
9ns: Make walk() follow symlinks

When we hit a chan that is a symlink, walk() will check it for mount
points, just like any other file.  Otherwise, we'll attempt to walk it.

Note that O_NOFOLLOW doesn't throw an error; it just means to not follow
the last step.  open() can throw an error if it wants.

Relative lookups are a little nasty.  We need the parent of the symlink,
but only the device knows the parent.  We can use walk() and dotdot to get
the parent.  The special casing can be a tricky.  When the tree_file code
is merged, you can see what tree_file_walk does.  It's basically the same
as the check that walk() makes: we can walk from a symlink, but only to
dotdot.  We should only be doing that when handling a relative walk, though
there might be a case where we can sneak by - hence the asserts.

We allow eight nested symlinks, and otherwise you can have as many symlinks
in your path as you'd like.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
16 months ago9ns: Use a helper struct for walk/namec options
Barret Rhoden [Mon, 26 Feb 2018 16:51:12 +0000 (11:51 -0500)]
9ns: Use a helper struct  for walk/namec options

'can_mount' is just one option from namec down through all walks.  Symlinks
will us more options and helper functions, and we'll also need a loop
counter.

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