Skip to content

Commit a430d99

Browse files
author
Peter Zijlstra
committed
sched/fair: Fix value reported by hot tasks pulled in /proc/schedstat
In /proc/schedstat, lb_hot_gained reports the number hot tasks pulled during load balance. This value is incremented in can_migrate_task() if the task is migratable and hot. After incrementing the value, load balancer can still decide not to migrate this task leading to wrong accounting. Fix this by incrementing stats when hot tasks are detached. This issue only exists in detach_tasks() where we can decide to not migrate hot task even if it is migratable. However, in detach_one_task(), we migrate it unconditionally. [Swapnil: Handled the case where nr_failed_migrations_hot was not accounted properly and wrote commit log] Fixes: d319808 ("sched: Move up affinity check to mitigate useless redoing overhead") Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Reported-by: "Gautham R. Shenoy" <[email protected]> Not-yet-signed-off-by: Peter Zijlstra <[email protected]> Signed-off-by: Swapnil Sapkal <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent ee8118c commit a430d99

File tree

2 files changed

+14
-4
lines changed

2 files changed

+14
-4
lines changed

include/linux/sched.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -937,6 +937,7 @@ struct task_struct {
937937
unsigned sched_reset_on_fork:1;
938938
unsigned sched_contributes_to_load:1;
939939
unsigned sched_migrated:1;
940+
unsigned sched_task_hot:1;
940941

941942
/* Force alignment to the next boundary: */
942943
unsigned :0;

kernel/sched/fair.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9396,6 +9396,8 @@ int can_migrate_task(struct task_struct *p, struct lb_env *env)
93969396
int tsk_cache_hot;
93979397

93989398
lockdep_assert_rq_held(env->src_rq);
9399+
if (p->sched_task_hot)
9400+
p->sched_task_hot = 0;
93999401

94009402
/*
94019403
* We do not migrate tasks that are:
@@ -9472,10 +9474,8 @@ int can_migrate_task(struct task_struct *p, struct lb_env *env)
94729474

94739475
if (tsk_cache_hot <= 0 ||
94749476
env->sd->nr_balance_failed > env->sd->cache_nice_tries) {
9475-
if (tsk_cache_hot == 1) {
9476-
schedstat_inc(env->sd->lb_hot_gained[env->idle]);
9477-
schedstat_inc(p->stats.nr_forced_migrations);
9478-
}
9477+
if (tsk_cache_hot == 1)
9478+
p->sched_task_hot = 1;
94799479
return 1;
94809480
}
94819481

@@ -9490,6 +9490,12 @@ static void detach_task(struct task_struct *p, struct lb_env *env)
94909490
{
94919491
lockdep_assert_rq_held(env->src_rq);
94929492

9493+
if (p->sched_task_hot) {
9494+
p->sched_task_hot = 0;
9495+
schedstat_inc(env->sd->lb_hot_gained[env->idle]);
9496+
schedstat_inc(p->stats.nr_forced_migrations);
9497+
}
9498+
94939499
deactivate_task(env->src_rq, p, DEQUEUE_NOCLOCK);
94949500
set_task_cpu(p, env->dst_cpu);
94959501
}
@@ -9650,6 +9656,9 @@ static int detach_tasks(struct lb_env *env)
96509656

96519657
continue;
96529658
next:
9659+
if (p->sched_task_hot)
9660+
schedstat_inc(p->stats.nr_failed_migrations_hot);
9661+
96539662
list_move(&p->se.group_node, tasks);
96549663
}
96559664

0 commit comments

Comments
 (0)