Browse Source

sched: call resched_task() conditionally from new task wake up path

- During wake up of a new task, task_new_fair() can do a resched_task()
  on the current task. Later in the code path, check_preempt_curr() also ends
  up doing the same, which can be avoided. Check if TIF_NEED_RESCHED is
  already set for the current task.

- task_new_fair() does a resched_task() on the current task unconditionally.
  This can be done only in case when child runs before the parent.

So this is a small speedup.

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Bharata B Rao 16 years ago
parent
commit
aec0a5142c
1 changed files with 8 additions and 1 deletions
  1. 8 1
      kernel/sched_fair.c

+ 8 - 1
kernel/sched_fair.c

@@ -1348,6 +1348,13 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p)
 	if (unlikely(se == pse))
 	if (unlikely(se == pse))
 		return;
 		return;
 
 
+	/*
+	 * We can come here with TIF_NEED_RESCHED already set from new task
+	 * wake up path.
+	 */
+	if (test_tsk_need_resched(curr))
+		return;
+
 	cfs_rq_of(pse)->next = pse;
 	cfs_rq_of(pse)->next = pse;
 
 
 	/*
 	/*
@@ -1620,10 +1627,10 @@ static void task_new_fair(struct rq *rq, struct task_struct *p)
 		 * 'current' within the tree based on its new key value.
 		 * 'current' within the tree based on its new key value.
 		 */
 		 */
 		swap(curr->vruntime, se->vruntime);
 		swap(curr->vruntime, se->vruntime);
+		resched_task(rq->curr);
 	}
 	}
 
 
 	enqueue_task_fair(rq, p, 0);
 	enqueue_task_fair(rq, p, 0);
-	resched_task(rq->curr);
 }
 }
 
 
 /*
 /*