From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1161415AbbKFMDq (ORCPT ); Fri, 6 Nov 2015 07:03:46 -0500 Received: from mailout2.w1.samsung.com ([210.118.77.12]:40696 "EHLO mailout2.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1161382AbbKFMDm (ORCPT ); Fri, 6 Nov 2015 07:03:42 -0500 X-AuditID: cbfec7f5-f794b6d000001495-e1-563c971ccd7a From: Arseniy Krasnov To: linux@arm.linux.org.uk, mingo@redhat.com, peterz@infradead.org Cc: a.krasnov@samsung.com, v.tyrtov@samsung.com, s.rogachev@samsung.com, linux-kernel@vger.kernel.org, Tarek Dakhran , Sergey Dyasly , Dmitriy Safonov , Ilya Maximets Subject: [PATCH 08/13] hperf_hmp: swap tasks function. Date: Fri, 06 Nov 2015 15:02:42 +0300 Message-id: <1446811367-23783-9-git-send-email-a.krasnov@samsung.com> X-Mailer: git-send-email 1.9.1 In-reply-to: <1446811367-23783-1-git-send-email-a.krasnov@samsung.com> References: <1446811367-23783-1-git-send-email-a.krasnov@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrBLMWRmVeSWpSXmKPExsVy+t/xK7oy023CDN6vUbGY91nQ4tPKp2wW V9p/sltc3jWHzeL2ZV6LSwcWMFkc7z3AZDF5tpTFu63XWC3WPz/FaDF1xg92B26PluYeNo/N K7Q8Dr7bw+Txft9VNo++LasYPT5vkgtgi+KySUnNySxLLdK3S+DKePPrN3PBC4WK4wdPszcw fpHqYuTgkBAwkfgwK7GLkRPIFJO4cG89WxcjF4eQwFJGiR8HN7NDOO1MEq9OzWEFqWIT0JX4 uXELG4gtIuAk0fPsLCOIzSwwmUliw9c0EFtYwEzidvN1sBoWAVWJ5RcmgPXyCrhK/L52mRFi m5zEyWOTweKcAm4SHV232UFsIaCajrPvWCYw8i5gZFjFKJpamlxQnJSea6RXnJhbXJqXrpec n7uJERJ+X3cwLj1mdYhRgINRiYfXYLl1mBBrYllxZe4hRgkOZiURXjlmmzAh3pTEyqrUovz4 otKc1OJDjNIcLErivDN3vQ8REkhPLEnNTk0tSC2CyTJxcEo1MM7p3ZxfVGUr/uGAqTzPZr2D Vnt3aejPNWvXDvt/NKKMV/Bqt9ZvJqdwF6Gi31Ka0vdjLyzJTOC1yzZVKP53QUy9rSo2qann 2hod983Po47uelGW3yg1de/jh8cmJGnpW6w8cPvajA91Pq/2fqwSmqk2L/nvzBkF96RvrVn9 6K/6op6DtwSXn1diKc5INNRiLipOBACi0Gj3OwIAAA== Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 'swap_tasks' performs migration between current CPU and CPU from another cluster. It scans two runqueues looking for tasks using 'druntime' metric. When both tasks are found it pulls task from another cluster, and push task from the current CPU. Signed-off-by: Tarek Dakhran Signed-off-by: Sergey Dyasly Signed-off-by: Dmitriy Safonov Signed-off-by: Arseniy Krasnov Signed-off-by: Ilya Maximets --- kernel/sched/fair.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++ kernel/sched/sched.h | 1 + 2 files changed, 101 insertions(+) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index ff05364..028d329 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -7419,6 +7419,106 @@ static unsigned int try_to_move_task(struct task_struct *migrate_task, return migrate_runnable_task(migrate_task, destination_cpu); } + +/** + * swap_tasks(): swaps two tasks from different HMP domains + * @sd: Current sched domain + * @this_cpu: without NO_HZ same as smp_processor_id(). + * + * Returns weight of migrated tasks. + */ +static unsigned int swap_tasks(struct sched_domain *sd, int this_cpu) +{ + unsigned int ld_moved = 0; + int local_stopper = 0; + int foreign_stopper = 0; + struct rq *local_rq = cpu_rq(this_cpu); + struct rq *foreign_rq = NULL; + struct task_struct *local_task = NULL; + struct task_struct *foreign_task = NULL; + unsigned long local_flags; + + local_irq_save(local_flags); + foreign_rq = get_unfair_rq(sd, this_cpu); + + if (!foreign_rq) { + local_irq_restore(local_flags); + return 0; + } + + double_lock_balance(foreign_rq, local_rq); + + /* rq's waiting for stopper execution, return */ + if (foreign_rq->active_balance) + goto unlock; + + if (local_rq->active_balance) + goto unlock; + + foreign_task = get_migration_candidate(sd, foreign_rq, 0, this_cpu); + + if (!foreign_task) + goto unlock; + + /* Get local task for migration */ + local_task = get_migration_candidate(sd, local_rq, 0, foreign_rq->cpu); + + if (!local_task) { + foreign_task->se.migrate_candidate = 0; + goto unlock; + } + /* First try to push local task */ + ld_moved = try_to_move_task(local_task, foreign_rq->cpu, + &local_stopper); + + /* If failed to move, then return, don't try to move foreign task */ + if (!ld_moved) { + local_task->se.migrate_candidate = 0; + foreign_task->se.migrate_candidate = 0; + goto unlock; + } + + /* + * Migration is possible, but task is running, + * so mark rq to run stopper. + */ + if (local_stopper) { + local_rq->push_cpu = foreign_rq->cpu; + local_rq->migrate_task = local_task; + local_rq->active_balance = 1; + } + + /* Now try to pull task from another cpu */ + ld_moved = try_to_move_task(foreign_task, this_cpu, + &foreign_stopper); + + /* Failed to move foreign_task */ + if (!ld_moved) + foreign_task->se.migrate_candidate = 0; + + /* Migration is possible, mark rq to run stopper */ + if (foreign_stopper) { + foreign_rq->push_cpu = this_cpu; + foreign_rq->migrate_task = foreign_task; + foreign_rq->active_balance = 1; + } + +unlock: + double_rq_unlock(local_rq, foreign_rq); + local_irq_restore(local_flags); + + if (local_stopper) + stop_one_cpu_nowait(local_rq->cpu, + active_load_balance_cpu_stop, local_rq, + &local_rq->active_balance_work); + + if (foreign_stopper) + stop_one_cpu_nowait(foreign_rq->cpu, + active_load_balance_cpu_stop, foreign_rq, + &foreign_rq->active_balance_work); + + return ld_moved; +} #endif /* CONFIG_HPERF_HMP */ /* diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 94828dc..47e9605 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -598,6 +598,7 @@ struct rq { unsigned long nr_uninterruptible; #ifdef CONFIG_HPERF_HMP + struct task_struct *migrate_task; /* task from this rq for migration */ /* shows the amount of accumulated unfairness by tasks of this rq */ long druntime_sum; unsigned int nr_hmp_tasks; -- 1.9.1