From: Mattia Dongili <malattia@linux.it>
To: CPUFreq Mailing List <cpufreq@lists.linux.org.uk>
Cc: Eric Piel <eric.piel@tremplin-utc.net>,
Dominik Brodowski <linux@dominikbrodowski.net>,
davej@redhat.com
Subject: [PATCH 2/2] Measure transition latency at driver initialization
Date: Wed, 30 Nov 2005 00:58:31 +0100 [thread overview]
Message-ID: <11333087111183-git-send-email-malattia@linux.it> (raw)
In-Reply-To: <11333087112659-git-send-email-malattia@linux.it>
Signed-off-by: Mattia Dongili <malattia@linux.it>
---
arch/i386/kernel/cpu/cpufreq/speedstep-ich.c | 90 +++++++++++++++++++++++---
1 files changed, 78 insertions(+), 12 deletions(-)
applies-to: 802a6f1c8699b27a187d801cf69a599409a6b5a4
1d29940b03826b73b9660abc348b8d2ede587587
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c b/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
index 17b7864..a931849 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-ich.c
@@ -42,6 +42,8 @@ static unsigned int speedstep_processor
static u32 pmbase;
+static int measure_latency;
+
/*
* There are only two frequency states for each processor. Values
* are in kHz for the time being.
@@ -85,23 +87,20 @@ static int speedstep_find_register (void
}
/**
- * speedstep_set_state - set the SpeedStep state
+ * __speedstep_set_state - set the SpeedStep state
* @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
*
* Tries to change the SpeedStep state.
+ * NOTE: it doesn't disable interrupts use speedstep_set_state instead.
*/
-static void speedstep_set_state (unsigned int state)
+static void __speedstep_set_state (unsigned int state)
{
u8 pm2_blk;
u8 value;
- unsigned long flags;
if (state > 0x1)
return;
- /* Disable IRQs */
- local_irq_save(flags);
-
/* read state */
value = inb(pmbase + 0x50);
@@ -128,11 +127,8 @@ static void speedstep_set_state (unsigne
/* check if transition was successful */
value = inb(pmbase + 0x50);
- /* Enable IRQs */
- local_irq_restore(flags);
-
dprintk("read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value);
-
+
if (state == (value & 0x1)) {
dprintk("change to %u MHz succeeded\n", (speedstep_get_processor_frequency(speedstep_processor) / 1000));
} else {
@@ -142,6 +138,68 @@ static void speedstep_set_state (unsigne
return;
}
+/**
+ * speedstep_measure_latency - measure latency usec
+ *
+ * Returns: the detected latency.
+ */
+static long speedstep_measure_latency (void)
+{
+ unsigned long flags;
+ unsigned int cur_speed = 0;
+ int state = 0;
+ struct timeval t1, t2;
+
+ cur_speed = speedstep_get_processor_frequency(speedstep_processor);
+ /* find out in which order we have to switch frequencies
+ * to really switch and measure latency time.
+ */
+ if (speedstep_freqs[SPEEDSTEP_LOW].frequency == cur_speed) {
+ state = SPEEDSTEP_HIGH;
+ } else {
+ state = SPEEDSTEP_LOW;
+ }
+
+ /* Disable IRQs */
+ local_irq_save(flags);
+
+ do_gettimeofday(&t1);
+
+ __speedstep_set_state(state);
+
+ do_gettimeofday(&t2);
+
+ /* restore the previous frequency */
+ __speedstep_set_state(!state);
+
+ /* Enable IRQs */
+ local_irq_restore(flags);
+
+ return (t2.tv_sec - t1.tv_sec) * USEC_PER_SEC +
+ t2.tv_usec - t1.tv_usec;
+}
+
+/**
+ * speedstep_set_state - set the SpeedStep state
+ * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
+ *
+ * Tries to change the SpeedStep state.
+ */
+static void speedstep_set_state (unsigned int state)
+{
+ unsigned long flags;
+
+ /* Disable IRQs */
+ local_irq_save(flags);
+
+ __speedstep_set_state(state);
+
+ /* Enable IRQs */
+ local_irq_restore(flags);
+
+ return;
+}
+
/**
* speedstep_activate - activate SpeedStep control in the chipset
@@ -320,6 +378,7 @@ static int speedstep_cpu_init(struct cpu
{
int result = 0;
unsigned int speed;
+ unsigned int transition_latency = CPUFREQ_ETERNAL;
cpumask_t cpus_allowed;
/* only run on CPU to be set, or on its sibling */
@@ -334,7 +393,7 @@ static int speedstep_cpu_init(struct cpu
result = speedstep_get_freqs(speedstep_processor,
&speedstep_freqs[SPEEDSTEP_LOW].frequency,
&speedstep_freqs[SPEEDSTEP_HIGH].frequency,
- &speedstep_set_state);
+ &__speedstep_set_state);
set_cpus_allowed(current, cpus_allowed);
if (result)
return result;
@@ -348,9 +407,14 @@ static int speedstep_cpu_init(struct cpu
(speed == speedstep_freqs[SPEEDSTEP_LOW].frequency) ? "low" : "high",
(speed / 1000));
+ if (measure_latency) {
+ transition_latency = speedstep_measure_latency() * 1000;
+ dprintk("measured transition latency is %u mS\n", transition_latency);
+ }
+
/* cpuinfo and default policy values */
policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
- policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+ policy->cpuinfo.transition_latency = transition_latency;
policy->cur = speed;
result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs);
@@ -434,6 +498,8 @@ static void __exit speedstep_exit(void)
cpufreq_unregister_driver(&speedstep_driver);
}
+module_param(measure_latency, int, 0444);
+MODULE_PARM_DESC(measure_latency, "Try to measure transition latency.");
MODULE_AUTHOR ("Dave Jones <davej@codemonkey.org.uk>, Dominik Brodowski <linux@brodo.de>");
MODULE_DESCRIPTION ("Speedstep driver for Intel mobile processors on chipsets with ICH-M southbridges.");
---
0.99.9.GIT
next prev parent reply other threads:[~2005-11-29 23:58 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-11-29 23:58 [RFC][PATCH 0/0] measure speedstep-ich transition latency at CPU initialization Mattia Dongili
2005-11-29 23:58 ` [PATCH 1/2] Move PMBASE reading away and do it only once at initialization time Mattia Dongili
2005-11-29 23:58 ` Mattia Dongili [this message]
2005-11-30 11:46 ` [PATCH 2/2] Measure transition latency at driver initialization Eric Piel
2005-11-30 22:30 ` Mattia Dongili
2005-11-30 23:41 ` Eric Piel
2005-12-01 19:31 ` [PATCH 2/2 updated] " Mattia Dongili
2005-12-01 21:05 ` Eric Piel
2005-12-01 23:34 ` Mattia Dongili
2005-12-02 11:37 ` Eric Piel
2005-12-02 13:34 ` Mattia Dongili
2005-12-02 20:59 ` Mattia Dongili
2005-12-02 23:43 ` Eric Piel
2005-12-04 17:00 ` Dominik Brodowski
2005-12-02 4:38 ` Ville Syrjälä
2005-11-30 11:02 ` [PATCH 1/2] Move PMBASE reading away and do it only once at initialization time Eric Piel
2005-11-30 21:00 ` Mattia Dongili
2005-12-04 16:58 ` Dominik Brodowski
-- strict thread matches above, loose matches on Subject: below --
2005-11-30 23:59 [PATCH 2/2] Measure transition latency at driver initialization Pallipadi, Venkatesh
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=11333087111183-git-send-email-malattia@linux.it \
--to=malattia@linux.it \
--cc=cpufreq@lists.linux.org.uk \
--cc=davej@redhat.com \
--cc=eric.piel@tremplin-utc.net \
--cc=linux@dominikbrodowski.net \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox