linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Arseniy Krasnov <a.krasnov@samsung.com>
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 <t.dakhran@samsung.com>,
	Sergey Dyasly <s.dyasly@samsung.com>,
	Dmitriy Safonov <d.safonov@partner.samsung.com>,
	Ilya Maximets <i.maximets@samsung.com>
Subject: [PATCH 08/13] hperf_hmp: swap tasks function.
Date: Fri, 06 Nov 2015 15:02:42 +0300	[thread overview]
Message-ID: <1446811367-23783-9-git-send-email-a.krasnov@samsung.com> (raw)
In-Reply-To: <1446811367-23783-1-git-send-email-a.krasnov@samsung.com>

	'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 <t.dakhran@samsung.com>
Signed-off-by: Sergey Dyasly <s.dyasly@samsung.com>
Signed-off-by: Dmitriy Safonov <d.safonov@partner.samsung.com>
Signed-off-by: Arseniy Krasnov <a.krasnov@samsung.com>
Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
---
 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


  parent reply	other threads:[~2015-11-06 12:03 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-06 12:02 [PATCH 00/13] High performance balancing logic for big.LITTLE Arseniy Krasnov
2015-11-06 12:02 ` [PATCH 01/13] hperf_hmp: add new config for arm and arm64 Arseniy Krasnov
2015-11-06 12:02 ` [PATCH 02/13] hperf_hmp: introduce hew domain flag Arseniy Krasnov
2015-11-06 12:02 ` [PATCH 03/13] hperf_hmp: add sched domains initialization Arseniy Krasnov
2015-11-06 12:02 ` [PATCH 04/13] hperf_hmp: scheduler initialization routines Arseniy Krasnov
2015-11-06 12:02 ` [PATCH 05/13] hperf_hmp: introduce druntime metric Arseniy Krasnov
2015-11-06 12:02 ` [PATCH 06/13] hperf_hmp: is_hmp_imbalance introduced Arseniy Krasnov
2015-11-06 12:02 ` [PATCH 07/13] hperf_hmp: migration auxiliary functions Arseniy Krasnov
2015-11-06 13:03   ` kbuild test robot
2015-11-06 12:02 ` Arseniy Krasnov [this message]
2015-11-06 12:02 ` [PATCH 09/13] hperf_hmp: one way balancing function Arseniy Krasnov
2015-11-06 12:02 ` [PATCH 10/13] hperf_hmp: idle pull function Arseniy Krasnov
2015-11-06 12:02 ` [PATCH 11/13] hperf_hmp: task CPU selection logic Arseniy Krasnov
2015-11-06 12:29   ` kbuild test robot
2015-11-06 12:02 ` [PATCH 12/13] hperf_hmp: rest of logic Arseniy Krasnov
2015-11-06 12:02 ` [PATCH 13/13] hperf_hmp: cpufreq routines Arseniy Krasnov
2015-11-07  9:52 ` [PATCH 00/13] High performance balancing logic for big.LITTLE Peter Zijlstra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1446811367-23783-9-git-send-email-a.krasnov@samsung.com \
    --to=a.krasnov@samsung.com \
    --cc=d.safonov@partner.samsung.com \
    --cc=i.maximets@samsung.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@arm.linux.org.uk \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=s.dyasly@samsung.com \
    --cc=s.rogachev@samsung.com \
    --cc=t.dakhran@samsung.com \
    --cc=v.tyrtov@samsung.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).