8 years agoVcore states for preemption recovery (XCC)
Barret Rhoden [Wed, 9 Nov 2011 23:12:01 +0000 (15:12 -0800)]
Vcore states for preemption recovery (XCC)

The kernel writes the states, and userspace will CAS with the kernel
whenever it needs to make decisions / sync on the flags.  I'll use this
more in the future.

Side note: having the kernel set the K_LOCK prevents userspace from
thinking a vcore wasn't preempted.  Ex: it receives a message, but
__preempt hasn't happened yet.  The preempt recovery handler will
(eventually) check/spin on the K_LOCK, which gets cleared once the vcore
is fully preempted.

Reinstall your kernel header(s).

8 years agoVcores always start in vcore context
Barret Rhoden [Wed, 9 Nov 2011 01:37:41 +0000 (17:37 -0800)]
Vcores always start in vcore context

Previously, after a preemption, the vcore would start whatever was
running when it was preempted: specifically, it could start a uthread.
Now, it'll always start in vcore context.  The 2LS will likely restart
the uthread right away.

We'll need this change to be able to steal uthreads from preempted
vcores (in future patches).  While the older style seemed reasonable for
programs written directly on the kernel, the 2LS now handles everything.

8 years agonotif_enabled -> notif_disabled (XCC)
Barret Rhoden [Wed, 9 Nov 2011 00:55:06 +0000 (16:55 -0800)]
notif_enabled -> notif_disabled (XCC)

The default state is now notifs enabled.  Vcores will still come up with
notifs disabled: the kernel will sort that out.  Its just that fresh
vcore preempt data won't need to have notifs manually enabled or
anything for the _S -> _M transition.

Reinstall your kernel header(s).

8 years agoClarifies/fixes some issues with __preempt and MCS
Barret Rhoden [Mon, 24 Oct 2011 18:00:08 +0000 (11:00 -0700)]
Clarifies/fixes some issues with __preempt and MCS

We need the wmb() in __preempt, which is racing with __map_vcore()
(among other things).  Basically, we need to make sure we don't give out
the vcore while cleaning up the vcore.  Once we __unmap_vcore(), we need
to never touch it again til it is mapped.

Likewise, the MCS-PDR code can quite easily see a situation where a core
is preempted but is still mapped.  The old assertion was mostly to catch
bugs, but that wasn't a "safe" check, since the preempting and unmapping
isn't atomic from the perspective of other cores.

8 years agoNo longer uses num_vcores() to determine _M (XCC)
Barret Rhoden [Tue, 18 Oct 2011 00:43:45 +0000 (17:43 -0700)]
No longer uses num_vcores() to determine _M (XCC)

We were using num_vcores() == 0 to determine if we're in _M mode or not.
This won't be true when we start sending bulk preempt messages, since
num_vcores() is 0 for an instant, which could trick some code to think
it is in _S mode and bypass some critical stuff.

Reinstall your kernel headers (procinfo.h).

8 years agovcore_request() no longer uses MCS locks
Barret Rhoden [Tue, 18 Oct 2011 00:21:19 +0000 (17:21 -0700)]
vcore_request() no longer uses MCS locks

All cores update a shared atomic, saying they want that many vcores.
One core will actually handle the process of prepping the vcores and
asking the kernel for them.

Note that the whole request/yield process and its effects on amt_wanted
and whatnot is rather jacked up.  Vcore code needs to be smarter about
how it interacts with amt_wanted, which will require some help from the
kernel, which I'll do in future patches.

8 years agoUthread blockon handles notif_disabled uthreads
Barret Rhoden [Thu, 13 Oct 2011 01:06:56 +0000 (18:06 -0700)]
Uthread blockon handles notif_disabled uthreads

The in_vcore_context() check tests TLS, not whether or not notifs are
disabled.  It is the latter we care about more.  We need to check
DONT_MIGRATE before checking if notifs are disabled (vcoreid), and any
code that does have DONT_MIGRATE set *when making a syscall* needs to
have notifs disabled.  I don't explicitly check for this, since you have
to set DONT_MIGRATE to be sure about your vcoreid.

8 years agoMore thoroughly detect preemptions
Barret Rhoden [Thu, 13 Oct 2011 00:50:23 +0000 (17:50 -0700)]
More thoroughly detect preemptions

MCS-PDR code checks for preemptions via preempt_tf_valid.  If you don't
you can accidentally think a yielded vcore is preempted.  Either way, it
is unmapped.  In the future, it'll be safe to restart them, but right
now we don't handle preemption messages, so processes can run into
issues.  Also, you don't really want to restart a yielded vcore.  Next
time you spin in the MCS code, you will (hopefully!) get a different
vcore (reread lockholder, etc).

Also, we were a bit sloppy about the use of preempt_tf_valid.  It's
actually an ancient seq_ctr instead of a bool.  The 2 year old reason
for that was to help us detect changes to the preempt tf for remote
recovery, but I have a feeling it might not be strong enough.

8 years agoPthreads now uses mcs_pdr locks
Barret Rhoden [Wed, 12 Oct 2011 23:24:20 +0000 (16:24 -0700)]
Pthreads now uses mcs_pdr locks

Instead of the old notif_safe MCS ones.  Note that the MCS-PDR locks are
notif_safe, and can be called from uthread context.

For those curious, pthread code has functions that lock that are called
from uthread context and from vcore context.  Specifically,
uthread_runnable/pth_thread_runnable can come from
uthread_init/pthread_create, which is uthread context, and
restart_thread, which is vcore context.  Plus, the pth_sched_entry
hammers the same runqueue lock in vcore context.

8 years agoproc_change_to_vcore() races fixed
Barret Rhoden [Wed, 12 Oct 2011 23:21:32 +0000 (16:21 -0700)]
proc_change_to_vcore() races fixed

This function had the same sorts of races as proc_yield(), namely that
your calling vcore could have been __preempted, have a preempt_served,
be DYING, etc.

