diff options
| -rw-r--r-- | Documentation/lockdep-design.txt | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/Documentation/lockdep-design.txt b/Documentation/lockdep-design.txt new file mode 100644 index 000000000000..00d93605bfd3 --- /dev/null +++ b/Documentation/lockdep-design.txt | |||
| @@ -0,0 +1,197 @@ | |||
| 1 | Runtime locking correctness validator | ||
| 2 | ===================================== | ||
| 3 | |||
| 4 | started by Ingo Molnar <mingo@redhat.com> | ||
| 5 | additions by Arjan van de Ven <arjan@linux.intel.com> | ||
| 6 | |||
| 7 | Lock-class | ||
| 8 | ---------- | ||
| 9 | |||
| 10 | The basic object the validator operates upon is a 'class' of locks. | ||
| 11 | |||
| 12 | A class of locks is a group of locks that are logically the same with | ||
| 13 | respect to locking rules, even if the locks may have multiple (possibly | ||
| 14 | tens of thousands of) instantiations. For example a lock in the inode | ||
| 15 | struct is one class, while each inode has its own instantiation of that | ||
| 16 | lock class. | ||
| 17 | |||
| 18 | The validator tracks the 'state' of lock-classes, and it tracks | ||
| 19 | dependencies between different lock-classes. The validator maintains a | ||
| 20 | rolling proof that the state and the dependencies are correct. | ||
| 21 | |||
| 22 | Unlike an lock instantiation, the lock-class itself never goes away: when | ||
| 23 | a lock-class is used for the first time after bootup it gets registered, | ||
| 24 | and all subsequent uses of that lock-class will be attached to this | ||
| 25 | lock-class. | ||
| 26 | |||
| 27 | State | ||
| 28 | ----- | ||
| 29 | |||
| 30 | The validator tracks lock-class usage history into 5 separate state bits: | ||
| 31 | |||
| 32 | - 'ever held in hardirq context' [ == hardirq-safe ] | ||
| 33 | - 'ever held in softirq context' [ == softirq-safe ] | ||
| 34 | - 'ever held with hardirqs enabled' [ == hardirq-unsafe ] | ||
| 35 | - 'ever held with softirqs and hardirqs enabled' [ == softirq-unsafe ] | ||
| 36 | |||
| 37 | - 'ever used' [ == !unused ] | ||
| 38 | |||
| 39 | Single-lock state rules: | ||
| 40 | ------------------------ | ||
| 41 | |||
| 42 | A softirq-unsafe lock-class is automatically hardirq-unsafe as well. The | ||
| 43 | following states are exclusive, and only one of them is allowed to be | ||
| 44 | set for any lock-class: | ||
| 45 | |||
| 46 | <hardirq-safe> and <hardirq-unsafe> | ||
| 47 | <softirq-safe> and <softirq-unsafe> | ||
| 48 | |||
| 49 | The validator detects and reports lock usage that violate these | ||
| 50 | single-lock state rules. | ||
| 51 | |||
| 52 | Multi-lock dependency rules: | ||
| 53 | ---------------------------- | ||
| 54 | |||
| 55 | The same lock-class must not be acquired twice, because this could lead | ||
| 56 | to lock recursion deadlocks. | ||
| 57 | |||
| 58 | Furthermore, two locks may not be taken in different order: | ||
| 59 | |||
| 60 | <L1> -> <L2> | ||
| 61 | <L2> -> <L1> | ||
| 62 | |||
| 63 | because this could lead to lock inversion deadlocks. (The validator | ||
| 64 | finds such dependencies in arbitrary complexity, i.e. there can be any | ||
| 65 | other locking sequence between the acquire-lock operations, the | ||
| 66 | validator will still track all dependencies between locks.) | ||
| 67 | |||
| 68 | Furthermore, the following usage based lock dependencies are not allowed | ||
| 69 | between any two lock-classes: | ||
| 70 | |||
| 71 | <hardirq-safe> -> <hardirq-unsafe> | ||
| 72 | <softirq-safe> -> <softirq-unsafe> | ||
| 73 | |||
| 74 | The first rule comes from the fact the a hardirq-safe lock could be | ||
| 75 | taken by a hardirq context, interrupting a hardirq-unsafe lock - and | ||
| 76 | thus could result in a lock inversion deadlock. Likewise, a softirq-safe | ||
| 77 | lock could be taken by an softirq context, interrupting a softirq-unsafe | ||
| 78 | lock. | ||
| 79 | |||
| 80 | The above rules are enforced for any locking sequence that occurs in the | ||
| 81 | kernel: when acquiring a new lock, the validator checks whether there is | ||
| 82 | any rule violation between the new lock and any of the held locks. | ||
| 83 | |||
| 84 | When a lock-class changes its state, the following aspects of the above | ||
| 85 | dependency rules are enforced: | ||
| 86 | |||
| 87 | - if a new hardirq-safe lock is discovered, we check whether it | ||
| 88 | took any hardirq-unsafe lock in the past. | ||
| 89 | |||
| 90 | - if a new softirq-safe lock is discovered, we check whether it took | ||
| 91 | any softirq-unsafe lock in the past. | ||
| 92 | |||
| 93 | - if a new hardirq-unsafe lock is discovered, we check whether any | ||
| 94 | hardirq-safe lock took it in the past. | ||
| 95 | |||
| 96 | - if a new softirq-unsafe lock is discovered, we check whether any | ||
| 97 | softirq-safe lock took it in the past. | ||
| 98 | |||
| 99 | (Again, we do these checks too on the basis that an interrupt context | ||
| 100 | could interrupt _any_ of the irq-unsafe or hardirq-unsafe locks, which | ||
| 101 | could lead to a lock inversion deadlock - even if that lock scenario did | ||
| 102 | not trigger in practice yet.) | ||
| 103 | |||
| 104 | Exception: Nested data dependencies leading to nested locking | ||
| 105 | ------------------------------------------------------------- | ||
| 106 | |||
| 107 | There are a few cases where the Linux kernel acquires more than one | ||
| 108 | instance of the same lock-class. Such cases typically happen when there | ||
| 109 | is some sort of hierarchy within objects of the same type. In these | ||
| 110 | cases there is an inherent "natural" ordering between the two objects | ||
| 111 | (defined by the properties of the hierarchy), and the kernel grabs the | ||
| 112 | locks in this fixed order on each of the objects. | ||
| 113 | |||
| 114 | An example of such an object hieararchy that results in "nested locking" | ||
| 115 | is that of a "whole disk" block-dev object and a "partition" block-dev | ||
| 116 | object; the partition is "part of" the whole device and as long as one | ||
| 117 | always takes the whole disk lock as a higher lock than the partition | ||
| 118 | lock, the lock ordering is fully correct. The validator does not | ||
| 119 | automatically detect this natural ordering, as the locking rule behind | ||
| 120 | the ordering is not static. | ||
| 121 | |||
| 122 | In order to teach the validator about this correct usage model, new | ||
| 123 | versions of the various locking primitives were added that allow you to | ||
| 124 | specify a "nesting level". An example call, for the block device mutex, | ||
| 125 | looks like this: | ||
| 126 | |||
| 127 | enum bdev_bd_mutex_lock_class | ||
| 128 | { | ||
| 129 | BD_MUTEX_NORMAL, | ||
| 130 | BD_MUTEX_WHOLE, | ||
| 131 | BD_MUTEX_PARTITION | ||
| 132 | }; | ||
| 133 | |||
| 134 | mutex_lock_nested(&bdev->bd_contains->bd_mutex, BD_MUTEX_PARTITION); | ||
| 135 | |||
| 136 | In this case the locking is done on a bdev object that is known to be a | ||
| 137 | partition. | ||
| 138 | |||
| 139 | The validator treats a lock that is taken in such a nested fasion as a | ||
| 140 | separate (sub)class for the purposes of validation. | ||
| 141 | |||
| 142 | Note: When changing code to use the _nested() primitives, be careful and | ||
| 143 | check really thoroughly that the hiearchy is correctly mapped; otherwise | ||
| 144 | you can get false positives or false negatives. | ||
| 145 | |||
| 146 | Proof of 100% correctness: | ||
| 147 | -------------------------- | ||
| 148 | |||
| 149 | The validator achieves perfect, mathematical 'closure' (proof of locking | ||
| 150 | correctness) in the sense that for every simple, standalone single-task | ||
| 151 | locking sequence that occured at least once during the lifetime of the | ||
| 152 | kernel, the validator proves it with a 100% certainty that no | ||
| 153 | combination and timing of these locking sequences can cause any class of | ||
| 154 | lock related deadlock. [*] | ||
| 155 | |||
| 156 | I.e. complex multi-CPU and multi-task locking scenarios do not have to | ||
| 157 | occur in practice to prove a deadlock: only the simple 'component' | ||
| 158 | locking chains have to occur at least once (anytime, in any | ||
| 159 | task/context) for the validator to be able to prove correctness. (For | ||
| 160 | example, complex deadlocks that would normally need more than 3 CPUs and | ||
| 161 | a very unlikely constellation of tasks, irq-contexts and timings to | ||
| 162 | occur, can be detected on a plain, lightly loaded single-CPU system as | ||
| 163 | well!) | ||
| 164 | |||
| 165 | This radically decreases the complexity of locking related QA of the | ||
| 166 | kernel: what has to be done during QA is to trigger as many "simple" | ||
| 167 | single-task locking dependencies in the kernel as possible, at least | ||
| 168 | once, to prove locking correctness - instead of having to trigger every | ||
| 169 | possible combination of locking interaction between CPUs, combined with | ||
| 170 | every possible hardirq and softirq nesting scenario (which is impossible | ||
| 171 | to do in practice). | ||
| 172 | |||
| 173 | [*] assuming that the validator itself is 100% correct, and no other | ||
| 174 | part of the system corrupts the state of the validator in any way. | ||
| 175 | We also assume that all NMI/SMM paths [which could interrupt | ||
| 176 | even hardirq-disabled codepaths] are correct and do not interfere | ||
| 177 | with the validator. We also assume that the 64-bit 'chain hash' | ||
| 178 | value is unique for every lock-chain in the system. Also, lock | ||
| 179 | recursion must not be higher than 20. | ||
| 180 | |||
| 181 | Performance: | ||
| 182 | ------------ | ||
| 183 | |||
| 184 | The above rules require _massive_ amounts of runtime checking. If we did | ||
| 185 | that for every lock taken and for every irqs-enable event, it would | ||
| 186 | render the system practically unusably slow. The complexity of checking | ||
| 187 | is O(N^2), so even with just a few hundred lock-classes we'd have to do | ||
| 188 | tens of thousands of checks for every event. | ||
| 189 | |||
| 190 | This problem is solved by checking any given 'locking scenario' (unique | ||
| 191 | sequence of locks taken after each other) only once. A simple stack of | ||
| 192 | held locks is maintained, and a lightweight 64-bit hash value is | ||
| 193 | calculated, which hash is unique for every lock chain. The hash value, | ||
| 194 | when the chain is validated for the first time, is then put into a hash | ||
| 195 | table, which hash-table can be checked in a lockfree manner. If the | ||
| 196 | locking chain occurs again later on, the hash table tells us that we | ||
| 197 | dont have to validate the chain again. | ||
