[lkml]   [2011]   [Jan]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
Subject[RFC] New console keyboard mode OFF

The current console keyboard situation can be improved by introducing
an "OFF" mode. All available modes for the console keyboard (RAW,
MEDIUMRAW, XLATE, and UNICODE) buffer key events in the current vt's
tty input. As recent Xorg releases no longer read input from the vt
there are two problems:

1) The tty input buffer eventually overflows because nothing is
reading it, triggering an infinite flush_to_ldisc() kworker loop.
2) If the vt's mode isn't changed to RAW or MEDIUMRAW, key events
remain translated by the kernel, causing shenanigans like pressing
Ctrl+C in Xterm would send SIGTERM to the X server.

Xorg fixed these problems in 2008 by always setting the vt to RAW mode
and making a handler call tcflush per keystroke if the
"AllowEmptyInput" option is enabled. I stumbled upon this issue when I
set my X server to not use AllowEmptyInput and manually defined input
devices using evdev. After a set amount of key presses in an X session
my system would experience 1000 wakeups/s, eating no real cpu time but
consuming three extra watts. While I appreciate that this is an
uncommon setup, the current solution is still sort-of hacky as it
means per-keystroke a key is simultaneously reported to userspace via
input device files as well as by the vt keyboard code, through the tty
and line descriptor until it gets to userspace where it is then
flushed by Xorg.

The addition of a new console keyboard mode "OFF" would remove the
need for the tcflush handler hack in Xorg and has the added benefit of
less code being run and less trips to userspace per key event. It is
simple to implement, either by returning early in the console input
handler's key event callback or by unregistering the console's input
handler while in the OFF mode VT. I have tried both methods with
success. Remember of course that the console keyboard mode is a per vt

The only complication is the way shift keys are handled (or modifiers
in X parlance.) As shift key up/down events are counted to get the
current shift state across all vts, disabling the input handler with a
shift key down makes things get out of sync with reality. Thus, the
key_down array (from which shift_down is calculated) should be cleared
when disabling the input handler. The other method of returning early
must still count shift key events. Note that neither SysRq, which uses
it's own input event handler, nor the Caps-Lock state, which is a
per-console thing, are affected by these changes.

The flush_to_ldisc() infinite kworker loop issue exists independent of
Xorg. It can be triggered by changing to a vt where nothing is reading
from it's input, like a log display, and mashing your keyboard for a
few minutes. Unlikely, but still present.

The Xorg commits I mentioned:


Arthur Taylor

 \ /
  Last update: 2011-01-09 10:03    [from the cache]
©2003-2011 Jasper Spaans