Also saves the FP state and a couple other minor things.

8 years agoFixes race and rewrites proc_yield()
Barret Rhoden [Wed, 12 Oct 2011 21:30:10 +0000 (14:30 -0700)]
Fixes race and rewrites proc_yield()

The race was with concurrent __preempts.  preempt_served would get
turned off and we'd be unmapped.  We needed to check for being unmapped
with irqs disabled.

preempt_served serves as a "preemption is on the way, but hasn't hit
yet".  In this case, we've been removed from the online list and just
need to return and take the preemption.  A process might see this as
yield failing, either immediately or when the vcore gets restarted.

A few notes on proc_yield, and the unfortunate fact that we lock in it
(making it a pain for scalability):

1) Yield needs to leave the core, just like __death.  unmap, abandon,

2) It is safe to do one unmap without the lock, but only if you were
told to by the lockholder (which is what __preempt and __death do).
Granting new ones requires the lock.  Other than in __preempt and
__death, you can't trust reading the vcoremap to get your vcoreid
without the lock, since you could see the result of a take_core then a
give_core to different a vcore.  This is probably true.

3) Adding the pcore to the idlecoremap involves locking too (though not
the proc_lock);

4) Yield needs to not conflict with KMSGs.

5) Yield needs to not miss a notif_pending (playing shmem games with the
lists and __alert_vcore()

6) Lacking any remote __preempt/__death/__myield, yield needs to remove
its vcore from the online_list, which requires locking.

8 years agoUCQs now use mcs_pdr_locks (XCC)
Barret Rhoden [Wed, 12 Oct 2011 01:12:22 +0000 (18:12 -0700)]
UCQs now use mcs_pdr_locks (XCC)

I'm using the memory safe locks for now.  You can get away with unsafe
versions if the storage for them never gets freed (and we'd need some
sanity checks in __ensure_qnode_runs()), though I'm not 100% on whether
or not uthread code will ever call ucq code, and as of right now,
uthread stacks get freed (2LS decision).

The downside to this is that our MCS-PDR locks use more memory, and that
memory was not as likely to be in the cache as the stack.

Reinstall your kernel headers (ucq.h).

8 years agoFixes ext2 RAM block device linking
Barret Rhoden [Thu, 15 Dec 2011 22:32:26 +0000 (14:32 -0800)]
Fixes ext2 RAM block device linking

Same deal as with 5aac42b0631a8, we need to convert it to a .o to link
it in.  It's a bit crappy, since we have to process another large file,
but it works for now.

8 years agoFixes excessive make realcleans
Barret Rhoden [Thu, 15 Dec 2011 21:38:22 +0000 (13:38 -0800)]
Fixes excessive make realcleans

Since b8738ad0, every time you make, you'd do a make realclean (at least
on x86), since the $@ wasn't changed when the target had "real-" added
to it.

8 years agoFixes gcc 4.6.1 incompatibility with old x86 asm
Barret Rhoden [Thu, 15 Dec 2011 21:05:36 +0000 (13:05 -0800)]
Fixes gcc 4.6.1 incompatibility with old x86 asm

4.6.1 didn't like the old version (couldn't handle the possibility of
"m", perhaps rightfully so).

Did anyone actually build the kernel on x86 with the new compiler, or
was it just my system that couldn't handle it?

8 years agoFixes binutils patch: Hammertime!
Barret Rhoden [Thu, 15 Dec 2011 19:11:52 +0000 (11:11 -0800)]
Fixes binutils patch: Hammertime!

Lots of systems have problems building some versions of binutils due to
the weirdness around RPATH_ENVVAR.  No idea why binutils does that crap.
We've adopted the same patch that Gentoo uses for the version of
binutils they distribute.


8 years agoFix xcc's "make patches"
Andrew Waterman [Thu, 15 Dec 2011 02:49:25 +0000 (18:49 -0800)]
Fix xcc's "make patches"

9 years agoadd getrlimit64 stub
Your Name [Sat, 12 Nov 2011 08:05:21 +0000 (00:05 -0800)]
add getrlimit64 stub

Necessary to link busybox on RISC-V.  The problem is
actually that the generic version doesn't libc_hidden_def
itself, so the exported symbol name was mangled.

9 years agoFixed bug in RISC-V env_user_mem_free
Your Name [Sat, 12 Nov 2011 08:04:39 +0000 (00:04 -0800)]
Fixed bug in RISC-V env_user_mem_free

It was rounding up to the largest page size, causing
procinfo/procdata to be freed on sys_exec.

9 years agoRISC-V compiler port configure script changes
Andrew Waterman [Fri, 11 Nov 2011 14:09:26 +0000 (06:09 -0800)]
RISC-V compiler port configure script changes

I had to change the RISC-V compiler port a bit to
maintain backwards compatibility with our generic
Newlib/ELF target.  This actually simplified the
configure script changes for RISC-V on ROS.

The commit is large because I've now put the RISC-V
cross-compiler in its own git repo, and I'm using
git diff to generate the patch files, and the slight
formatting change makes for a large apparent change.

9 years agoFixed RISC-V page fault handling
Andrew Waterman [Fri, 11 Nov 2011 09:14:40 +0000 (01:14 -0800)]
Fixed RISC-V page fault handling

The current tf wasn't being set.

9 years agoChanges to RISC-V supervisor mode
Andrew Waterman [Fri, 11 Nov 2011 08:32:22 +0000 (00:32 -0800)]
Changes to RISC-V supervisor mode

See commit comments in ISA simulator for details

9 years agoMiscellaneous RISC-V compiler updates
Andrew Waterman [Fri, 11 Nov 2011 08:31:50 +0000 (00:31 -0800)]
Miscellaneous RISC-V compiler updates

9 years agoDynamic linking now works on RISC-V
Andrew Waterman [Tue, 8 Nov 2011 09:39:13 +0000 (01:39 -0800)]
Dynamic linking now works on RISC-V

