[PATCH] fix off-by-one in __iterator_load_balance

From: David Newall
Date: Wed Mar 11 2009 - 10:49:31 EST


An off-by-one bug in __iterator_load_balance causes it to erroneously
return NULL if the next task on the list is also the last entry in the
list. This patch corrects that fault.
--- sched_fair.c 2009-02-21 09:09:34.000000000 +1030
+++ sched_fair.c.dn 2009-03-12 01:09:46.000000000 +1030
@@ -1439,27 +1439,18 @@
static struct task_struct *
__load_balance_iterator(struct cfs_rq *cfs_rq, struct list_head *next)
{
- struct task_struct *p = NULL;
struct sched_entity *se;
-
- if (next == &cfs_rq->tasks)
- return NULL;
-
- /* Skip over entities that are not tasks */
- do {
+ while (next != &cfs_rq->tasks)
+ {
se = list_entry(next, struct sched_entity, group_node);
next = next->next;
- } while (next != &cfs_rq->tasks && !entity_is_task(se));
-
- if (next == &cfs_rq->tasks)
- return NULL;
-
- cfs_rq->balance_iterator = next;
-
- if (entity_is_task(se))
- p = task_of(se);
-
- return p;
+ if (entity_is_task(se))
+ {
+ cfs_rq->balance_iterator = next;
+ return task_of(se);
+ }
+ }
+ return NULL;
}

static struct task_struct *load_balance_start_fair(void *arg)