diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2013-02-11 22:48:51 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2013-02-11 22:48:51 -0500 |
commit | c063e088be8e1bcbb6a76b8cd087f8dc8b6923b2 (patch) | |
tree | 4450780888858cfbb0d042605035db689c3eedbe /litmus/ikglp_lock.c | |
parent | 40d12009bd0c3515c5bfee5425bd80f58cdd7b73 (diff) |
BUG FIX: Support DGLs with PRIOQ_MUTEXwip-prioq-dgl
First 'working' implementation of DGLs with PRIOQ_MUTEX.
(All other code prior was work-in-progress.)
General approach:
Because of priority queue order, PRIOQ_MUTEX DGLs must be
*acquired* atomically. This means that a task cannot
acquire an available PRIOQ_MUTEX if another PRIOQ_MUTEX
is not available at the same time. Requests are buffered
in PRIOQ_MUTEX and the resource 'idles'-- that is, the
mutex owner is NULL, but there are waiting tasks for the
resource.
Several notes/side-effects:
1) A high-priority task that idles a resource can
effectively block lower-priority tasks from acquiring
that resource. This is because the low-prio task
cannot skip ahead of the high-prio task in the priority
queue.
2) Priority inheritance from nesting can cause the
low-prioity task in #1 to jump over the high-priority
task and acquire the resource. This means that
any task blocked on a DGL that receives an increase
in priority while blocked on the DGL must trigger
a re-eval of the locks it can take. If the resources
can be acquired, then the task needs to be woken
up! <<<<< Lock acquisition via inheritance is entirely
new and weird! >>>>>
3) A similar case for #2 exists for priorty decreases
(example: this can happen when a task loses a donor)
while it is blocked on a PRIOQ_MUTEX. The high-priority
task described in #1 can change and become a lower-
priority task. Every idle lock (mutex owner is NULL)
on which the task losing priority must be revaluated---
it is possible that the (possible) new head on the
priority queue can take the lock. Note: This affects
BOTH singular and DGL resource requests, while
the case described in #2 only affects DGL requests
(because a singular request at the head of the priority
queue will never idle a resource).
Diffstat (limited to 'litmus/ikglp_lock.c')
-rw-r--r-- | litmus/ikglp_lock.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/litmus/ikglp_lock.c b/litmus/ikglp_lock.c index 3d79e41b42df..3fd760799a75 100644 --- a/litmus/ikglp_lock.c +++ b/litmus/ikglp_lock.c | |||
@@ -1401,7 +1401,9 @@ int ikglp_unlock(struct litmus_lock* l) | |||
1401 | struct nested_info, hp_binheap_node); | 1401 | struct nested_info, hp_binheap_node); |
1402 | ++count; | 1402 | ++count; |
1403 | } | 1403 | } |
1404 | litmus->decrease_prio(t, NULL); | 1404 | if (count) { |
1405 | litmus->decrease_prio(t, NULL); | ||
1406 | } | ||
1405 | WARN_ON(count > 2); // should not be greater than 2. only local fq inh and donation can be possible. | 1407 | WARN_ON(count > 2); // should not be greater than 2. only local fq inh and donation can be possible. |
1406 | } | 1408 | } |
1407 | raw_spin_unlock(&tsk_rt(t)->hp_blocked_tasks_lock); | 1409 | raw_spin_unlock(&tsk_rt(t)->hp_blocked_tasks_lock); |