cpufreq Archive on lore.kernel.org
 help / color / mirror / Atom feed
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

  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