From 4c47f397c0636a7bc8202ce6fa274d37e4de2eb1 Mon Sep 17 00:00:00 2001 From: Steve Muckle Date: Mon, 11 Mar 2013 16:33:42 -0700 Subject: sched: provide per cpu-cgroup option to notify on migrations On systems where CPUs may run asynchronously, task migrations between CPUs running at grossly different speeds can cause problems. This change provides a mechanism to notify a subsystem in the kernel if a task in a particular cgroup migrates to a different CPU. Other subsystems (such as cpufreq) may then register for this notifier to take appropriate action when such a task is migrated. The cgroup attribute to set for this behavior is "notify_on_migrate" . Change-Id: Ie1868249e53ef901b89c837fdc33b0ad0c0a4590 Signed-off-by: Steve Muckle Signed-off-by: W4TCH0UT Conflicts: kernel/sched/core.c kernel/sched/rt.c --- kernel/sched/rt.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'kernel/sched') diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index 692fb1e77..c1b6096fc 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c @@ -2401,6 +2401,7 @@ static int push_rt_task(struct rq *rq) struct task_struct *next_task; struct rq *lowest_rq; int ret = 0; + bool moved = false; if (!rq->rt.overloaded) return 0; @@ -2465,6 +2466,7 @@ retry: deactivate_task(rq, next_task, 0); set_task_cpu(next_task, lowest_rq->cpu); + moved = true; activate_task(lowest_rq, next_task, 0); ret = 1; @@ -2475,6 +2477,11 @@ retry: out: put_task_struct(next_task); + if (moved && task_notify_on_migrate(next_task)) + atomic_notifier_call_chain(&migration_notifier_head, + cpu_of(lowest_rq), + (void *)cpu_of(rq)); + return ret; } @@ -2614,9 +2621,11 @@ static int pull_rt_task(struct rq *this_rq) int ret = 0; #ifndef CONFIG_MT_RT_SCHED int cpu; - struct task_struct *p; + struct task_struct *p = NULL; struct rq *src_rq; #endif + bool moved = false; + int src_cpu = 0; mt_sched_printf(sched_rt_info, "0. pull_rt_task %d %d ", rt_overloaded(this_rq), this_rq->cpu); @@ -2689,6 +2698,10 @@ static int pull_rt_task(struct rq *this_rq) deactivate_task(src_rq, p, 0); set_task_cpu(p, this_cpu); activate_task(this_rq, p, 0); + + moved = true; + src_cpu = cpu_of(src_rq); + /* * We continue with the search, just in * case there's an even higher prio task @@ -2701,6 +2714,11 @@ skip: } #endif + if (moved && task_notify_on_migrate(p)) + atomic_notifier_call_chain(&migration_notifier_head, + this_cpu, + (void *)src_cpu); + return ret; } -- cgit v1.2.3