The spurious invalid dynamic relocations within ld.so
were caused by our errno.c using TLS for errno within
the RTLD.  Instead, we should use a global errno then.

9 years agoRISC-V architecture bugfix potpourri
Andrew Waterman [Tue, 8 Nov 2011 09:38:28 +0000 (01:38 -0800)]
RISC-V architecture bugfix potpourri

9 years agoImproved ELF loader
Andrew Waterman [Tue, 8 Nov 2011 09:36:36 +0000 (01:36 -0800)]
Improved ELF loader

- support program headers spanning more than a page
  (this does occur with 64-bit ELFs)

- load program headers without MAP_FIXED, so that they
  don't collide with the dynamic linker.  we now load
  the linker starting at page 1.

- fixed kernel page fault when zeroing a partial BSS
  section with demand paging.  we need to bring the
  fringe page in with MAP_POPULATE before zeroing it.

9 years agoMakefile changes to support RISC-V
Andrew Waterman [Mon, 7 Nov 2011 23:03:36 +0000 (15:03 -0800)]
Makefile changes to support RISC-V

Added riscv target to build for RISC-V
and rvfs target to run the simulator

9 years agoDon't populate core 0's stack, except for SPARC
Andrew Waterman [Mon, 7 Nov 2011 22:58:45 +0000 (14:58 -0800)]
Don't populate core 0's stack, except for SPARC

SPARC needs stacks to be mapped in so that
register window spills always succeed.  Other
ISAs can safely fault on stack accesses.

9 years agoRename c3po ucontext to avoid namespace collision
Andrew Waterman [Sat, 5 Nov 2011 02:06:59 +0000 (19:06 -0700)]
Rename c3po ucontext to avoid namespace collision

... with sys/ucontext.h's struct ucontext.

9 years agoFixed dynamic linking on x86
Andrew Waterman [Sat, 5 Nov 2011 02:05:10 +0000 (19:05 -0700)]
Fixed dynamic linking on x86

Some changes in binutils made ld.so reject
our libraries as having an invalid ABI.
Also, we have to avoid using recursive
spinlocks (which use __thread) while inside
ld.so before __thread is valid.

9 years agoProgress towards dynamic linking on RISC-V
Andrew Waterman [Fri, 4 Nov 2011 21:38:41 +0000 (14:38 -0700)]
Progress towards dynamic linking on RISC-V

This patch changes how command-line args are passed to
the dynamic linker.  Before, it was being done in a way
that required a function call at a time when function
calls are not legal.

9 years agoAdd some more ignores to the gitignore
Kevin Klues [Thu, 3 Nov 2011 04:23:16 +0000 (21:23 -0700)]
Add some more ignores to the gitignore

9 years agoRISC-V and updated cross compiler (XCC)
Kevin Klues [Thu, 3 Nov 2011 01:30:15 +0000 (18:30 -0700)]
RISC-V and updated cross compiler (XCC)

At this point, we now use gcc 4.6.1 and glibc 2.14.1.  If you recently pulled
this commit on an older repo, you'll need to do a few things.

If you don't care about your local changes, just copy out your two Makelocals
(the kernel one and the XCC one), blow away the repo, and reclone.

If you have changes, checkout an older version of the repo and make clean for
both the kernel and the xcc.  Otherwise, you could manually get rid of some old
gcc/glibc/binutils/etc tarballs and directories.

Finally, you'll want to rebase your working branches onto the new master's
HEAD, or somewhere in the past downstream if you want to keep it where it was
in the original master branch.  Most people should just rebase now to the new

Ex: git rebase --onto master UPSTREAM YOUR-OLD-BRANCH , where UPSTREAM is the
commit where you diverged from the upstream/master branch.

9 years agoUpdated .gitignore to reflect new xcc version
Andrew Waterman [Wed, 2 Nov 2011 23:05:48 +0000 (16:05 -0700)]
Updated .gitignore to reflect new xcc version

9 years agoRISC-V userland now works-ish
Andrew Waterman [Wed, 2 Nov 2011 09:34:22 +0000 (02:34 -0700)]
RISC-V userland now works-ish

9 years ago64-bit compatibility fixes in userland/tests
Andrew Waterman [Wed, 2 Nov 2011 09:32:32 +0000 (02:32 -0700)]
64-bit compatibility fixes in userland/tests

9 years agoRISC-V compiler now builds working executables
Andrew Waterman [Wed, 2 Nov 2011 09:29:53 +0000 (02:29 -0700)]
RISC-V compiler now builds working executables

9 years agoSimplified binutils build process
Andrew Waterman [Wed, 2 Nov 2011 09:28:36 +0000 (02:28 -0700)]
Simplified binutils build process

There's no need to make a copy of the source directory then build out of it.
Just build out of an empty directory.

9 years agoRISC-V cross compiler now builds (XCC)
Andrew Waterman [Thu, 3 Nov 2011 01:29:43 +0000 (18:29 -0700)]
RISC-V cross compiler now builds (XCC)

9 years agofixes to RISC-V trap handling
Andrew Waterman [Fri, 28 Oct 2011 12:21:29 +0000 (05:21 -0700)]
fixes to RISC-V trap handling

9 years agohandle sizeof(pid_t) != sizeof(void*) gracefully
Andrew Waterman [Fri, 28 Oct 2011 12:20:27 +0000 (05:20 -0700)]
handle sizeof(pid_t) != sizeof(void*) gracefully

9 years agoupgraded to gcc 4.6.1 and glibc 2.14.1 (XCC)
Andrew Waterman [Thu, 3 Nov 2011 01:20:00 +0000 (18:20 -0700)]
upgraded to gcc 4.6.1 and glibc 2.14.1 (XCC)

This commit includes not only brigning in the new gcc and glibc, but also the
changes to the glibc-*-ros files as well.  We did this so that this commit
will compile and build properly.  To see the diff of the glibc-*-ros files
with the old version, run the following command relative to checking out THIS

