cpufreq: Fix timer/workqueue corruption due to double queueing
PATCH 1/1 cpufreq: Fix timer/workqueue corruption due to double queueing
When a CPU is hot removed we'll cancel all the delayed work items via gov_cancel_work(). Normally this will just cancel a delayed timer on each CPU that the policy is managing and the work won't run, but if the work is already running the workqueue code will wait for the work to finish before continuing to prevent the work items from re-queuing themselves like they normally do. This scheme will work most of the time, except for the case where the work function determines that it should adjust the delay for all other CPUs that the policy is managing. If this scenario occurs, the canceling CPU will cancel its own work but queue up the other CPUs works to run. For example:
CPU0 CPU1
---- ----
cpu_down()
...
__cpufreq_remove_dev()
cpufreq_governor_dbs()
case CPUFREQ_GOV_STOP:
gov_cancel_work(dbs_data, policy);
cpu0 work is canceled
timer is canceled
cpu1 work is canceled <work runs>
<waits for cpu1> od_dbs_timer()
gov_queue_work(*, *, true);
cpu0 work queued cpu1 work queued cpu2 work queued
...
cpu1 work is canceled
cpu2 work is canceled
...
At the end of the GOV_STOP case cpu0 still has a work queued to run although the code is expecting all of the works to be canceled. __cpufreq_remove_dev() will then proceed to re-initialize all the other CPUs works except for the CPU that is going down. The CPUFREQ_GOV_START case in cpufreq_governor_dbs() will trample over the queued work and debugobjects will spit out a warning:
WARNING: at lib/debugobjects.c:260 debug_print_object+0x94/0xbc() ODEBUG: init active (active state 0) object type: timer_list hint: delayed_work_timer_fn+0x0/0x10 Modules linked in: CPU: 0 PID: 1491 Comm: sh Tainted: G W 3.10.0 #19 [<c010c178>] (unwind_backtrace+0x0/0x11c) from [<c0109dec>] (show_stack+0x10/0x14) [<c0109dec>] (show_stack+0x10/0x14) from [<c01904cc>] (warn_slowpath_common+0x4c/0x6c) [<c01904cc>] (warn_slowpath_common+0x4c/0x6c) from [<c019056c>] (warn_slowpath_fmt+0x2c/0x3c) [<c019056c>] (warn_slowpath_fmt+0x2c/0x3c) from [<c0388a7c>] (debug_print_object+0x94/0xbc) [<c0388a7c>] (debug_print_object+0x94/0xbc) from [<c0388e34>] (__debug_object_init+0x2d0/0x340) [<c0388e34>] (__debug_object_init+0x2d0/0x340) from [<c019e3b0>] (init_timer_key+0x14/0xb0) [<c019e3b0>] (init_timer_key+0x14/0xb0) from [<c0635f78>] (cpufreq_governor_dbs+0x3e8/0x5f8) [<c0635f78>] (cpufreq_governor_dbs+0x3e8/0x5f8) from [<c06325a0>] (__cpufreq_governor+0xdc/0x1a4) [<c06325a0>] (__cpufreq_governor+0xdc/0x1a4) from [<c0633704>] (__cpufreq_remove_dev.isra.10+0x3b4/0x434) [<c0633704>] (__cpufreq_remove_dev.isra.10+0x3b4/0x434) from [<c08989f4>] (cpufreq_cpu_callback+0x60/0x80) [<c08989f4>] (cpufreq_cpu_callback+0x60/0x80) from [<c08a43c0>] (notifier_call_chain+0x38/0x68) [<c08a43c0>] (notifier_call_chain+0x38/0x68) from [<c01938e0>] (__cpu_notify+0x28/0x40) [<c01938e0>] (__cpu_notify+0x28/0x40) from [<c0892ad4>] (_cpu_down+0x7c/0x2c0) [<c0892ad4>] (_cpu_down+0x7c/0x2c0) from [<c0892d3c>] (cpu_down+0x24/0x40) [<c0892d3c>] (cpu_down+0x24/0x40) from [<c0893ea8>] (store_online+0x2c/0x74) [<c0893ea8>] (store_online+0x2c/0x74) from [<c04519d8>] (dev_attr_store+0x18/0x24) [<c04519d8>] (dev_attr_store+0x18/0x24) from [<c02a69d4>] (sysfs_write_file+0x100/0x148) [<c02a69d4>] (sysfs_write_file+0x100/0x148) from [<c0255c18>] (vfs_write+0xcc/0x174) [<c0255c18>] (vfs_write+0xcc/0x174) from [<c0255f70>] (SyS_write+0x38/0x64) [<c0255f70>] (SyS_write+0x38/0x64) from [<c0106120>] (ret_fast_syscall+0x0/0x30)
The simplest fix is to check and see if the governor is being stopped and ignore the all_cpus flag so that only the work that's being canceled has the chance to re-queue itself.
---
This should probably go to stable. I think this all started happening in commit 031299b3be30f3ec (cpufreq: governors: Avoid unnecessary per cpu timer interrupts, 2013-02-27).
drivers/cpufreq/cpufreq_governor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/cpufreq/cpufreq_governor.c +1 -1
@@ -133,7 +133,7 @@ void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy, {int i; -if (!all_cpus) { +if (!all_cpus || !policy->governor_enabled) {__gov_queue_work (smp_processor_id (), dbs_data, delay); }else {for_each_cpu (i, policy->cpus)
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
Viresh Kumar
maintainerdrivers/cpufreq/cpufreq_governor.c void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy, · line 139
Quoted 10 lines · Stephen Boyd
+++
b/drivers/cpufreq/cpufreq_governor.cdrivers/cpufreq/cpufreq_governor.c +1
-1@@ -133,7 +133,7 @@ void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy, {int i; -if (!all_cpus) { +if (!all_cpus || !policy->governor_enabled) {__gov_queue_work (smp_processor_id (), dbs_data, delay); }else {for_each_cpu (i, policy->cpus)
Shouldn't we simply do this instead at the top of this function?
Quoted 2 lines
(quoted diff) +2
-0+ if (!policy->governor_enabled) + return;
PATCH 1/1 cpufreq: Fix timer/workqueue corruption due to double queueing
When a CPU is hot removed we'll cancel all the delayed work items via gov_cancel_work(). Normally this will just cancel a delayed timer on each CPU that the policy is managing and the work won't run, but if the work is already running the workqueue code will wait for the work to finish before continuing to prevent the work items from re-queuing themselves like they normally do. This scheme will work most of the time, except for the case where the work function determines that it should adjust the delay for all other CPUs that the policy is managing. If this scenario occurs, the canceling CPU will cancel its own work but queue up the other CPUs works to run. For example:
CPU0 CPU1
---- ----
cpu_down()
...
__cpufreq_remove_dev()
cpufreq_governor_dbs()
case CPUFREQ_GOV_STOP:
gov_cancel_work(dbs_data, policy);
cpu0 work is canceled
timer is canceled
cpu1 work is canceled <work runs>
<waits for cpu1> od_dbs_timer()
gov_queue_work(*, *, true);
cpu0 work queued cpu1 work queued cpu2 work queued
...
cpu1 work is canceled
cpu2 work is canceled
...
At the end of the GOV_STOP case cpu0 still has a work queued to run although the code is expecting all of the works to be canceled. __cpufreq_remove_dev() will then proceed to re-initialize all the other CPUs works except for the CPU that is going down. The CPUFREQ_GOV_START case in cpufreq_governor_dbs() will trample over the queued work and debugobjects will spit out a warning:
WARNING: at lib/debugobjects.c:260 debug_print_object+0x94/0xbc() ODEBUG: init active (active state 0) object type: timer_list hint: delayed_work_timer_fn+0x0/0x10 Modules linked in: CPU: 0 PID: 1491 Comm: sh Tainted: G W 3.10.0 #19 [<c010c178>] (unwind_backtrace+0x0/0x11c) from [<c0109dec>] (show_stack+0x10/0x14) [<c0109dec>] (show_stack+0x10/0x14) from [<c01904cc>] (warn_slowpath_common+0x4c/0x6c) [<c01904cc>] (warn_slowpath_common+0x4c/0x6c) from [<c019056c>] (warn_slowpath_fmt+0x2c/0x3c) [<c019056c>] (warn_slowpath_fmt+0x2c/0x3c) from [<c0388a7c>] (debug_print_object+0x94/0xbc) [<c0388a7c>] (debug_print_object+0x94/0xbc) from [<c0388e34>] (__debug_object_init+0x2d0/0x340) [<c0388e34>] (__debug_object_init+0x2d0/0x340) from [<c019e3b0>] (init_timer_key+0x14/0xb0) [<c019e3b0>] (init_timer_key+0x14/0xb0) from [<c0635f78>] (cpufreq_governor_dbs+0x3e8/0x5f8) [<c0635f78>] (cpufreq_governor_dbs+0x3e8/0x5f8) from [<c06325a0>] (__cpufreq_governor+0xdc/0x1a4) [<c06325a0>] (__cpufreq_governor+0xdc/0x1a4) from [<c0633704>] (__cpufreq_remove_dev.isra.10+0x3b4/0x434) [<c0633704>] (__cpufreq_remove_dev.isra.10+0x3b4/0x434) from [<c08989f4>] (cpufreq_cpu_callback+0x60/0x80) [<c08989f4>] (cpufreq_cpu_callback+0x60/0x80) from [<c08a43c0>] (notifier_call_chain+0x38/0x68) [<c08a43c0>] (notifier_call_chain+0x38/0x68) from [<c01938e0>] (__cpu_notify+0x28/0x40) [<c01938e0>] (__cpu_notify+0x28/0x40) from [<c0892ad4>] (_cpu_down+0x7c/0x2c0) [<c0892ad4>] (_cpu_down+0x7c/0x2c0) from [<c0892d3c>] (cpu_down+0x24/0x40) [<c0892d3c>] (cpu_down+0x24/0x40) from [<c0893ea8>] (store_online+0x2c/0x74) [<c0893ea8>] (store_online+0x2c/0x74) from [<c04519d8>] (dev_attr_store+0x18/0x24) [<c04519d8>] (dev_attr_store+0x18/0x24) from [<c02a69d4>] (sysfs_write_file+0x100/0x148) [<c02a69d4>] (sysfs_write_file+0x100/0x148) from [<c0255c18>] (vfs_write+0xcc/0x174) [<c0255c18>] (vfs_write+0xcc/0x174) from [<c0255f70>] (SyS_write+0x38/0x64) [<c0255f70>] (SyS_write+0x38/0x64) from [<c0106120>] (ret_fast_syscall+0x0/0x30)
---
Quoted 6 lines · Viresh Kumar
Quoted 5 lines · Stephen Boyd
+++
b/drivers/cpufreq/cpufreq_governor.c(quoted diff) +0
-0@@ -133,7 +133,7 @@ void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy, { int i;
Quoted 10 lines
Review void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy, · line 139
Quoted 5 lines
(quoted diff) +1
-1- if (!all_cpus) { + if (!all_cpus || !policy->governor_enabled) { __gov_queue_work(smp_processor_id(), dbs_data, delay); } else { for_each_cpu(i, policy->cpus)Shouldn't we simply do this instead at the top of this function?
Quoted 2 lines
(quoted diff) +2
-0+ if (!policy->governor_enabled) + return;
Sure that works just as well. Here's a patch.
drivers/cpufreq/cpufreq_governor.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/cpufreq/cpufreq_governor.c +3 -0
@@ -133,6 +133,9 @@ void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy, {int i; +if (!policy->governor_enabled) +return ; +if (!all_cpus) {__gov_queue_work (smp_processor_id (), dbs_data, delay); }else {
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
PATCH 1/1 cpufreq: Don't use smp_processor_id() in preemptible context
Workqueues are preemptible even if works are queued on them with queue_work_on(). Let's just use the policy->cpu argument here instead of using smp_processor_id() to silence the warning.
BUG: using smp_processor_id() in preemptible [00000000] code: kworker/3:2/674 caller is gov_queue_work+0x28/0xb0 CPU: 0 PID: 674 Comm: kworker/3:2 Tainted: G W 3.10.0 #30 Workqueue: events od_dbs_timer [<c010c178>] (unwind_backtrace+0x0/0x11c) from [<c0109dec>] (show_stack+0x10/0x14) [<c0109dec>] (show_stack+0x10/0x14) from [<c03885a4>] (debug_smp_processor_id+0xbc/0xf0) [<c03885a4>] (debug_smp_processor_id+0xbc/0xf0) from [<c0635864>] (gov_queue_work+0x28/0xb0) [<c0635864>] (gov_queue_work+0x28/0xb0) from [<c0635618>] (od_dbs_timer+0x108/0x134) [<c0635618>] (od_dbs_timer+0x108/0x134) from [<c01aa8f8>] (process_one_work+0x25c/0x444) [<c01aa8f8>] (process_one_work+0x25c/0x444) from [<c01aaf88>] (worker_thread+0x200/0x344) [<c01aaf88>] (worker_thread+0x200/0x344) from [<c01b03bc>] (kthread+0xa0/0xb0) [<c01b03bc>] (kthread+0xa0/0xb0) from [<c01061b8>] (ret_from_fork+0x14/0x3c)
---
Also found this one. I'm tracking down a pretty bad hotplug/sysfs race on 3.10. I've applied all the stable patches but I'm seeing this still. I'll start another thread on this
WARNING: at kernel/mutex.c:341 __mutex_lock_slowpath+0x14c/0x410() DEBUG_LOCKS_WARN_ON(l->magic != l) Modules linked in: CPU: 0 PID: 1960 Comm: sh Tainted: G W 3.10.0 #32 [<c010c178>] (unwind_backtrace+0x0/0x11c) from [<c0109dec>] (show_stack+0x10/0x14) [<c0109dec>] (show_stack+0x10/0x14) from [<c01904cc>] (warn_slowpath_common+0x4c/0x6c) [<c01904cc>] (warn_slowpath_common+0x4c/0x6c) from [<c019056c>] (warn_slowpath_fmt+0x2c/0x3c) [<c019056c>] (warn_slowpath_fmt+0x2c/0x3c) from [<c08a0334>] (__mutex_lock_slowpath+0x14c/0x410) [<c08a0334>] (__mutex_lock_slowpath+0x14c/0x410) from [<c08a0618>] (mutex_lock+0x20/0x3c) [<c08a0618>] (mutex_lock+0x20/0x3c) from [<c0636114>] (cpufreq_governor_dbs+0x568/0x5f8) [<c0636114>] (cpufreq_governor_dbs+0x568/0x5f8) from [<c06325b0>] (__cpufreq_governor+0xdc/0x1a4) [<c06325b0>] (__cpufreq_governor+0xdc/0x1a4) from [<c06328f0>] (__cpufreq_set_policy+0x278/0x2c0) [<c06328f0>] (__cpufreq_set_policy+0x278/0x2c0) from [<c0632ea0>] (store_scaling_min_freq+0x80/0x9c) [<c0632ea0>] (store_scaling_min_freq+0x80/0x9c) from [<c0633ae4>] (store+0x58/0x90) [<c0633ae4>] (store+0x58/0x90) from [<c02a69d4>] (sysfs_write_file+0x100/0x148) [<c02a69d4>] (sysfs_write_file+0x100/0x148) from [<c0255c18>] (vfs_write+0xcc/0x174) [<c0255c18>] (vfs_write+0xcc/0x174) from [<c0255f70>] (SyS_write+0x38/0x64) [<c0255f70>] (SyS_write+0x38/0x64) from [<c0106120>] (ret_fast_syscall+0x0/0x30)
drivers/cpufreq/cpufreq_governor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/cpufreq/cpufreq_governor.c +1 -1
@@ -137,7 +137,7 @@ void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy,return ;if (!all_cpus) { -__gov_queue_work (smp_processor_id (), dbs_data, delay); +__gov_queue_work (policy->cpu, dbs_data, delay); }else {for_each_cpu (i, policy->cpus)__gov_queue_work (i, dbs_data, delay);
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
Viresh Kumar
maintainerRe: [PATCH] cpufreq: Don't use smp_processor_id() in preemptible context
drivers/cpufreq/cpufreq_governor.c void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy, · line 140
Quoted 10 lines · Stephen Boyd
drivers/cpufreq/cpufreq_governor.c +1
-1@@ -137,7 +137,7 @@ void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy,return ;if (!all_cpus) { -__gov_queue_work (smp_processor_id (), dbs_data, delay); +__gov_queue_work (policy->cpu, dbs_data, delay);
This is probably wrong.. We wanted to queue work on current cpu and not policy->cpu.. Can you use raw_smp_processor_id()?
Quoted 7 lines
drivers/cpufreq/cpufreq_governor.c +0
-1}else {for_each_cpu (i, policy->cpus)__gov_queue_work (i, dbs_data, delay); --The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
Re: [PATCH] cpufreq: Don't use smp_processor_id() in preemptible context
Quoted 8 lines · Viresh Kumar
Quoted 7 lines · Stephen Boyd
drivers/cpufreq/cpufreq_governor.c +0
-0@@ -137,7 +137,7 @@ void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy,return ;
Quoted 5 lines
drivers/cpufreq/cpufreq_governor.c void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy, · line 140
Quoted 3 lines
drivers/cpufreq/cpufreq_governor.c +1
-1if (!all_cpus) { -__gov_queue_work (smp_processor_id (), dbs_data, delay); +__gov_queue_work (policy->cpu, dbs_data, delay);This is probably wrong.. We wanted to queue work on current cpu and not
policy->cpu.. Can you useraw_smp_processor_id()?
Ah right, for the case where the policy covers more than one cpu. raw_smp_processor_id() would work but it probably also needs a large comment. I'll resend with that.
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
PATCH v2 1/1 cpufreq: Don't use smp_processor_id() in preemptible context
Workqueues are preemptible even if works are queued on them with queue_work_on(). Let's use raw_smp_processor_id() here to silence the warning.
BUG: using smp_processor_id() in preemptible [00000000] code: kworker/3:2/674 caller is gov_queue_work+0x28/0xb0 CPU: 0 PID: 674 Comm: kworker/3:2 Tainted: G W 3.10.0 #30 Workqueue: events od_dbs_timer [<c010c178>] (unwind_backtrace+0x0/0x11c) from [<c0109dec>] (show_stack+0x10/0x14) [<c0109dec>] (show_stack+0x10/0x14) from [<c03885a4>] (debug_smp_processor_id+0xbc/0xf0) [<c03885a4>] (debug_smp_processor_id+0xbc/0xf0) from [<c0635864>] (gov_queue_work+0x28/0xb0) [<c0635864>] (gov_queue_work+0x28/0xb0) from [<c0635618>] (od_dbs_timer+0x108/0x134) [<c0635618>] (od_dbs_timer+0x108/0x134) from [<c01aa8f8>] (process_one_work+0x25c/0x444) [<c01aa8f8>] (process_one_work+0x25c/0x444) from [<c01aaf88>] (worker_thread+0x200/0x344) [<c01aaf88>] (worker_thread+0x200/0x344) from [<c01b03bc>] (kthread+0xa0/0xb0) [<c01b03bc>] (kthread+0xa0/0xb0) from [<c01061b8>] (ret_from_fork+0x14/0x3c)
--- drivers/cpufreq/cpufreq_governor.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/cpufreq/cpufreq_governor.c +8 -1
@@ -137,7 +137,14 @@ void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy,return ;if (!all_cpus) { -__gov_queue_work (smp_processor_id (), dbs_data, delay); +/* +* Use raw_smp_processor_id() to avoid preemptible warnings. +* We know that this is only called with all_cpus == false from +* works that have been queued with *_work_on() functions and +* those works are canceled during CPU_DOWN_PREPARE so they +* can't possibly run on any other CPU. +*/ +__gov_queue_work (raw_smp_processor_id (), dbs_data, delay); }else {for_each_cpu (i, policy->cpus)__gov_queue_work (i, dbs_data, delay);
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
Re: [PATCH v2] cpufreq: Don't use smp_processor_id() in preemptible context
Quoted 17 lines · Stephen Boyd
Workqueues are preemptible even if works are queued on them with
queue_work_on(). Let's useraw_smp_processor_id()here to silence the warning.BUG: using smp_processor_id() in preemptible [00000000] code: kworker/3:2/674 caller is gov_queue_work+0x28/0xb0 CPU: 0 PID: 674 Comm: kworker/3:2 Tainted: G W 3.10.0 #30 Workqueue: events od_dbs_timer [<c010c178>] (unwind_backtrace+0x0/0x11c) from [<c0109dec>] (show_stack+0x10/0x14) [<c0109dec>] (show_stack+0x10/0x14) from [<c03885a4>] (debug_smp_processor_id+0xbc/0xf0) [<c03885a4>] (debug_smp_processor_id+0xbc/0xf0) from [<c0635864>] (gov_queue_work+0x28/0xb0) [<c0635864>] (gov_queue_work+0x28/0xb0) from [<c0635618>] (od_dbs_timer+0x108/0x134) [<c0635618>] (od_dbs_timer+0x108/0x134) from [<c01aa8f8>] (process_one_work+0x25c/0x444) [<c01aa8f8>] (process_one_work+0x25c/0x444) from [<c01aaf88>] (worker_thread+0x200/0x344) [<c01aaf88>] (worker_thread+0x200/0x344) from [<c01b03bc>] (kthread+0xa0/0xb0) [<c01b03bc>] (kthread+0xa0/0xb0) from [<c01061b8>] (ret_from_fork+0x14/0x3c)
Quoted 4 lines
Signed-off-by Stephen Boyd <[email protected]>--- drivers/cpufreq/cpufreq_governor.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
Rafael J. Wysocki
AppliedRe: [PATCH v2] cpufreq: Don't use smp_processor_id() in preemptible context
Quoted 18 lines · Viresh Kumar
Quoted 17 lines · Stephen Boyd
Workqueues are preemptible even if works are queued on them with
queue_work_on(). Let's useraw_smp_processor_id()here to silence the warning.BUG: using smp_processor_id() in preemptible [00000000] code: kworker/3:2/674 caller is gov_queue_work+0x28/0xb0 CPU: 0 PID: 674 Comm: kworker/3:2 Tainted: G W 3.10.0 #30 Workqueue: events od_dbs_timer [<c010c178>] (unwind_backtrace+0x0/0x11c) from [<c0109dec>] (show_stack+0x10/0x14) [<c0109dec>] (show_stack+0x10/0x14) from [<c03885a4>] (debug_smp_processor_id+0xbc/0xf0) [<c03885a4>] (debug_smp_processor_id+0xbc/0xf0) from [<c0635864>] (gov_queue_work+0x28/0xb0) [<c0635864>] (gov_queue_work+0x28/0xb0) from [<c0635618>] (od_dbs_timer+0x108/0x134) [<c0635618>] (od_dbs_timer+0x108/0x134) from [<c01aa8f8>] (process_one_work+0x25c/0x444) [<c01aa8f8>] (process_one_work+0x25c/0x444) from [<c01aaf88>] (worker_thread+0x200/0x344) [<c01aaf88>] (worker_thread+0x200/0x344) from [<c01b03bc>] (kthread+0xa0/0xb0) [<c01b03bc>] (kthread+0xa0/0xb0) from [<c01061b8>] (ret_from_fork+0x14/0x3c)
Quoted 6 lines
Quoted 4 lines
Signed-off-by Stephen Boyd <[email protected]>--- drivers/cpufreq/cpufreq_governor.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)Acked-by Viresh Kumar <[email protected]>
Queued up for 3.12, thanks!
Signature · 2 lines
I speak only for myself. Rafael J. Wysocki, Intel Open Source Technology Center.
Quoted 10 lines · Stephen Boyd
Sure that works just as well. Here's a patch.
drivers/cpufreq/cpufreq_governor.c | 3 +++ 1 file changed, 3 insertions(+)drivers/cpufreq/cpufreq_governor.c +0
-0
drivers/cpufreq/cpufreq_governor.c void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy, · line 141
Quoted 9 lines
drivers/cpufreq/cpufreq_governor.c +3
-0@@ -133,6 +133,9 @@ void gov_queue_work(struct dbs_data *dbs_data, struct cpufreq_policy *policy, {int i; +if (!policy->governor_enabled) +return ; +if (!all_cpus) {__gov_queue_work (smp_processor_id (), dbs_data, delay); }else {