summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlav Haugan <ohaugan@codeaurora.org>2016-10-13 10:34:11 -0700
committerOlav Haugan <ohaugan@codeaurora.org>2016-10-18 14:48:14 -0700
commit651e7eb964b24c96efb6ce13159e18bfe6c541b0 (patch)
tree591f11d5a0358cb859f55fe6869df9d46236ccab
parent827d0483007ace97844284be67624f1e06ff54e9 (diff)
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>
-rw-r--r--include/trace/events/sched.h15
-rw-r--r--kernel/sched/core_ctl.c33
-rw-r--r--kernel/sched/core_ctl.h7
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