git diff HEAD^:tools/compilers/gcc-glibc/glibc-2.11.1-ros \

9 years agoFixed RISC-V trap entry
Andrew Waterman [Thu, 27 Oct 2011 11:04:40 +0000 (04:04 -0700)]
Fixed RISC-V trap entry

IRQs were being enabled in the wrong place, etc.

9 years agoUpdated RISC-V boot sequence; use 8KB pages
Andrew Waterman [Thu, 27 Oct 2011 10:07:43 +0000 (03:07 -0700)]
Updated RISC-V boot sequence; use 8KB pages

9 years agoMMAP_LOWEST_VA must be page-aligned
Andrew Waterman [Thu, 27 Oct 2011 10:04:39 +0000 (03:04 -0700)]
MMAP_LOWEST_VA must be page-aligned

... so I just set equal to PGSIZE, which doesn't change its value on x86.

9 years agoGMP, MPFR, and MPC are external dependences (XCC)
Andrew Waterman [Thu, 27 Oct 2011 07:31:26 +0000 (00:31 -0700)]
GMP, MPFR, and MPC are external dependences (XCC)

The cross-compiler now depends on the GMP, MPFR, and MPC libraries; they
will no longer be built along with the compiler.  These libraries are never
modified, and they complicate and slow the build process.

On Debian systems, this suffices: apt-get libgmp-dev libmpfr-dev libmpc-dev

9 years agoupgraded to binutils 2.21.1
Andrew Waterman [Thu, 3 Nov 2011 01:06:14 +0000 (18:06 -0700)]
upgraded to binutils 2.21.1

9 years agocode changes for new RISC-V GCC toolchain
Andrew Waterman [Sun, 23 Oct 2011 06:42:18 +0000 (23:42 -0700)]
code changes for new RISC-V GCC toolchain

9 years agoSort of hacky way of adding our binary blob for kfs to the kernel image
Andrew Waterman [Wed, 2 Nov 2011 22:44:56 +0000 (15:44 -0700)]
Sort of hacky way of adding our binary blob for kfs to the kernel image

Will become necessary after we add in compiler support for riscv.  Since the
way in which we even interact with KFS is probably temporary, this hack is
probably justified...

9 years agoForce kernel to be built with the static flag
Andrew Waterman [Wed, 2 Nov 2011 22:08:23 +0000 (15:08 -0700)]
Force kernel to be built with the static flag

Default in older gccs, but as we move to a new
one it might not be.  We just want to be prepared.....

9 years agoMCS Preemption-Detection and Recovery locks
Barret Rhoden [Wed, 12 Oct 2011 01:06:54 +0000 (18:06 -0700)]
MCS Preemption-Detection and Recovery locks

The basic idea is that if you are spinning, make sure someone else is
online/running that is on the way to making progress/unblocking you.
Normally, this is the lockholder, but it could also be someone else on a
chain of qnodes.  You make sure they are running, they make sure the
next one up is running, etc.  Even if we have only one pcore, this
should still unjam some preempted vcores involved in MCS locking.

Any MCS lock that is grabbed in vcore context will need to use these.
This includes all cases of notif_safe that needed to be called from
uthread context (though that needs a review, in case we still need

Regardless the mcs_pdr locks can handle being called from uthread
context, and odds are that anyone desiring to use an MCS lock will need
to use these (even regular old uthread code).

9 years agosys_change_vcore() (XCC)
Barret Rhoden [Wed, 12 Oct 2011 00:06:56 +0000 (17:06 -0700)]
sys_change_vcore() (XCC)

Syscall, allowing a process's vcore to change into another unmapped
vcore.  Be sure to only call this on vcores that have a stack set up for
them, and not some random vcore.

__startcore() and proc_change_to_vcore() both have some common
functionality.  __startcore() wasn't changed: its lower half just became
the helper.

Reinstall your kernel headers (bits/syscall.h).

9 years agoSend preemption messages (XCC)
Barret Rhoden [Wed, 12 Oct 2011 00:03:19 +0000 (17:03 -0700)]
Send preemption messages (XCC)

When a vcore is preempted, the kernel will send an event to the
appropriate ev_q.  For all uthread code, the handler and ev_q is set up
in uthread_lib_init().  Note that the handler does nothing yet but give
us some helpful information.

Reinstall your kernel headers (event.h).

9 years agoFixes minor bug
Barret Rhoden [Tue, 11 Oct 2011 23:46:18 +0000 (16:46 -0700)]
Fixes minor bug

Had no effect on pthread code, caught it when I forgot to put in a
FALLBACK and wondered why I wasn't getting the warning.

9 years agoUthread helpers for disabling notifs
Barret Rhoden [Tue, 11 Oct 2011 00:40:36 +0000 (17:40 -0700)]
Uthread helpers for disabling notifs

The DONT_MIGRATE bit is tricky, and that code is about to get repeated a
lot, so it makes sense to have a helper.  Other code might be able to
use this, though I left them as is.  uthread_init() seems clear as is,
and might be getting mucked with in a concurrent patch set.

9 years agoAdds MCS unlock code that uses CAS.
Barret Rhoden [Mon, 10 Oct 2011 23:24:12 +0000 (16:24 -0700)]
Adds MCS unlock code that uses CAS.

We don't use this since SPARC and RISCV don't have a native CAS yet, but
I want the code in place for a couple upcoming commits.

This patch also comments on how the MCS locks work, which helps a bit.

9 years agoQuickly return/pop DONT_MIGRATE uthreads
Barret Rhoden [Thu, 6 Oct 2011 00:20:32 +0000 (17:20 -0700)]
Quickly return/pop DONT_MIGRATE uthreads

Two rules:

1) Don't check messages/handle events when you have a DONT_MIGRATE
uthread.  This will become important in the future.

2) All uses of DONT_MIGRATE must reenable notifs (and check messages) at
some point.  One such case is uthread_yield().  Another is

