| Both sides previous revision Previous revision Next revision | Previous revision |
| andriygapon:avgsyscons [2011/12/17 20:59] – wip AndriyGapon | andriygapon:avgsyscons [2016/07/21 11:02] (current) – Move user articles under user heirarchy KubilayKocak |
|---|
| At this stage the interrupts are already enabled and there are multiple threads of execution. There are still no userland processes. This is the most complex context from the point of view of locking. The keyboard driver's interrupt handler may get invoked but it must not interfere with kernel polling. | At this stage the interrupts are already enabled and there are multiple threads of execution. There are still no userland processes. This is the most complex context from the point of view of locking. The keyboard driver's interrupt handler may get invoked but it must not interfere with kernel polling. |
| So, in this context in particular, the keyboard drivers must ensure that either their interrupt handler do not fire or that they do not modify parts of the internal state that can be concurrently accessed by the polling code path. | So, in this context in particular, the keyboard drivers must ensure that either their interrupt handler do not fire or that they do not modify parts of the internal state that can be concurrently accessed by the polling code path. |
| | Giant is already held in this context - it is acquired in ''%%start_init%%'' before the ''%%vfs_mountroot%%'' call. |
| |
| ==== 3. KDB/DDB context ==== | ==== 3. KDB/DDB context ==== |
| |
| ==== 5. Late shutdown context ==== | ==== 5. Late shutdown context ==== |
| This is a context where the kernel may ask to press a key for some action. E.g. after ''%%shutdown -h%%'' the kernel asks "to press any key to reboot". This case is rather similar to the first case. | This is a context where the kernel may ask to press a key for some action. E.g. after ''%%shutdown -h%%'' the kernel asks "to press any key to reboot". At this stage the interrupts and the scheduler should still be functional. The ''%%Giant%%'' is held by the shutdown thread - it's taken in ''%%sys_reboot%%''. |
| |
| ==== Summary ==== | ==== Summary ==== |
| * from the kernel in polling mode | * from the kernel in polling mode |
| The first two are already protected by the proper ''%%Giant%%'' locking, so there is no need for additional locking in these code paths. On the other hand the entry points for the third path must be explicitly protected. That protection must obey the previous rule about ''%%kdb_active%%''. | The first two are already protected by the proper ''%%Giant%%'' locking, so there is no need for additional locking in these code paths. On the other hand the entry points for the third path must be explicitly protected. That protection must obey the previous rule about ''%%kdb_active%%''. |
| | |
| | Additional observation is that the kernel never really competes with the userland for access to the keyboard(s). The kernel polls the console for input either when there is no userland yet or there is no userland already or either ''%%panic%%'' or ''%%kdb%%'' are entered and the userland is "suspended". |
| | Also, it can be seen that at present there is no concurrent access to the console input from the kernel side too. So the code doesn't expect this and is not equipped to properly handle such a situation yet. |
| | |
| | One more thing to note is that at present the kernel always accesses the console input in a well-defined locking locking context. Either it is a "single-threaded"/"lock-less" context of the ''%%panic%%''/''%%kdb%%'' or a rather clean context of a specific system boot or shutdown stage. |
| |
| ===== Interaction between the input and output paths ===== | ===== Interaction between the input and output paths ===== |
| |
| The current code has one non-trivial interaction between the output path and input path. ''%%syscons%%'' tries to provide the following behavior: if a Scroll Lock mode is active and kernel prints something to a console, the the Scroll Lock must be deactivated and correspondingly a Scroll Lock LED on a keyboard must be turned off. As mentioned above, the kernel may produce output from arbitrary contexts, but turning off the LED requires calling into the keyboard drivers which require specific locking and currently use the ''%%Giant%%''. So a direct call may result in a LOR and potentially a deadlock. One way to work around this problem is to execute the action asynchronously via a ''%%taskqueue%%''. | The current code has one non-trivial interaction between the output path and input path. ''%%syscons%%'' tries to provide the following behavior: if a Scroll Lock mode is active and kernel prints something to a console, the the Scroll Lock must be deactivated and correspondingly a Scroll Lock LED on a keyboard must be turned off. As mentioned above, the kernel may produce output from arbitrary contexts, but turning off the LED requires calling into the keyboard drivers which require specific locking and currently use the ''%%Giant%%''. So a direct call may result in a LOR and potentially a deadlock (provided that all the locking requirements are properly satisfied). One way to work around this problem is to execute the action asynchronously via a ''%%taskqueue%%''. |
| | |
| | ===== ukbd ===== |
| | |
| | The problem with ''%%ukbd%%'' is that it has to interact with rather complex hardware compared to AT compatible keyboard controller, besides also unlike the AT keyboard controller the USB controller can be shared with rather non-trivial peripherals and their drivers. By necessity the underlying USB subsystem must use multiple threads in most of the contexts. Thus the ''%%ukbd%%'' driver must honor concurrency and locking strategies of the USB subsystem when the USB threads are active. |
| | |
| | Summary. Context 1 is not applicable to the ''%%ukbd%%''. In contexts 3 and 4 the USB threads do not run, so the ''%%ukbd%%'' doesn't have to acquire any locks (in fact in context 3 it must not acquire any locks) and also it must directly go all the way to hardware via direct calls. In context 2 the ''%%ukbd%%'' must acquire the necessary locks, the ''%%Giant%%'' currently, if it is called via routines related to polling. It's important to note that in this context the ''%%ukbd%%'' driver works in interrupt driven mode internally. The USB threads are running and they perform the actual interaction with the hardware. So the ''%%ukbd%%'' must not access the hardware directly. Also, if it has to sleep/wait for the USB threads, then it should release the ''%%Giant%%'' while doing so, so that the USB threads can interact with the ''%%ukbd%%'' under ''%%Giant%%'' protection. ukbd is detached before context 5 is entered, so it is useless there and that context is irrelevant to ukbd. |
| | |
| | Routines for non-polling access should already be called with the proper locks, that fact can be asserted in the code. |
| |