diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/sched.c | 10 | ||||
-rw-r--r-- | kernel/sched_fair.c | 21 |
2 files changed, 21 insertions, 10 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index ae1a3e936d28..3202462109f5 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -384,8 +384,12 @@ struct cfs_rq { | |||
384 | 384 | ||
385 | struct rb_root tasks_timeline; | 385 | struct rb_root tasks_timeline; |
386 | struct rb_node *rb_leftmost; | 386 | struct rb_node *rb_leftmost; |
387 | struct rb_node *rb_load_balance_curr; | 387 | |
388 | /* 'curr' points to currently running entity on this cfs_rq. | 388 | struct list_head tasks; |
389 | struct list_head *balance_iterator; | ||
390 | |||
391 | /* | ||
392 | * 'curr' points to currently running entity on this cfs_rq. | ||
389 | * It is set to NULL otherwise (i.e when none are currently running). | 393 | * It is set to NULL otherwise (i.e when none are currently running). |
390 | */ | 394 | */ |
391 | struct sched_entity *curr, *next; | 395 | struct sched_entity *curr, *next; |
@@ -2525,6 +2529,7 @@ static void __sched_fork(struct task_struct *p) | |||
2525 | 2529 | ||
2526 | INIT_LIST_HEAD(&p->rt.run_list); | 2530 | INIT_LIST_HEAD(&p->rt.run_list); |
2527 | p->se.on_rq = 0; | 2531 | p->se.on_rq = 0; |
2532 | INIT_LIST_HEAD(&p->se.group_node); | ||
2528 | 2533 | ||
2529 | #ifdef CONFIG_PREEMPT_NOTIFIERS | 2534 | #ifdef CONFIG_PREEMPT_NOTIFIERS |
2530 | INIT_HLIST_HEAD(&p->preempt_notifiers); | 2535 | INIT_HLIST_HEAD(&p->preempt_notifiers); |
@@ -7898,6 +7903,7 @@ int in_sched_functions(unsigned long addr) | |||
7898 | static void init_cfs_rq(struct cfs_rq *cfs_rq, struct rq *rq) | 7903 | static void init_cfs_rq(struct cfs_rq *cfs_rq, struct rq *rq) |
7899 | { | 7904 | { |
7900 | cfs_rq->tasks_timeline = RB_ROOT; | 7905 | cfs_rq->tasks_timeline = RB_ROOT; |
7906 | INIT_LIST_HEAD(&cfs_rq->tasks); | ||
7901 | #ifdef CONFIG_FAIR_GROUP_SCHED | 7907 | #ifdef CONFIG_FAIR_GROUP_SCHED |
7902 | cfs_rq->rq = rq; | 7908 | cfs_rq->rq = rq; |
7903 | #endif | 7909 | #endif |
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 9e301a2bab6f..ed8ce329899b 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c | |||
@@ -533,6 +533,7 @@ account_entity_enqueue(struct cfs_rq *cfs_rq, struct sched_entity *se) | |||
533 | add_cfs_task_weight(cfs_rq, se->load.weight); | 533 | add_cfs_task_weight(cfs_rq, se->load.weight); |
534 | cfs_rq->nr_running++; | 534 | cfs_rq->nr_running++; |
535 | se->on_rq = 1; | 535 | se->on_rq = 1; |
536 | list_add(&se->group_node, &cfs_rq->tasks); | ||
536 | } | 537 | } |
537 | 538 | ||
538 | static void | 539 | static void |
@@ -545,6 +546,7 @@ account_entity_dequeue(struct cfs_rq *cfs_rq, struct sched_entity *se) | |||
545 | add_cfs_task_weight(cfs_rq, -se->load.weight); | 546 | add_cfs_task_weight(cfs_rq, -se->load.weight); |
546 | cfs_rq->nr_running--; | 547 | cfs_rq->nr_running--; |
547 | se->on_rq = 0; | 548 | se->on_rq = 0; |
549 | list_del_init(&se->group_node); | ||
548 | } | 550 | } |
549 | 551 | ||
550 | static void enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se) | 552 | static void enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se) |
@@ -1289,21 +1291,24 @@ static void put_prev_task_fair(struct rq *rq, struct task_struct *prev) | |||
1289 | * the current task: | 1291 | * the current task: |
1290 | */ | 1292 | */ |
1291 | static struct task_struct * | 1293 | static struct task_struct * |
1292 | __load_balance_iterator(struct cfs_rq *cfs_rq, struct rb_node *curr) | 1294 | __load_balance_iterator(struct cfs_rq *cfs_rq, struct list_head *next) |
1293 | { | 1295 | { |
1294 | struct task_struct *p = NULL; | 1296 | struct task_struct *p = NULL; |
1295 | struct sched_entity *se; | 1297 | struct sched_entity *se; |
1296 | 1298 | ||
1297 | if (!curr) | 1299 | if (next == &cfs_rq->tasks) |
1298 | return NULL; | 1300 | return NULL; |
1299 | 1301 | ||
1300 | /* Skip over entities that are not tasks */ | 1302 | /* Skip over entities that are not tasks */ |
1301 | do { | 1303 | do { |
1302 | se = rb_entry(curr, struct sched_entity, run_node); | 1304 | se = list_entry(next, struct sched_entity, group_node); |
1303 | curr = rb_next(curr); | 1305 | next = next->next; |
1304 | } while (curr && !entity_is_task(se)); | 1306 | } while (next != &cfs_rq->tasks && !entity_is_task(se)); |
1305 | 1307 | ||
1306 | cfs_rq->rb_load_balance_curr = curr; | 1308 | if (next == &cfs_rq->tasks) |
1309 | return NULL; | ||
1310 | |||
1311 | cfs_rq->balance_iterator = next; | ||
1307 | 1312 | ||
1308 | if (entity_is_task(se)) | 1313 | if (entity_is_task(se)) |
1309 | p = task_of(se); | 1314 | p = task_of(se); |
@@ -1315,14 +1320,14 @@ static struct task_struct *load_balance_start_fair(void *arg) | |||
1315 | { | 1320 | { |
1316 | struct cfs_rq *cfs_rq = arg; | 1321 | struct cfs_rq *cfs_rq = arg; |
1317 | 1322 | ||
1318 | return __load_balance_iterator(cfs_rq, first_fair(cfs_rq)); | 1323 | return __load_balance_iterator(cfs_rq, cfs_rq->tasks.next); |
1319 | } | 1324 | } |
1320 | 1325 | ||
1321 | static struct task_struct *load_balance_next_fair(void *arg) | 1326 | static struct task_struct *load_balance_next_fair(void *arg) |
1322 | { | 1327 | { |
1323 | struct cfs_rq *cfs_rq = arg; | 1328 | struct cfs_rq *cfs_rq = arg; |
1324 | 1329 | ||
1325 | return __load_balance_iterator(cfs_rq, cfs_rq->rb_load_balance_curr); | 1330 | return __load_balance_iterator(cfs_rq, cfs_rq->balance_iterator); |
1326 | } | 1331 | } |
1327 | 1332 | ||
1328 | static unsigned long | 1333 | static unsigned long |