Josh Radel
|
Priority inversion with multiple server priority inheritance
|
Josh Radel
10/21/2009 7:01 PM
post40469
|
Priority inversion with multiple server priority inheritance
Starting in QNX 6.4, priority inheritance follows client->server through multiple levels (from the 6.4.0 release notes:
"Priority inheritance no longer occurs just one level deep. (Ref# 53452, 56738)).
However, my testing has shown that, while priority inheritance does indeed follow the client->server1->server2 chain,
priority boosting from a send-blocked client only goes to the first server. This mismatch creates an opportunity for
unbounded priority inversion.
To test this, unpack the attached zip file, make, copy the binaries from the test_* directories over to a QNX
environment, copy the .sh files from test_client over to the same directory, and then, from that directory, run
test_prio_inversion.sh.
In short, what is happening in the test_prio_inversion.sh script (also described inside the script):
Client 1 runs at priority 3 and continually calls into the server in a loop
Client 2 runs at priority 30 and calls into the server with short sleeps in between its calls
A CPU hog task runs at priority 4, continually spinning for 30ms and then sleeping for 5ms
The server runs at some priority (doesn’t matter since it always inherits the priority of the client(s)) and, during
its message processing, makes calls to slogger
Slogger runs at some priority (doesn’t matter since it ends up inheriting the priority of the client via the server
through multiple level inheritance)
In a case where there is no priority inversion, Client 1 would only write to slogger when the hog task is sleeping,
unless Client 2 were send-blocked (in which case Client 1 would be boosted to Client 2’s priority, letting it run above
the hog task). However, we _do_ have priority inversion – Client 2 ends up getting stuck in the send-block state while
the CPU hog task runs.
When priority inheritance only followed one client->server level, we could avoid priority inversion by ensuring that any
intermediate servers were set to run at the highest priorities of any of the clients (for example, in the above
scenario, we would run the server at priority 30). This unfortunately meant that all calls from the server to slogger
would happen at priority 30 (regardless of the client’s priority), but at least avoided unbounded priority inversion.
With the current multiple level priority inheritance – but only single-level send-blocked boosting – we have
potentially unbounded priority inversion.
Ideally there is a solution that allows send-blocked clients to propagate their priorities down the entire multiple
server chain. Short of that, though, I think there needs to at least be a way to revert back to the pre-6.4 behavior of
single-level inheritance.
|
|
|