The classic solution for priority inversion is priority inheritance; if a high-priority task finds itself blocked on a lock, it lends its priority to the lock holder, allowing the holder to progress and release the lock. Linux implements priority inheritance for the realtime scheduling classes, but that approach is not really applicable to the normal scheduling classes (where priorities are far more dynamic) or the deadline class (which has no priorities at all). So taking a different tack is called for.
That tack is proxy execution. While priority inheritance donates a task's priority to another, proxy execution also donates the waiting task's available CPU time. In short, if a high-priority ("donor") task finds itself waiting on a lock, the lock holder (the "proxy") is allowed to run in its place, using the donor's time on the CPU to get its work done. It is a relatively simple idea, but the implementation is anything but.
This patch series from John Stultz (containing the work of several developers) pushes the proxy-execution project one significant step forward. It starts by adding a new kernel configuration option, SCHED_PROXY_EXEC, to control whether the feature is built into the kernel. At this point, proxy execution is incompatible with realtime preemption, and with the extensible scheduler class as well, so the kernel cannot (yet) be built with all of those features enabled.