|
@@ -1192,7 +1192,6 @@ static int push_rt_task(struct rq *rq)
|
|
|
{
|
|
|
struct task_struct *next_task;
|
|
|
struct rq *lowest_rq;
|
|
|
- int paranoid = RT_MAX_TRIES;
|
|
|
|
|
|
if (!rq->rt.overloaded)
|
|
|
return 0;
|
|
@@ -1226,23 +1225,34 @@ static int push_rt_task(struct rq *rq)
|
|
|
struct task_struct *task;
|
|
|
/*
|
|
|
* find lock_lowest_rq releases rq->lock
|
|
|
- * so it is possible that next_task has changed.
|
|
|
- * If it has, then try again.
|
|
|
+ * so it is possible that next_task has migrated.
|
|
|
+ *
|
|
|
+ * We need to make sure that the task is still on the same
|
|
|
+ * run-queue and is also still the next task eligible for
|
|
|
+ * pushing.
|
|
|
*/
|
|
|
task = pick_next_pushable_task(rq);
|
|
|
- if (unlikely(task != next_task) && task && paranoid--) {
|
|
|
- put_task_struct(next_task);
|
|
|
- next_task = task;
|
|
|
- goto retry;
|
|
|
+ if (task_cpu(next_task) == rq->cpu && task == next_task) {
|
|
|
+ /*
|
|
|
+ * If we get here, the task hasnt moved at all, but
|
|
|
+ * it has failed to push. We will not try again,
|
|
|
+ * since the other cpus will pull from us when they
|
|
|
+ * are ready.
|
|
|
+ */
|
|
|
+ dequeue_pushable_task(rq, next_task);
|
|
|
+ goto out;
|
|
|
}
|
|
|
|
|
|
+ if (!task)
|
|
|
+ /* No more tasks, just exit */
|
|
|
+ goto out;
|
|
|
+
|
|
|
/*
|
|
|
- * Once we have failed to push this task, we will not
|
|
|
- * try again, since the other cpus will pull from us
|
|
|
- * when they are ready
|
|
|
+ * Something has shifted, try again.
|
|
|
*/
|
|
|
- dequeue_pushable_task(rq, next_task);
|
|
|
- goto out;
|
|
|
+ put_task_struct(next_task);
|
|
|
+ next_task = task;
|
|
|
+ goto retry;
|
|
|
}
|
|
|
|
|
|
deactivate_task(rq, next_task, 0);
|