This patch handles the case where a uthread turns on DONT_MIGRATE and
gets IPI'd before it can disable_notif.  We simply return to it, leaving
notif_pending turned on so that we make sure we will go back into vcore
context and check messages at the next safe opportunity.  That makes
this the one time we can leave vcore context with notif_pending: since
we know we'll get back to it right away.

Another way to look at it is that we lost the race, and got the IPI
before disabling.  This allows us to pretend like we won the race
(barring any bugs...).

9 years agoproc_notify() no longer checks notif_pending
Barret Rhoden [Thu, 6 Oct 2011 00:15:17 +0000 (17:15 -0700)]
proc_notify() no longer checks notif_pending

We were accidentally masking our IPIs when notif_pending was set.  This
was due to a change over time of what notif_pending means.  It used to
only mean "an IPI is on its way", but now it means "there is a reason to
reenter vcore context and/or check messages/events".

9 years agoDONT_MIGRATE set more carefully
Barret Rhoden [Wed, 5 Oct 2011 22:28:00 +0000 (15:28 -0700)]
DONT_MIGRATE set more carefully

It's held the entire time throughout an mcs_notif_safe lock, since it
doesn't make sense to migrate or otherwise try to restart/run that
thread (could be holding the lock, etc).

Also, after turning off DONT_MIGRATE, you need to check messages (which
enable_notifs() does).  This isn't critical right now, but future
patches will require it.  It's harmless to turn them on before
enable_notif(), since the protection it provides is in the process of
disabling notifs.  Once that is done, you won't get migrated anyways.

Finally, this makes sure we only do the DONT_MIGRATE / notif_disabling
business if we're in _M mode.  This wasn't pairing properly, and we were
getting our thread0 set with DONT_MIGRATE the first time it ran.

9 years agoAdds /dev/null
Barret Rhoden [Tue, 4 Oct 2011 23:30:21 +0000 (16:30 -0700)]
Adds /dev/null

To the ghetto devfs.  Needed by BB for some job management for some

9 years agoKthreads from a different process can restart
Barret Rhoden [Tue, 4 Oct 2011 23:28:21 +0000 (16:28 -0700)]
Kthreads from a different process can restart

Whether or not you want to run kthread bottom halves on a core that is
owned by another process is a matter of policy.  The code can handle it
either way.  If you don't want to, then route your interrupts to LL
cores and put some thought into where you send the __launch_kthread

9 years agoProcess refcnt optimizations
Barret Rhoden [Tue, 4 Oct 2011 21:06:08 +0000 (14:06 -0700)]
Process refcnt optimizations

The __startcore optimization is similar to how it was before, but I
separated it from the owning_proc commit to show that it isn't necessary
and to make it more clear.

The kthread optimization is just a comment for now, since it's not clear
to me which way is best (if any).

9 years agoUpdated memory barrier stuff
Barret Rhoden [Mon, 3 Oct 2011 23:26:28 +0000 (16:26 -0700)]
Updated memory barrier stuff

Minor change to the MCS lock (which did not appear to be a problem in
the assembly) and some talk about the Alpha memory model.

Note that I caught a process deadlocked on an MCS lock in a VM (one
vcore, spinning on a locked lock, no preemptions etc outstanding), so
something out there is probably jacked up.

9 years agocur_proc broken up into owning_proc and cur_proc
Barret Rhoden [Mon, 3 Oct 2011 23:18:34 +0000 (16:18 -0700)]
cur_proc broken up into owning_proc and cur_proc

It's important that our interrup/kmsg handlers do not adjust current out
from under regular kthread code (or whatever was running there before).
This led to splitting up cur_proc.

pcpui->cur_proc (current) is now only what context is loaded, and not
what process owns the core (owning_proc).  This distinction wasn't clear
before.  owning_proc tells us which process to run, and cur_tf tells us
what trapframe to pop/run.

All proc mgmt kmsg handlers now work on owning_proc, instead of some
combination of cur_tf or cur_proc.  cur_tf has no meaning without an
owning proc.  Earlier, we used cur_tf as a signal to run things.  now we
use owning_proc.

Read the documentation for more details.

9 years agoswitch_to() and switch_back() disable interrupts
Barret Rhoden [Mon, 3 Oct 2011 23:15:37 +0000 (16:15 -0700)]
switch_to() and switch_back() disable interrupts

Prevents a potential race with an unlucky IPI that cares about cur_proc.

9 years agocore_request() uses current_tf to return
Barret Rhoden [Thu, 29 Sep 2011 22:02:11 +0000 (15:02 -0700)]
core_request() uses current_tf to return

Instead of manually calling smp_idle(), we just zero current_tf to
trigger abandoning the core.

9 years agoproc_destroy() no longer requires edible refs
Barret Rhoden [Thu, 29 Sep 2011 21:30:38 +0000 (14:30 -0700)]
proc_destroy() no longer requires edible refs

proc_destroy() will return, though it does require handling an IMMEDIATE
kmsg (which PRKM currently does, or you can enable interrupts at some
point) before the kernel returns to userspace (in the event of
proc_destroy() being called on the current_tf).

Note that all return paths need to check interrupts (and RKMs) at some

9 years agoRemoves __proc_kmsg_pending()
Barret Rhoden [Thu, 29 Sep 2011 20:12:01 +0000 (13:12 -0700)]
Removes __proc_kmsg_pending()

Since proc management kmsgs return and are IMMEDIATE, we no longer need
the painful logic of determining that the kernel needs to clean up in
anticipating of a 'stack killing' kmsg.

This means schedule() can run on a core, preempt the _M's vcore running
there, and give out both that vcore and the pcore without worrying about
its own code getting interrupted.

9 years agoProcess mgmt kmsgs are now IMMEDIATE
Barret Rhoden [Thu, 29 Sep 2011 01:37:27 +0000 (18:37 -0700)]
Process mgmt kmsgs are now IMMEDIATE

