]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/commit
Add some locking to sc_cngetc().
authorBruce Evans <bde@FreeBSD.org>
Wed, 31 Aug 2016 11:10:39 +0000 (11:10 +0000)
committerBruce Evans <bde@FreeBSD.org>
Wed, 31 Aug 2016 11:10:39 +0000 (11:10 +0000)
commita95582c6fdf5c116d8a113272474dd7604e68cad
tree0afa8e3fd7b8d9936a7654df1620861c27d219f6
parent63dc81d861300d66d9a004954202e39e92a136f0
Add some locking to sc_cngetc().

Keyboard input needs Giant locking, and that is not possible to do
correctly here.  Use mtx_trylock() and proceed unlocked as before if
we can't acquire Giant (non-recursively), except in kdb mode don't
even try to acquire Giant.  Everything here is a hack, but it often
works.  Even if mtx_trylock() succeeds, this might be a LOR.

Keyboard input also needs screen locking, to handle screen updates
and switches.  Add this, using the same simplistic screen locking
as for sc_cnputc().

Giant must be acquired before the screen lock, and the screen lock
must be dropped when calling the keyboard driver (else it would get a
harmless LOR if it tries to acquire Giant).  It was intended that sc
cn open/close hide the locking calls, and they do for i/o functions
functions except for this complication.

Non-console keyboard input is still only Giant-locked, with screen
locking in some called functions.  This is correct for the keyboard
parts only.

When Giant cannot be acquired properly, atkbd and kbdmux tend to race
and work (they assume that the caller acquired Giant properly and don't
try to acquire it again or check that it has been acquired, and the
races rarely matter), while ukbd tends to deadlock or panic (since it
does the opposite, and has other usb threads to deadlock with).

The keyboard (Giant) locking here does very little, but the screen
locking completes screen locking for console mode except for not
detecting or handling deadlock.
sys/dev/syscons/syscons.c
sys/dev/syscons/syscons.h