From 651e7eb964b24c96efb6ce13159e18bfe6c541b0 Mon Sep 17 00:00:00 2001
From: Olav Haugan <ohaugan@codeaurora.org>
Date: Thu, 13 Oct 2016 10:34:11 -0700
Subject: [PATCH 1/2] core_ctl: Add refcounting to boost api

More than one client may call the core_ctl_set_boost api. Add support
for this.
Also add a new trace event that is emitted when this api is called.

Change-Id: Iad0a9fc45f1ce87433995e8e549bfca80e8b9cb2
Signed-off-by: Olav Haugan <ohaugan@codeaurora.org>
---
 include/trace/events/sched.h | 15 +++++++++++++++
 kernel/sched/core_ctl.c      | 33 ++++++++++++++++++++++++++++-----
 kernel/sched/core_ctl.h      |  7 +++++--
 3 files changed, 48 insertions(+), 7 deletions(-)

diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h
index daf69b7df534..080d1a87fefa 100644
--- a/include/trace/events/sched.h
+++ b/include/trace/events/sched.h
@@ -1287,6 +1287,21 @@ TRACE_EVENT(core_ctl_set_busy,
 		  __entry->is_busy)
 );
 
+TRACE_EVENT(core_ctl_set_boost,
+
+	TP_PROTO(u32 refcount, s32 ret),
+	TP_ARGS(refcount, ret),
+	TP_STRUCT__entry(
+		__field(u32, refcount)
+		__field(s32, ret)
+	),
+	TP_fast_assign(
+		__entry->refcount = refcount;
+		__entry->ret = ret;
+	),
+	TP_printk("refcount=%u, ret=%d", __entry->refcount, __entry->ret)
+);
+
 /**
  * sched_isolate - called when cores are isolated/unisolated
  *
diff --git a/kernel/sched/core_ctl.c b/kernel/sched/core_ctl.c
index d81886da7ca2..0db85a4fa9c8 100644
--- a/kernel/sched/core_ctl.c
+++ b/kernel/sched/core_ctl.c
@@ -45,7 +45,7 @@ struct cluster_data {
 	bool nrrun_changed;
 	struct task_struct *core_ctl_thread;
 	unsigned int first_cpu;
-	bool boost;
+	unsigned int boost;
 	struct kobject kobj;
 };
 
@@ -652,17 +652,40 @@ static bool do_check(u64 wallclock)
 	return do_check;
 }
 
-void core_ctl_set_boost(bool boost)
+int core_ctl_set_boost(bool boost)
 {
 	unsigned int index = 0;
 	struct cluster_data *cluster;
+	unsigned long flags;
+	int ret = 0;
+	bool boost_state_changed = false;
 
+	spin_lock_irqsave(&state_lock, flags);
 	for_each_cluster(cluster, index) {
-		if (cluster->is_big_cluster && cluster->boost != boost) {
-			cluster->boost = boost;
-			apply_need(cluster);
+		if (cluster->is_big_cluster) {
+			if (boost) {
+				boost_state_changed = !cluster->boost;
+				++cluster->boost;
+			} else {
+				if (!cluster->boost) {
+					pr_err("Error turning off boost. Boost already turned off\n");
+					ret = -EINVAL;
+				} else {
+					--cluster->boost;
+					boost_state_changed = !cluster->boost;
+				}
+			}
+			break;
 		}
 	}
+	spin_unlock_irqrestore(&state_lock, flags);
+
+	if (boost_state_changed)
+		apply_need(cluster);
+
+	trace_core_ctl_set_boost(cluster->boost, ret);
+
+	return ret;
 }
 
 void core_ctl_check(u64 wallclock)
diff --git a/kernel/sched/core_ctl.h b/kernel/sched/core_ctl.h
index 3b0c12acb9c0..98d7cb3e899b 100644
--- a/kernel/sched/core_ctl.h
+++ b/kernel/sched/core_ctl.h
@@ -16,9 +16,12 @@
 
 #ifdef CONFIG_SCHED_CORE_CTL
 void core_ctl_check(u64 wallclock);
-void core_ctl_set_boost(bool boost);
+int core_ctl_set_boost(bool boost);
 #else
 static inline void core_ctl_check(u64 wallclock) {}
-static inline void core_ctl_set_boost(bool boost) {}
+static inline int core_ctl_set_boost(bool boost)
+{
+	return 0;
+}
 #endif
 #endif

From 76ac2a28035f2c5648fd5fb4babcd94ca1c73b2b Mon Sep 17 00:00:00 2001
From: Olav Haugan <ohaugan@codeaurora.org>
Date: Tue, 18 Oct 2016 18:09:59 -0700
Subject: [PATCH 2/2] sched/core_ctl: Move header file to global location

Move the header file of core control to the standard linux include
directory to allow other entities to include this file.

Change-Id: I2ddb8b3b96063be3c6a6cb6bc333998e007f9de7
Signed-off-by: Olav Haugan <ohaugan@codeaurora.org>
---
 {kernel => include/linux}/sched/core_ctl.h | 0
 kernel/sched/core.c                        | 2 +-
 kernel/sched/hmp.c                         | 2 +-
 3 files changed, 2 insertions(+), 2 deletions(-)
 rename {kernel => include/linux}/sched/core_ctl.h (100%)

diff --git a/kernel/sched/core_ctl.h b/include/linux/sched/core_ctl.h
similarity index 100%
rename from kernel/sched/core_ctl.h
rename to include/linux/sched/core_ctl.h
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 024fb1007c78..5276061a2003 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -75,6 +75,7 @@
 #include <linux/context_tracking.h>
 #include <linux/compiler.h>
 #include <linux/irq.h>
+#include <linux/sched/core_ctl.h>
 
 #include <asm/switch_to.h>
 #include <asm/tlb.h>
@@ -85,7 +86,6 @@
 #endif
 
 #include "sched.h"
-#include "core_ctl.h"
 #include "../workqueue_internal.h"
 #include "../smpboot.h"
 
diff --git a/kernel/sched/hmp.c b/kernel/sched/hmp.c
index 3d5de8ba70a2..c89dda673525 100644
--- a/kernel/sched/hmp.c
+++ b/kernel/sched/hmp.c
@@ -18,9 +18,9 @@
 #include <linux/list_sort.h>
 #include <linux/syscore_ops.h>
 #include <linux/of.h>
+#include <linux/sched/core_ctl.h>
 
 #include "sched.h"
-#include "core_ctl.h"
 
 #include <trace/events/sched.h>