Do remember that current CPUs can dynamically run cores/hyper-threads at different clock speeds at the same time. Not to mention significantly mismatched performance ones (eg ARM big.LITTLE).
If you didn't have fairness, and the developer hadn't carefully assigned threads to cpus based on performance / priority of the work the thread is doing (and locked the CPU clock speeds), then the higher performing ones will starve out the others.
Fairness at least ensures that the developers writing simple straightforward code would get simple straightforward behaviour.
Then again, if you are writing simple straightforward code you shouldn't be mucking around with thread priorities. In fact probably you shouldn't be dealing with raw threads and mutices in the first place but using some higher level abstraction.
If you didn't have fairness, and the developer hadn't carefully assigned threads to cpus based on performance / priority of the work the thread is doing (and locked the CPU clock speeds), then the higher performing ones will starve out the others.
Fairness at least ensures that the developers writing simple straightforward code would get simple straightforward behaviour.