Instead of ROUTINE.  This means that __startcore, __notify, __preempt,
and __death now are received whenever interrupts are enabled, instead of
only when we PRKM.  This means we no longer need to go out of our way to
get these messages, which will allow me to clean up some proc mgmt code
in future commits.

Note that __launch_kthread() is still ROUTINE, since it does not return.

9 years agoProtects cur_tf by disabling interrupts
Barret Rhoden [Wed, 28 Sep 2011 20:58:06 +0000 (13:58 -0700)]
Protects cur_tf by disabling interrupts

Disable interrupts to keep cur_tf or its contents from changing out from
under you.  This doesn't happen yet, since all kmsgs that change cur_tf
are still routine.

proc_yield() needs to be careful due to concurrent notifications.
proc_yield() is a lot like the other blocks of code that adjust a
process's state on a core (__startcore, __preempt, etc): it should be
run with interrupts disabled to avoid any interleavings.

The changes to _S code (fork/exec) are there just in case we muck with
cur_tf in the future.

9 years agoProc kmsgs now make their changes to cur_tf
Barret Rhoden [Wed, 28 Sep 2011 00:57:47 +0000 (17:57 -0700)]
Proc kmsgs now make their changes to cur_tf

Previously, when a process management kernel message came in, it's
effects would be felt immediately.  A new TF would be popped, etc.  Now,
all of these messages work on the cur_tf, which is the context that will
run when the kernel is done and either idles or reaches a place it can
run a process (like a PRKM site) (which is where we call

Put another way, instead of actually running the context, we just set up
to run it later.  We can then handle other messages (like a __preempt),
which will just change the cur_tf to do what we want when we attempt to
run them (in that case, it will be to do nothing, since __preempt sets
cur_tf to 0).

Also, __startcore and __notify now return.  __launch_kthread still does

9 years agoset_current_tf() no longer sets the local *tf var
Barret Rhoden [Wed, 28 Sep 2011 00:44:24 +0000 (17:44 -0700)]
set_current_tf() no longer sets the local *tf var

Meaning that we only copy out the *tf and set cur_tf, but do not change
tf in the calling function.  The contents are the same, but if something
happens that changes cur_tf's contents, you're still using the same one
you came in on (this will matter for a future commit).

The old style had a bug too.  If a kthread migrated, when it returned up
its stack and it looked at *tf, it would point to the cur_tf of possibly
another core (which is not what we want).  We want to point to the
original TF we came in on, so we can decide if we should return to the
kernel or not (and if we do, we just pop that TF).

Sparc and RISCV probably need a little work.  I put warns in there to
catch IRQs being enabled.  set_current_tf() probably needs to be called
more often too (like when handling other traps).

9 years agox86 interrupts are disabled til cur_tf is set
Barret Rhoden [Tue, 27 Sep 2011 21:27:36 +0000 (14:27 -0700)]
x86 interrupts are disabled til cur_tf is set

Whenever we're in the kernel with interrupts enabled, if there is a
process that is running (or should be running) on the core, current and
cur_tf should both be set.  On the first time into the kernel (syscall,
trap, etc) from userspace, cur_tf needs to get set.

Also remember that a 0'd cur_tf means that we should no longer run a
context (which happens after a kthread returns from blocking if the
process is no longer present).  In those situations, it is still okay to
have current set.  That is just which process's context we have loaded.

9 years ago__preempt and __death now return
Barret Rhoden [Tue, 27 Sep 2011 00:05:48 +0000 (17:05 -0700)]
__preempt and __death now return

They had been 'stack-smashing' KMSGs, which forced them to be routine
and made it hard to receive them from certain fictional contexts (such
as schedule() trying to preempt the core it runs on from the process
running there.).

9 years agox86 kernel messages go through irq_handler()
Barret Rhoden [Mon, 26 Sep 2011 23:36:18 +0000 (16:36 -0700)]
x86 kernel messages go through irq_handler()

Previously, __kernel_message() was getting called directly from the
assembly routines.  Now, it goes through irq_handler() like all other
traps.  While it is slightly slower, it will go through the same path,
including proc_restartcore() on the way back out.

9 years agoResolves race with __unmap and __map_vcore()
Barret Rhoden [Mon, 26 Sep 2011 20:49:06 +0000 (13:49 -0700)]
Resolves race with __unmap and __map_vcore()

When you send a __preempt message (or __death), the unmapping happens on
the destination core.  If you were to try and give out the vcore
immediately, the old mapping would still be there.  This is a problem
that came about when we switch to using vcore lists.

Now we'll spin til the remote core unmaps.  This means that we can't
have scheduler code (or whatever) try to preempt its current pcore's
vcore and then try to give out that same vcore somewhere else without
take the stack-smashing __preempt message.  No one does this yet, since
our scheduler() only runs on LL cores.

9 years ago_S processes properly map/unmap vcore 0
Barret Rhoden [Mon, 26 Sep 2011 20:32:01 +0000 (13:32 -0700)]
_S processes properly map/unmap vcore 0

To make __death easier, vcore 0 is mapped to whatever pcore the process
is running on in _S.  We were a bit lazy about unmapping it.

9 years agoCleaned up memory barrier usage (XCC)
Barret Rhoden [Sun, 25 Sep 2011 23:16:34 +0000 (16:16 -0700)]
Cleaned up memory barrier usage (XCC)

Cleaned up the use of memory barriers in our shared memory
synchronization code (event stuff, locking stuff, etc).  Check out the
documentation if you plan to write any concurrent, shared memory code
that doesn't use locking.

9 years agoFixes disable_kevent()
Barret Rhoden [Tue, 20 Sep 2011 21:50:14 +0000 (14:50 -0700)]
Fixes disable_kevent()

Need to be more careful with deregistering for events (don't free the
ev_q if it is possible the kernel is still sending messages).

No one uses it yet (or ever), so it's not a big deal.

9 years agoProcesses can yield the entire process
Barret Rhoden [Sun, 18 Sep 2011 02:44:40 +0000 (19:44 -0700)]
Processes can yield the entire process

When yielding your last vcore, you'll now transition to WAITING, and be
woken up when an event comes in.  If you ever want to wake back up,
you'll need to have at least one ev_q marked FALLBACK/INDIR, and have
that ev_q trigger.

We don't support yielding just to be nice.  If you yield, you need an
event to wake you.  Otherwise, just do your work.

This also changes the ksched to be able to handle a RUNNABLE_M, albeit
not in a perfect manner.

9 years agoManager change: Hit Shift-G to get to the monitor
Barret Rhoden [Sun, 18 Sep 2011 02:36:35 +0000 (19:36 -0700)]
Manager change: Hit Shift-G to get to the monitor

For now, the manager will just spin looking for work.  Interrupt it with
a shift-g to get into the monitor.  Believe it or not, this is an
improvement over the old style, though it ideally wouldn't need to spin
looking for work either.

9 years agopthread_join() no longer spins
Barret Rhoden [Sun, 18 Sep 2011 01:29:35 +0000 (18:29 -0700)]
pthread_join() no longer spins

It'll now wait on the join_target, which will wake it up when it exits
(depending on how the atomic_swap race went).

9 years agoev_q option VCORE_MUST_RUN (XCC)
Barret Rhoden [Sat, 17 Sep 2011 00:59:44 +0000 (17:59 -0700)]
ev_q option VCORE_MUST_RUN (XCC)

Some event queues need to have their alerts sent to a vcore that will
definitely run (as of the time alert_vcore() was called), and not just a
can_rcv_msg.  The one (and probably only) example of this is the
preempt_msg ev_q.  Simply put, you can't send the preempt message about
a given vcore to that vcore, which could happen without this option.

Note that the vcore that receives this message can be yielding or
getting preempted or whatever - so long as it wasn't the vcore that
was preempted (and thus generated the preempt message) (unless it will
be forced to run in the ultimate_fallback area).

Even if you want to just poll your preeempt ev_q (and not want an
INDIR), you still need the MUST_RUN flag to make sure the IPI gets
there.  If you don't want an IPI either, you'll have issues with locking
in uthread context and with preemption response latency.

9 years agoAllow ev_qs to not have INDIR throttling (XCC)
Barret Rhoden [Fri, 16 Sep 2011 23:14:43 +0000 (16:14 -0700)]
Allow ev_qs to not have INDIR throttling (XCC)

As a reminder, ev_qs normally will only have one INDIR event sent at a
time (roughly), and future INDIRs/IPIs (alerts) won't be sent until the
main ev_q has been tended to.  This patch allows ev_qs to opt out.

The only use for this I forsee is the preemption ev_q, since the
original INDIR might be sent to a preempted vcore.

9 years agoBreaks up the proc_lock to use the mm_lock
Barret Rhoden [Fri, 16 Sep 2011 23:01:02 +0000 (16:01 -0700)]
Breaks up the proc_lock to use the mm_lock

While this has been needed for a long time, it now is critical due to
event code holding the proc_lock and then posting an INDIR (which may
mmap()).  It's a fairly rare condition (which I didn't get yet), but it
will deadlock.

