What is priority inversion, and how does it happen?
A high-priority task waits for a resource held by a low-priority task, and a medium-priority task that doesn't need the resource preempts the low one, so the high-priority task is effectively delayed by a less important task.
* Task 1 waits on Task 4's lock, and Task 2 runs in between: the priorities of Tasks 1 and 4 are inverted. *
Step by step, with Task 1 highest and Task 4 lowest:
- Task 4 (low) is running and takes a lock on a shared resource.
- Task 1 (high) becomes ready and preempts Task 4, as it should.
- Task 1 needs the same resource. It is locked, so Task 1 blocks, and Task 4 resumes to finish with the resource.
- Task 2 (medium) becomes ready. It outranks Task 4, so it preempts Task 4, and Task 2 runs even though Task 1 is waiting.
- Only when Task 2 is done can Task 4 continue, release the resource, and let Task 1 run.
Waiting in step 3 is expected and short: Task 4 only needs to finish its critical section. The problem is step 4. Task 1's delay now depends on how long Task 2 runs, a task it has nothing to do with, and in the worst case that delay is unbounded, which breaks every real-time guarantee.
Tip: it takes three priorities to cause the problem. The high one waits on the low one, and the medium one keeps the low one from finishing.
Go deeper:
Wikipedia — Priority inversion — the general problem, the solutions, and famous cases.