Kernel: Fix tty race condition, introduce new tty_sleeping() function.
authorWill Sowerbutts <will@sowerbutts.com>
Fri, 20 Feb 2015 21:21:29 +0000 (21:21 +0000)
committerWill Sowerbutts <will@sowerbutts.com>
Fri, 20 Feb 2015 21:36:02 +0000 (21:36 +0000)
commitb3132168b6fd183a577ca9e4242951f7359f3a3f
tree9d5dd727a8b7ad07f122558b9e0d4e3bf87bbce5
parent881de4242780f0f5cb5745adec4703bab612e276
Kernel: Fix tty race condition, introduce new tty_sleeping() function.

There are a few cases where a process goes to sleep while waiting for
the UART to be ready to transmit. We want to be able to use interrupts
to alert us to the UART becoming ready again (for example once the UART
has drained or the flow control pins have changed).

There was a race to put the process to sleep after tty_writeready()
reports that it the UART is busy but before psleep() is called; the
waking interrupt may arrive in that interval, wakeup() will not find
any sleeping process, and no further interrupts will arrive after
psleep() returns.

The solution adopted here is to normally run with these waking
interrupts disabled. When we put the process to sleep we enable the
waking interrupts and call psleep() atomically. A new platform
tty_sleeping() function is required to do the work of enabling the
relevant interrupts for the given tty. The platform interrupt handler
then disables these interrupts when calling tty_outproc() to awaken the
process.
Kernel/include/tty.h
Kernel/tty.c