As it is now, we're okay, so long as our mmap() call doesn't try a
tlbshootdown (which needs the proclock for now).

9 years agoFixes event FALLBACK code
Barret Rhoden [Fri, 16 Sep 2011 00:10:03 +0000 (17:10 -0700)]
Fixes event FALLBACK code

Previously, we had situations where the kernel couldn't find a core that
can_rcv_msg, and the code couldn't handle going into the PROC_WAITING
state.  It could handle going down to one core, but it couldn't handle
process state.

This new version of alert_core() can handle single cores yielding, the
entire process yielding, bulk preemption, single core preemption, and
anything else I can think of.  It does this without locking in the
common case, which would be a scalability problem.  Arguably, when we
need to FALLBACK, all events will pick the same online vcore (first on
the list), and hammer the same VCPD UCQ, but it won't be while holding a
massive lock.

Note that we could have moved __proc_wakeup() from alert_vcore() to
send_event().  It won't hurt to do that, other than to give you the fall
sense of security that a process will always be able to yield without
missing a wake up.  You need to want an INDIR/IPI and want FALLBACK
(which is rapidly becoming the default) to be guaranteed to wake up.

There are a couple other issues that need to be sorted before this can
be used for preemption messages.  Stay tuned!

9 years agoProc state work: WAITING helpers and is_mcp helper
Barret Rhoden [Fri, 16 Sep 2011 00:06:16 +0000 (17:06 -0700)]
Proc state work: WAITING helpers and is_mcp helper

The __proc_wakeup() function can be called whether the process is
WAITING or not - it doesn't particularly care.

Instead of having multiple WAITING states, I'm going with the is_mcp
bool.  This simplifies event code and other places that don't care about
the _M nature of the process.  We'll see if this is a good idea or not.
I might slim down the other states as well, though those seem to work
well with the switch statements.

9 years agoKmsg debug routine
Barret Rhoden [Thu, 15 Sep 2011 00:37:18 +0000 (17:37 -0700)]
Kmsg debug routine

I used this to help with a brutal bug a couple weeks ago (c281e8419974).
Call it with kfunc, or build it in to the monitor if you want, etc.

9 years agoproc_yield() will return if you have an event
Barret Rhoden [Wed, 14 Sep 2011 01:49:11 +0000 (18:49 -0700)]
proc_yield() will return if you have an event

INDIRs will now set notif_pending, whose meaning changes slightly to be
"check your shit".  It's actually always been that, but that was before
we split up INDIRs and IPIs.  Without this, we could miss INDIRs while
trying to leave vcore context.

The intuition here is that processes should not leave vcore context
while notif_pending is set.  There are two ways out, one of which has
been sorted for a while: pop_ros_tf() (note the other uses of
clear_notif_pending()).  The other way is via proc_yield(), and the
kernel will help if we lose those races (racing with send_event()).

