I'm not convinced there is anything major wrong with the patch but
them's the rules..
I am using my "David's mentor" hat to revert this as he's
offline for a while.
data structure called kse_upcall to manage UPCALL. All KSE binding
and loaning code are gone.
A thread owns an upcall can collect all completed syscall contexts in
its ksegrp, turn itself into UPCALL mode, and takes those contexts back
to userland. Any thread without upcall structure has to export their
contexts and exit at user boundary.
Any thread running in user mode owns an upcall structure, when it enters
kernel, if the kse mailbox's current thread pointer is not NULL, then
when the thread is blocked in kernel, a new UPCALL thread is created and
the upcall structure is transfered to the new UPCALL thread. if the kse
mailbox's current thread pointer is NULL, then when a thread is blocked
in kernel, no UPCALL thread will be created.
Each upcall always has an owner thread. Userland can remove an upcall by
calling kse_exit, when all upcalls in ksegrp are removed, the group is
atomatically shutdown. An upcall owner thread also exits when process is
in exiting state. when an owner thread exits, the upcall it owns is also
removed.
KSE is a pure scheduler entity. it represents a virtual cpu. when a thread
is running, it always has a KSE associated with it. scheduler is free to
assign a KSE to thread according thread priority, if thread priority is changed,
KSE can be moved from one thread to another.
When a ksegrp is created, there is always N KSEs created in the group. the
N is the number of physical cpu in the current system. This makes it is
possible that even an userland UTS is single CPU safe, threads in kernel still
can execute on different cpu in parallel. Userland calls kse_create to add more
upcall structures into ksegrp to increase concurrent in userland itself, kernel
is not restricted by number of upcalls userland provides.
The code hasn't been tested under SMP by author due to lack of hardware.
Reviewed by: julian
implement ALT_BREAK_TO_DEBUGGER. The caller provides a pointer to a state
variable to allow different state to be maintained for separate instances of
a device.
- Use struct vm_map * instead of vm_map_t in db_break.h to avoid its users
needing to include vm headers.
Requested by: njl
(show thread {address})
Remove the IDLE kse state and replace it with a change in
the way threads sahre KSEs. Every KSE now has a thread, which is
considered its "owner" however a KSE may also be lent to other
threads in the same group to allow completion of in-kernel work.
n this case the owner remains the same and the KSE will revert to the
owner when the other work has been completed.
All creations of upcalls etc. is now done from
kse_reassign() which in turn is called from mi_switch or
thread_exit(). This means that special code can be removed from
msleep() and cv_wait().
kse_release() does not leave a KSE with no thread any more but
converts the existing thread into teh KSE's owner, and sets it up
for doing an upcall. It is just inhibitted from being scheduled until
there is some reason to do an upcall.
Remove all trace of the kse_idle queue since it is no-longer needed.
"Idle" KSEs are now on the loanable queue.
- Make DDB use %y instead of %z.
- Teach GCC about %y.
- Implement support for the C99 %z format modifier.
Approved by: re@
Reviewed by: peter
Tested on: i386, sparc64
It is never used. I left it there from pre-KSE days as I didn't know
if I'd need it or not but now I know I don't.. It's functionality
is in TDI_IWAIT in the thread.
in specific situations. The owner thread must be blocked, and the
borrower can not proceed back to user space with the borrowed KSE.
The borrower will return the KSE on the next context switch where
teh owner wants it back. This removes a lot of possible
race conditions and deadlocks. It is consceivable that the
borrower should inherit the priority of the owner too.
that's another discussion and would be simple to do.
Also, as part of this, the "preallocatd spare thread" is attached to the
thread doing a syscall rather than the KSE. This removes the need to lock
the scheduler when we want to access it, as it's now "at hand".
DDB now shows a lot mor info for threaded proceses though it may need
some optimisation to squeeze it all back into 80 chars again.
(possible JKH project)
Upcalls are now "bound" threads, but "KSE Lending" now means that
other completing syscalls can be completed using that KSE before the upcall
finally makes it back to the UTS. (getting threads OUT OF THE KERNEL is
one of the highest priorities in the KSE system.) The upcall when it happens
will present all the completed syscalls to the KSE for selection.
name instead. (e.g., SLOCK instead of SMTX, TD_ON_LOCK() instead of
TD_ON_MUTEX()) Eventually a turnstile abstraction will be added that
will be shared with mutexes and other types of locks. SLOCK/TDI_LOCK will
be used internally by the turnstile code and will not be specific to
mutexes. Making the change now ensures that turnstiles can be dropped
in at a later date without affecting the ABI of userland applications.
MD function is just a wrapper around db_stack_trace_cmd() that prints out
a backtrace of curthread. Currently, this function is only implemented
on i386 and alpha (and the alpha version isn't quite tested yet, will do
that in a bit). Other changes:
- For i386, fix a bug in the raw frame address case. The eip we extract
from the passed in frame address does not match the frame we received.
Thus, instead of printing a bogus frame with the wrong eip, go ahead
and advance frame down to the same frame as the eip we are using.
- For alpha, attempt to add a way of doing a raw trace for alpha. Instead
of passing a frame address in 'addr', pass in a pointer to a structure
containing PC and KSP and use those to start the backtrace. The alpha
db_print_backtrace() uses asm to read in the current PC and KSP values
into such a request.
Tested on: i386
Requested by: many
X_db_search_symbol(). Otherwise we don't see important symbols in
non-verbosely written assembler code.
NetBSD already has this. The kld version already has a stronger form
of it without really trying -- linker_ddb_search_symbol() doesn't
support ddb's symbol search strategy parameter, so the kld
X_db_search_symbol() doesn't pass the parameter to linker_ddb...() and
linker_ddb...() doesn't make distinctions based on the symbol type.
db_elf.c now works better than db_kld.c when it works (which is essentially
when there are no modules except the kernel). It works after booting
with -d. db_kld.c doesn't work until lots of SYSINIT()s have run.
symbol table sections. Reconstruct the necessary section headers from
(ksym_start, ksym_end). This was much easier than converting to use
module metadata, and just works for static symbols, unlike db_kld when
there is no module metadata. Initialize (ksym_start, ksym_end) from
bootinfo on i386's only.
The boot loader should load section headers for all sections that it
loads, and apparently did this for at least the symbol table sections
when this file last worked under FreeBSD (on alphas only) and always
did this under NetBSD (where this file was obtained from). At least
on i386's, boot2 discards the section headers (except for converting
them to (bootinfo.bi_symtab, bootinfo.bi_esymtab), and as far as I can
tell, loader(8) discards them apart from converting them to the bootinfo
values and module metadata.
and renaming ALIGNED_POINTER() to _ALIGNED_POINTER() plus the following
hacks for i386's:
- define _ALIGNED_POINTER() if it is not already defined. Most non-i386
arches define it <machine/param.h> define it in <machine/param.h>,
although none actually used it in the kernel.
- define ksym_start and ksym_end. Most non-i386 arches still define and
initialize these in machdep.c although they didn't used them. Here is
a better place to define them but not to initialize them.
Don't attempt to follow null pointers for zombie processes in db_ps().
Style fix: use explicit an comparison with NULL for all null pointer
checks in db_ps() instead of for half of them.
db_interface.c:
Fixed ddb's handling of traps from with ddb on i386's only.
This was mostly fixed in rev.1.27 (by longjmp()'ing back to the top
level) but was completly broken in rev.1.48 (by not unwinding the new
state (mainly db_active) either before or after the longjmp(). This
mostly never worked for other arches, since rev.1.27 has not been ported
and lower level longjmp()'s only handle traps for memory accesses. All
cases should be handled at a lower level to provided better control and
simplify unwinding of state.
Implementation details: don't pretend to maintain db_active in a nested
way -- ddb cannot be reentered in a nested way. Use db_active instead
of the db_global_jmpbuf_valid flag and longjmp()'s return value for things
related to reentering ddb. [re]entering is still not atomic enough.
The ability to schedule multiple threads per process
(one one cpu) by making ALL system calls optionally asynchronous.
to come: ia64 and power-pc patches, patches for gdb, test program (in tools)
Reviewed by: Almost everyone who counts
(at various times, peter, jhb, matt, alfred, mini, bernd,
and a cast of thousands)
NOTE: this is still Beta code, and contains lots of debugging stuff.
expect slight instability in signals..
the indirection operator ('*') and address examination ('x/a') on
big-endian platoforms for which the above is not true, as well as on
little-endian platforms if the cut-off bits are not 0.
this is a low-functionality change that changes the kernel to access the main
thread of a process via the linked list of threads rather than
assuming that it is embedded in the process. It IS still embeded there
but remove all teh code that assumes that in preparation for the next commit
which will actually move it out.
Reviewed by: peter@freebsd.org, gallatin@cs.duke.edu, benno rice,
respects locks. Before SMPng, one was able to call psignal()
using the "call" command, but this is no longer possible because it
does not respect locks by itself. This is very useful when one has
gotten their machine into a state where it is impossible to spawn
ps/kill or su to root.
In this case, respecting locks essentially means trying to aquire the
proc lock before calling psignal(). We can't block in the debugger,
so if trylock fails, the operation fails. This also means that we
can't use pfind(), since that will attempt to lock the process for us.
Reviewed by: jhb
Note ALL MODULES MUST BE RECOMPILED
make the kernel aware that there are smaller units of scheduling than the
process. (but only allow one thread per process at this time).
This is functionally equivalent to teh previousl -current except
that there is a thread associated with each process.
Sorry john! (your next MFC will be a doosie!)
Reviewed by: peter@freebsd.org, dillon@freebsd.org
X-MFC after: ha ha ha ha