This is an old revision of the document!
Locking in syscons(4), its subordinate drivers and some edge cases
Overview
In general syscons output path to video hardware and input path from keyboards are sufficiently independent except for one special case described below. The output path is initiated in interfaces like printf and db_printf which can be called from literally any context in FreeBSD kernel. As such the output path must be lock-less or, at least, it must use context-aware locking to avoid deadlocks from unexpected re-entrance. Examples of the latter include entering kdb or panic(9) on one CPU while another CPU is at an arbitrary place in the middle of the output path.
Currently the output path code utilizes only spinlocks. It seems to be non-perfect from the point of view of protecting from the unexpected re-entrance. It is clear if the perfection can be achieved here and at what cost. Consider for example a re-entrance in the middle of non-atomic hardware programming. But at the very least the locking in the output path should take into account kdb_active and SCHEDULER_STOPPED.
Input path locking
Input path is the code involved into getting data from keyboards and similar input devices. The FreeBSD kernel is interested only in keyboards input, so this article is limited only to those. Currently input path is protected by the Giant in normal contexts. The special contexts will be described later. With the exception of ukbd(4) USB keyboard driver no code in syscons(4) and other keyboard drivers depends on the special properties of the Giant. So the Giant could be easily replaced with a separate “syscons lock” mutex. Peculiarities of ukbd(4) will be described later.
The Giant is almost never acquired explicitly. Mostly its use is requested via the following means:
D_NEEDGIANTflag for character devicestaskqueue_swi_giantis used for asynchronous actionsGiant-protected version of callouts is usedGiantis passed as a lock totty_alloc_mutex(), so that it is used as tty-level lock- interrupt handlers of the keyboard drivers are not declared as
INTR_MPSAFE, so the interrupt threads acquire theGiantbefore executing the handlers
So the above cases would have to be properly converted if/when the Giant is replaced with the syscons lock.
The Giant is acquired explicitly only in sckbdevent, sckbdevent is always called as kb_callback.kc_func and it seems that in most if not all cases it is invoked either from a callout or from an interrupt handler (called via kbdd_intr). So it is possible that this use of the Giant can be replaced with mtx_assert(MA_OWNED). It seems that kb_callback.kc_func must be called with the Giant held by necessity as the code that calls it also modifies internal state of the corresponding keyboard driver.