USB2 + kdb support (UMASS disk dump + USB keyboard)
Robert Watson
rwatson at FreeBSD.org
Wed Feb 18 03:11:00 PST 2009
On Tue, 17 Feb 2009, Hans Petter Selasky wrote:
> With USB1 it was possible to use the USB keyboard in the debugger. With USB2
> this is also possible, but not as long as the keyboard driver is using
> Giant.
>
> Currently USB2 supports a special mode called polling mode, which is going
> to be removed, because even on a micro embedded system polling mode is not
> useful, which was my thought keeping this behaviour.
>
> Instead I want to enforce normal running mode where USB and timer callbacks
> are handled like normal when in the kernel debugger.
>
> Question:
>
> When the CPU is in the debugger and is asking for USB devices to be polled,
> is there a way to get the USB threads running again so that callbacks can be
> handled?
DDB is a very special execution environment intended to be able to be execute
in a number of sticky circumstances including:
- Complete deadlock of the system with interrupts disabled on all CPUs.
- panic() within the scheduler itself, possibly as a result of corrupted
scheduler data structures or violated invariants relating to threads,
locking, such as a corrupted mutex pointer being passed to a locking
primitive, etc.
- Following a crashdump that has reset disk controllers in order to perform a
dump from an unknown controller state.
- From within both fast and ithread interrupt handlers.
- From within callout handlers and task queue execution environments.
- From within the idle loop in idle threads, which must always be in a
runnable state and never block when the scheduler is in execution.
- From any regular code path in the kernel.
While in DDB, in general, no further kernel execution is permitted, and we
disable interrupts and IPI all CPUs (ideally with an NMI on supporting
platforms) to ensure that is the case. To add insult to injury, the kernel
then has to be restartable again after running in DDB for a potentially
extended period. On the whole this works well, although you can upset
accounting of process execution times in practice, or cause things to time out
oddly when the callout thread is suspended for an extended period (for
example).
This is the reason for the polled interface to all low-level console devices,
which provide a reliable, minimal, and lock-free path that can be used by the
debugger for I/O to the user, and in the case of serial ports, a serial
debugger. On the whole, this is possible because normal console and serial
parts support minimalist "just pop things in the I/O port" interfaces that are
moderately reentrant with respect to normal kernel interface with the device.
Execution of kernel threads for the purposes of I/O would violate a number of
the above requirements in at least the following ways:
- It would require restarting some or all of the kernel in a debugging
context.
- It would require entering the scheduler and relying on its data structures,
as well as potentially IPI'ing other CPUs if the thread in question were
already running there, requiring interrupt handling to be working and
enabled.
At the end of the day, DDB can only be used to debug things effectively if
they aren't used to interact with DDB, so not being able to debug USB well may
be a natural consequence of using USB to talk to DDB. However, USB, if used
to interact with DDB, must play by DDB's rules. Any weakening of DDB's
assumptions (no interrupts, no parallelism, no scheduling, no locking, ...)
will make DDB a less effective debugging tool, and if possible, we should try
to entirely avoid that. Certainly, executing complex code paths, such as the
kbd mux code requiring deferred execution contexts, is out of the question,
but it would be useful if a USB keyboard could be used in a minimal mode with
minimal code and functional footprint with DDB.
Robert N M Watson
Computer Laboratory
University of Cambridge
More information about the freebsd-current
mailing list