From: Greg Kroah-Hartman Date: Tue, 7 Oct 2014 20:02:28 +0000 (-0700) Subject: 3.10-stable patches X-Git-Tag: v3.10.57~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ddd193aa66c99e435e119c0347a3fb284e9686dd;p=thirdparty%2Fkernel%2Fstable-queue.git 3.10-stable patches added patches: cpufreq-serialize-calls-to-__cpufreq_governor.patch --- diff --git a/queue-3.10/cpufreq-serialize-calls-to-__cpufreq_governor.patch b/queue-3.10/cpufreq-serialize-calls-to-__cpufreq_governor.patch new file mode 100644 index 00000000000..2b8be466e36 --- /dev/null +++ b/queue-3.10/cpufreq-serialize-calls-to-__cpufreq_governor.patch @@ -0,0 +1,88 @@ +From 19c763031acb831a5ab9c1a701b7fedda073eb3f Mon Sep 17 00:00:00 2001 +From: Viresh Kumar +Date: Sat, 31 Aug 2013 17:48:23 +0530 +Subject: cpufreq: serialize calls to __cpufreq_governor() + +From: Viresh Kumar + +commit 19c763031acb831a5ab9c1a701b7fedda073eb3f upstream. + +We can't take a big lock around __cpufreq_governor() as this causes +recursive locking for some cases. But calls to this routine must be +serialized for every policy. Otherwise we can see some unpredictable +events. + +For example, consider following scenario: + +__cpufreq_remove_dev() + __cpufreq_governor(policy, CPUFREQ_GOV_STOP); + policy->governor->governor(policy, CPUFREQ_GOV_STOP); + cpufreq_governor_dbs() + case CPUFREQ_GOV_STOP: + mutex_destroy(&cpu_cdbs->timer_mutex) + cpu_cdbs->cur_policy = NULL; + +store() + __cpufreq_set_policy() + __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS); + policy->governor->governor(policy, CPUFREQ_GOV_LIMITS); + case CPUFREQ_GOV_LIMITS: + mutex_lock(&cpu_cdbs->timer_mutex); <-- Warning (destroyed mutex) + if (policy->max < cpu_cdbs->cur_policy->cur) <- cur_policy == NULL + +And so store() will eventually result in a crash if cur_policy is +NULL at this point. + +Introduce an additional variable which would guarantee serialization +here. + +Reported-by: Stephen Boyd +Signed-off-by: Viresh Kumar +Signed-off-by: Rafael J. Wysocki +Cc: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/cpufreq/cpufreq.c | 9 +++++++-- + include/linux/cpufreq.h | 1 + + 2 files changed, 8 insertions(+), 2 deletions(-) + +--- a/drivers/cpufreq/cpufreq.c ++++ b/drivers/cpufreq/cpufreq.c +@@ -1566,12 +1566,14 @@ static int __cpufreq_governor(struct cpu + policy->cpu, event); + + mutex_lock(&cpufreq_governor_lock); +- if ((!policy->governor_enabled && (event == CPUFREQ_GOV_STOP)) || +- (policy->governor_enabled && (event == CPUFREQ_GOV_START))) { ++ if (policy->governor_busy ++ || (!policy->governor_enabled && (event == CPUFREQ_GOV_STOP)) ++ || (policy->governor_enabled && (event == CPUFREQ_GOV_START))) { + mutex_unlock(&cpufreq_governor_lock); + return -EBUSY; + } + ++ policy->governor_busy = true; + if (event == CPUFREQ_GOV_STOP) + policy->governor_enabled = false; + else if (event == CPUFREQ_GOV_START) +@@ -1603,6 +1605,9 @@ static int __cpufreq_governor(struct cpu + if ((event == CPUFREQ_GOV_STOP) && !ret) + module_put(policy->governor->owner); + ++ mutex_lock(&cpufreq_governor_lock); ++ policy->governor_busy = false; ++ mutex_unlock(&cpufreq_governor_lock); + return ret; + } + +--- a/include/linux/cpufreq.h ++++ b/include/linux/cpufreq.h +@@ -108,6 +108,7 @@ struct cpufreq_policy { + struct cpufreq_governor *governor; /* see below */ + void *governor_data; + bool governor_enabled; /* governor start/stop flag */ ++ bool governor_busy; + + struct work_struct update; /* if update_policy() needs to be + * called, but you're in IRQ context */ diff --git a/queue-3.10/series b/queue-3.10/series index 2f3356f36ea..924f628678b 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -9,3 +9,4 @@ md-raid5-disable-discard-by-default-due-to-safety-concerns.patch jiffies-fix-timeval-conversion-to-jiffies.patch drbd-fix-regression-out-of-mem-failed-to-invoke-fence-peer-helper.patch nl80211-clear-skb-cb-before-passing-to-netlink.patch +cpufreq-serialize-calls-to-__cpufreq_governor.patch