aboutsummaryrefslogtreecommitdiffstats
path: root/litmus/ikglp_lock.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2013-02-11 22:48:51 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2013-02-11 22:48:51 -0500
commitc063e088be8e1bcbb6a76b8cd087f8dc8b6923b2 (patch)
tree4450780888858cfbb0d042605035db689c3eedbe /litmus/ikglp_lock.c
parent40d12009bd0c3515c5bfee5425bd80f58cdd7b73 (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.c4
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);