diff options
author | Bjoern Brandenburg <bbb@mpi-sws.org> | 2013-01-11 08:10:43 -0500 |
---|---|---|
committer | Bjoern Brandenburg <bbb@mpi-sws.org> | 2013-02-04 09:24:58 -0500 |
commit | c7cd5432b98df518b05bc8978d34382797fd9a05 (patch) | |
tree | 965b87bee5d38ecf2e5d3218e842533e8610e597 | |
parent | 4bd4eacab5070ac3003925b50a3d03069ae15e4a (diff) |
P-FP: fix BUG_ON releated to priority inheritancearchive/unc-master-3.0
In some cases, the PCP priority inheritance code triggered a
(defensive) BUG_ON() in fp_common.c. This shuffles the order of
operations a bit to be compliant with the restriction that tasks are
never compared against themselves.
-rw-r--r-- | litmus/sched_pfp.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/litmus/sched_pfp.c b/litmus/sched_pfp.c index 91e52391a173..0e875a3b5cba 100644 --- a/litmus/sched_pfp.c +++ b/litmus/sched_pfp.c | |||
@@ -182,7 +182,7 @@ static struct task_struct* pfp_schedule(struct task_struct * prev) | |||
182 | np = exists && is_np(pfp->scheduled); | 182 | np = exists && is_np(pfp->scheduled); |
183 | sleep = exists && is_completed(pfp->scheduled); | 183 | sleep = exists && is_completed(pfp->scheduled); |
184 | migrate = exists && get_partition(pfp->scheduled) != pfp->cpu; | 184 | migrate = exists && get_partition(pfp->scheduled) != pfp->cpu; |
185 | preempt = migrate || fp_preemption_needed(&pfp->ready_queue, prev); | 185 | preempt = !blocks && (migrate || fp_preemption_needed(&pfp->ready_queue, prev)); |
186 | 186 | ||
187 | /* If we need to preempt do so. | 187 | /* If we need to preempt do so. |
188 | * The following checks set resched to 1 in case of special | 188 | * The following checks set resched to 1 in case of special |
@@ -1089,8 +1089,10 @@ static void pcp_priority_inheritance(void) | |||
1089 | fp_set_prio_inh(pfp, blocker, blocked); | 1089 | fp_set_prio_inh(pfp, blocker, blocked); |
1090 | } | 1090 | } |
1091 | 1091 | ||
1092 | /* check if anything changed */ | 1092 | /* Check if anything changed. If the blocked job is current, then it is |
1093 | if (fp_higher_prio(fp_prio_peek(&pfp->ready_queue), pfp->scheduled)) | 1093 | * just blocking and hence is going to call the scheduler anyway. */ |
1094 | if (blocked != current && | ||
1095 | fp_higher_prio(fp_prio_peek(&pfp->ready_queue), pfp->scheduled)) | ||
1094 | preempt(pfp); | 1096 | preempt(pfp); |
1095 | 1097 | ||
1096 | raw_spin_unlock_irqrestore(&pfp->slock, flags); | 1098 | raw_spin_unlock_irqrestore(&pfp->slock, flags); |
@@ -1201,10 +1203,10 @@ static void pcp_lower_ceiling(struct pcp_semaphore* sem) | |||
1201 | 1203 | ||
1202 | TRACE_CUR("PCP released sem %p\n", sem); | 1204 | TRACE_CUR("PCP released sem %p\n", sem); |
1203 | 1205 | ||
1206 | pcp_priority_inheritance(); | ||
1207 | |||
1204 | /* Wake up all ceiling-blocked jobs that now pass the ceiling. */ | 1208 | /* Wake up all ceiling-blocked jobs that now pass the ceiling. */ |
1205 | pcp_resume_unblocked(); | 1209 | pcp_resume_unblocked(); |
1206 | |||
1207 | pcp_priority_inheritance(); | ||
1208 | } | 1210 | } |
1209 | 1211 | ||
1210 | static void pcp_update_prio_ceiling(struct pcp_semaphore* sem, | 1212 | static void pcp_update_prio_ceiling(struct pcp_semaphore* sem, |