summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2017-03-23 09:44:49 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2017-03-23 09:44:48 -0700
commit0a6a4c21ffdb312e39de6933e2f7c8b1b3e77f8f (patch)
tree05a57d353d5e7ed266007b2958da67a306a34cb2
parentce0b78dbf16e78d6726fb24c71b70f617bc6048a (diff)
parent16aa0854d5f7522efa1be565ab166e799031319a (diff)
Merge "ARM: dts: msm: disable core_ctl for SDM630"
-rw-r--r--Documentation/kernel-parameters.txt6
-rw-r--r--arch/arm/boot/dts/qcom/sdm630.dtsi2
-rw-r--r--kernel/sched/core_ctl.c45
3 files changed, 52 insertions, 1 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 45d680644dfe..7d6fef1aa136 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -750,6 +750,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
seconds. Defaults to 10*60 = 10mins. A value of 0
disables the blank timer.
+ core_ctl_disable_cpumask= [SMP]
+ Exempt the CPUs from being managed by core_ctl.
+ core_ctl operates on a cluster basis. So all the
+ CPUs in a given cluster must be specified to disable
+ core_ctl for that cluster.
+
coredump_filter=
[KNL] Change the default value for
/proc/<pid>/coredump_filter.
diff --git a/arch/arm/boot/dts/qcom/sdm630.dtsi b/arch/arm/boot/dts/qcom/sdm630.dtsi
index 35a0709bd874..9626e0548789 100644
--- a/arch/arm/boot/dts/qcom/sdm630.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm630.dtsi
@@ -34,7 +34,7 @@
chosen {
stdout-path = "serial0";
- bootargs = "rcupdate.rcu_expedited=1";
+ bootargs = "rcupdate.rcu_expedited=1 core_ctl_disable_cpumask=0-7";
};
psci {
diff --git a/kernel/sched/core_ctl.c b/kernel/sched/core_ctl.c
index 983159cc0646..1dde338d30f2 100644
--- a/kernel/sched/core_ctl.c
+++ b/kernel/sched/core_ctl.c
@@ -653,6 +653,9 @@ int core_ctl_set_boost(bool boost)
int ret = 0;
bool boost_state_changed = false;
+ if (unlikely(!initialized))
+ return 0;
+
spin_lock_irqsave(&state_lock, flags);
for_each_cluster(cluster, index) {
if (cluster->is_big_cluster) {
@@ -931,6 +934,42 @@ static struct notifier_block __refdata cpu_notifier = {
/* ============================ init code ============================== */
+static cpumask_var_t core_ctl_disable_cpumask;
+static bool core_ctl_disable_cpumask_present;
+
+static int __init core_ctl_disable_setup(char *str)
+{
+ if (!*str)
+ return -EINVAL;
+
+ alloc_bootmem_cpumask_var(&core_ctl_disable_cpumask);
+
+ if (cpulist_parse(str, core_ctl_disable_cpumask) < 0) {
+ free_bootmem_cpumask_var(core_ctl_disable_cpumask);
+ return -EINVAL;
+ }
+
+ core_ctl_disable_cpumask_present = true;
+ pr_info("disable_cpumask=%*pbl\n",
+ cpumask_pr_args(core_ctl_disable_cpumask));
+
+ return 0;
+}
+early_param("core_ctl_disable_cpumask", core_ctl_disable_setup);
+
+static bool should_skip(const struct cpumask *mask)
+{
+ if (!core_ctl_disable_cpumask_present)
+ return false;
+
+ /*
+ * We operate on a cluster basis. Disable the core_ctl for
+ * a cluster, if all of it's cpus are specified in
+ * core_ctl_disable_cpumask
+ */
+ return cpumask_subset(mask, core_ctl_disable_cpumask);
+}
+
static struct cluster_data *find_cluster_by_first_cpu(unsigned int first_cpu)
{
unsigned int i;
@@ -952,6 +991,9 @@ static int cluster_init(const struct cpumask *mask)
unsigned int cpu;
struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 };
+ if (should_skip(mask))
+ return 0;
+
if (find_cluster_by_first_cpu(first_cpu))
return 0;
@@ -1052,6 +1094,9 @@ static int __init core_ctl_init(void)
{
unsigned int cpu;
+ if (should_skip(cpu_possible_mask))
+ return 0;
+
core_ctl_check_interval = (rq_avg_period_ms - RQ_AVG_TOLERANCE)
* NSEC_PER_MSEC;