From: "Andi Kleen" <ak@suse.de>
To: torvalds@osdl.org
Cc: akpm@osdl.org, discuss@x86-64.org, cpufreq@lists.linux.org.uk
Subject: [PATCH] [7/7] x86_64: Move ondemand timer into own work queue
Date: Fri, 05 May 2006 20:33:14 +0200 [thread overview]
Message-ID: <445B9A6A.mailIZ41BYSAC@suse.de> (raw)
Taking the cpu hotplug semaphore in a normal events workqueue
is unsafe because other tasks can wait for any workqueues with
it hold. This results in a deadlock.
Move the DBS timer into its own work queue which is not
affected by other work queue flushes to avoid this.
Cc: venkatesh.pallipadi@intel.com
Cc: cpufreq@lists.linux.org.uk
Signed-off-by: Andi Kleen <ak@suse.de>
---
drivers/cpufreq/cpufreq_ondemand.c | 28 ++++++++++++++++++++--------
1 files changed, 20 insertions(+), 8 deletions(-)
Index: linux/drivers/cpufreq/cpufreq_ondemand.c
===================================================================
--- linux.orig/drivers/cpufreq/cpufreq_ondemand.c
+++ linux/drivers/cpufreq/cpufreq_ondemand.c
@@ -74,6 +74,8 @@ static unsigned int dbs_enable; /* numbe
static DEFINE_MUTEX (dbs_mutex);
static DECLARE_WORK (dbs_work, do_dbs_timer, NULL);
+static struct workqueue_struct *dbs_workq;
+
struct dbs_tuners {
unsigned int sampling_rate;
unsigned int sampling_down_factor;
@@ -364,23 +366,29 @@ static void do_dbs_timer(void *data)
mutex_lock(&dbs_mutex);
for_each_online_cpu(i)
dbs_check_cpu(i);
- schedule_delayed_work(&dbs_work,
- usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
+ queue_delayed_work(dbs_workq, &dbs_work,
+ usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
mutex_unlock(&dbs_mutex);
}
static inline void dbs_timer_init(void)
{
INIT_WORK(&dbs_work, do_dbs_timer, NULL);
- schedule_delayed_work(&dbs_work,
- usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
+ if (!dbs_workq)
+ dbs_workq = create_singlethread_workqueue("ondemand");
+ if (!dbs_workq) {
+ printk(KERN_ERR "ondemand: Cannot initialize kernel thread\n");
+ return;
+ }
+ queue_delayed_work(dbs_workq, &dbs_work,
+ usecs_to_jiffies(dbs_tuners_ins.sampling_rate));
return;
}
static inline void dbs_timer_exit(void)
{
- cancel_delayed_work(&dbs_work);
- return;
+ if (dbs_workq)
+ cancel_rearming_delayed_workqueue(dbs_workq, &dbs_work);
}
static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
@@ -489,8 +497,12 @@ static int __init cpufreq_gov_dbs_init(v
static void __exit cpufreq_gov_dbs_exit(void)
{
- /* Make sure that the scheduled work is indeed not running */
- flush_scheduled_work();
+ /* Make sure that the scheduled work is indeed not running.
+ Assumes the timer has been cancelled first. */
+ if (dbs_workq) {
+ flush_workqueue(dbs_workq);
+ destroy_workqueue(dbs_workq);
+ }
cpufreq_unregister_governor(&cpufreq_gov_dbs);
}
next reply other threads:[~2006-05-05 18:33 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-05-05 18:33 Andi Kleen [this message]
2006-05-05 19:09 ` [PATCH] [7/7] x86_64: Move ondemand timer into own work queue Dave Jones
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=445B9A6A.mailIZ41BYSAC@suse.de \
--to=ak@suse.de \
--cc=akpm@osdl.org \
--cc=cpufreq@lists.linux.org.uk \
--cc=discuss@x86-64.org \
--cc=torvalds@osdl.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.