When yielding, if we lost the race we bail out.  This is a little
different than the usages of clear_notif_pending() in u/p/uthread.c.  In
those cases, we'll go ahead and run the thread, and the events don't get
a chance to change the mind of the 2LS.  (We can change this in the
future).  When vcore_yield() fails, we go back into the main 2LS loop
(in pthread.c).

Note some of this stuff will be more useful in future patches.  The
details of FALLBACK will change shortly.

9 years agoCleans up __proc_give and _take code
Barret Rhoden [Wed, 14 Sep 2011 00:01:02 +0000 (17:01 -0700)]
Cleans up __proc_give and _take code

It's been ghetto for far too long now.  There's also a slight change in
behavior: on the grant side, num_cpus gets updated before handing out
the vcores.  I prefer it this way, and it doesn't really matter: the
kernel shouldn't expect things to line up while the lock is held, and
userspace shouldn't trust num_vcores/the vcoremap while the seq_ctr is

9 years agoVcore management uses the lists
Barret Rhoden [Tue, 13 Sep 2011 22:36:34 +0000 (15:36 -0700)]
Vcore management uses the lists

Vastly cleans up vcore allocation/discovery/management.  Doesn't use the
bulk_preempt list for the preempt_all yet.  Those will need a bit of
work anyways.

9 years agoVcore lists now track vcore statuses
Barret Rhoden [Tue, 13 Sep 2011 20:39:26 +0000 (13:39 -0700)]
Vcore lists now track vcore statuses

We don't use the lists yet, they just track the state of vcores as they
are granted and taken.

We don't use the bulk preempt list at all yet either.

9 years agoCleans up fork/exec's procinfo/data handling
Barret Rhoden [Tue, 13 Sep 2011 18:35:06 +0000 (11:35 -0700)]
Cleans up fork/exec's procinfo/data handling

This makes the process fork creates new/fresh by default, and things
needed from procinfo are copied over one at a time.  The old way was
that the procinfo/procdata were identical.

In general, I tend to really dislike fork/exec: lots of hacks and pains
in the ass.  At least it isn't as bad as it used to be (when the proc
creation paths were totally separate).

9 years agoVcore list initialization. (XCC)
Barret Rhoden [Mon, 12 Sep 2011 22:57:50 +0000 (15:57 -0700)]
Vcore list initialization. (XCC)

There are three lists: active, bulk_preempted, and inactive/yielded.  We
don't use them in this commit; we just get them in place.  They have a
few purposes.  In the long run, it'll help the kernel with bulk
preemption.  For now, it will help with quickly finding a new vcore (no
more scanning from vcore0).  In the middle run, event FALLBACK will be
able to find a destination quickly.

9 years agoMCS locks properly disable thread migration
Barret Rhoden [Mon, 12 Sep 2011 21:52:17 +0000 (14:52 -0700)]
MCS locks properly disable thread migration

Any time you disable notifs, you need to disable uthread migration too.
The reason for this is that we can't atomically disable interrupts on a
vcore, so we need to make sure we're not moved around in the instant
after we read vcoreid and before we actually disable notifs.  x86's
'cli' doesn't have this issue.  =)

I put an assert in disable_notifs() to catch any future callers that
don't do this.

Also note that disabling/enabling notifs isn't the only reason to
disable migration; we want to disable migration for code that requires
staying on a vcore.  We don't necessarily want to turn it off an on at
exactly the same call sites as enable/disable notifs.  Check
uthread_yield() for an example (note it doesn't even enable_notifs()

9 years agoUses vcore_yield() for the preempt_pending path
Barret Rhoden [Mon, 12 Sep 2011 21:21:03 +0000 (14:21 -0700)]
Uses vcore_yield() for the preempt_pending path

I'm considering getting rid of the preemption pending business
completely, and just dealing with it afterwards.  But so long as we have
it, we need to make it work so that we don't lose INDIR messages by
yielding without checking events, etc.

9 years agoAdded gawk check to the Makefile
Kevin Klues [Thu, 8 Sep 2011 22:40:35 +0000 (15:40 -0700)]
Added gawk check to the Makefile

9 years agoSparc's cpu_halt() enables interrupts
Barret Rhoden [Wed, 31 Aug 2011 21:16:11 +0000 (14:16 -0700)]
Sparc's cpu_halt() enables interrupts

This isn't atomic, so may suffer from the race mentioned above.  This
compiles and runs, barely.  I say barely since there seem to be some
other sparc issues atm (running mhello, for instance).

9 years agoFixes race where we'd ignore a kmsg when halting
Barret Rhoden [Wed, 31 Aug 2011 02:24:04 +0000 (19:24 -0700)]
Fixes race where we'd ignore a kmsg when halting

If an interrupt came in at the wrong time, right after PRKM returns
(more specifically, right after it turns on interrupts but after it
thought the list was empty), then we'd halt and miss the message til the
next interrupt.

To fix this, we want cpu_halt() to mean "turn on interrupts and then
halt the core, atomically".  x86 does this via some irq_handler()
hacking, though from what I've seen, "sti;hlt" won't get interrupts
before the hlt (not sure if this is intentional or not).

Other archs (sparc/riscv) will need to support similar semantics in
their cpu_halt(), as the code is now.  Alternatively (and slightly
preferred), we can shut down the core completely and have it come back
up and come in through the top of smp_idle().

9 years agoEvent queue throttling (XCC)
Barret Rhoden [Mon, 29 Aug 2011 22:06:19 +0000 (15:06 -0700)]
Event queue throttling (XCC)

If an INDIR alert is pending for an ev_q, we won't send more til the
first one was acknowledged.  Some extras will make it through (due to
the nature of the race, but extras are always okay.

On a simple block test, this reduced the INDIRs by 10% - not a big deal.
If you want to turn it off for debugging reasons, comment out the
check/return block at the top of alert_vcore().  I want to leave it on
all the time, since it might help me catch a bug.

Reinstall your kernel headers / rebuild the parlib stuff.