diff mbox

speedstep-smi: enable interrupts when waiting

Message ID alpine.LRH.2.02.1502091337090.18363@file01.intranet.prod.int.rdu2.redhat.com (mailing list archive)
State Accepted, archived
Delegated to: Rafael Wysocki
Headers show

Commit Message

Mikulas Patocka Feb. 9, 2015, 6:38 p.m. UTC
On Dell Latitude C600 laptop with Pentium 3 850MHz processor, the
speedstep-smi driver sometimes loads and sometimes doesn't load with
"change to state X failed" message.

The hardware sometimes refuses to change frequency and in this case, we
need to retry later. I found out that we need to enable interrupts while
waiting. When we enable interrupts, the hardware blockage that prevents
frequency transition resolves and the transition is possible. With
disabled interrupts, the blockage doesn't resolve (no matter how long do
we wait). The exact reasons for this hardware behavior are unknown.

This patch enables interrupts in the function speedstep_set_state that can
be called with disabled interrupts. However, this function is called with
disabled interrupts only from speedstep_get_freqs, so it shouldn't cause
any problem.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com
Cc: stable@vger.kernel.org

---
 drivers/cpufreq/speedstep-lib.c |    3 +++
 drivers/cpufreq/speedstep-smi.c |   12 ++++++++++++
 2 files changed, 15 insertions(+)

--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Viresh Kumar Feb. 11, 2015, 3:29 a.m. UTC | #1
On 10 February 2015 at 02:38, Mikulas Patocka <mpatocka@redhat.com> wrote:
> On Dell Latitude C600 laptop with Pentium 3 850MHz processor, the
> speedstep-smi driver sometimes loads and sometimes doesn't load with
> "change to state X failed" message.
>
> The hardware sometimes refuses to change frequency and in this case, we
> need to retry later. I found out that we need to enable interrupts while
> waiting. When we enable interrupts, the hardware blockage that prevents
> frequency transition resolves and the transition is possible. With
> disabled interrupts, the blockage doesn't resolve (no matter how long do
> we wait). The exact reasons for this hardware behavior are unknown.
>
> This patch enables interrupts in the function speedstep_set_state that can
> be called with disabled interrupts. However, this function is called with
> disabled interrupts only from speedstep_get_freqs, so it shouldn't cause
> any problem.
>
> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com
> Cc: stable@vger.kernel.org
>
> ---
>  drivers/cpufreq/speedstep-lib.c |    3 +++
>  drivers/cpufreq/speedstep-smi.c |   12 ++++++++++++
>  2 files changed, 15 insertions(+)

It looks it was reviewed/Acked long time back, what happened
then ?
--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Mikulas Patocka Feb. 11, 2015, 11:01 a.m. UTC | #2
On Wed, 11 Feb 2015, Viresh Kumar wrote:

> On 10 February 2015 at 02:38, Mikulas Patocka <mpatocka@redhat.com> wrote:
> > On Dell Latitude C600 laptop with Pentium 3 850MHz processor, the
> > speedstep-smi driver sometimes loads and sometimes doesn't load with
> > "change to state X failed" message.
> >
> > The hardware sometimes refuses to change frequency and in this case, we
> > need to retry later. I found out that we need to enable interrupts while
> > waiting. When we enable interrupts, the hardware blockage that prevents
> > frequency transition resolves and the transition is possible. With
> > disabled interrupts, the blockage doesn't resolve (no matter how long do
> > we wait). The exact reasons for this hardware behavior are unknown.
> >
> > This patch enables interrupts in the function speedstep_set_state that can
> > be called with disabled interrupts. However, this function is called with
> > disabled interrupts only from speedstep_get_freqs, so it shouldn't cause
> > any problem.
> >
> > Signed-off-by: Mikulas Patocka <mpatocka@redhat.com
> > Cc: stable@vger.kernel.org
> >
> > ---
> >  drivers/cpufreq/speedstep-lib.c |    3 +++
> >  drivers/cpufreq/speedstep-smi.c |   12 ++++++++++++
> >  2 files changed, 15 insertions(+)
> 
> It looks it was reviewed/Acked long time back, what happened
> then ?

I don't know. You acknowledged it, but didn't put it upstream.

Mikulas
--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Rafael J. Wysocki Feb. 11, 2015, 2:18 p.m. UTC | #3
On Wednesday, February 11, 2015 06:01:27 AM Mikulas Patocka wrote:
> 
> On Wed, 11 Feb 2015, Viresh Kumar wrote:
> 
> > On 10 February 2015 at 02:38, Mikulas Patocka <mpatocka@redhat.com> wrote:
> > > On Dell Latitude C600 laptop with Pentium 3 850MHz processor, the
> > > speedstep-smi driver sometimes loads and sometimes doesn't load with
> > > "change to state X failed" message.
> > >
> > > The hardware sometimes refuses to change frequency and in this case, we
> > > need to retry later. I found out that we need to enable interrupts while
> > > waiting. When we enable interrupts, the hardware blockage that prevents
> > > frequency transition resolves and the transition is possible. With
> > > disabled interrupts, the blockage doesn't resolve (no matter how long do
> > > we wait). The exact reasons for this hardware behavior are unknown.
> > >
> > > This patch enables interrupts in the function speedstep_set_state that can
> > > be called with disabled interrupts. However, this function is called with
> > > disabled interrupts only from speedstep_get_freqs, so it shouldn't cause
> > > any problem.
> > >
> > > Signed-off-by: Mikulas Patocka <mpatocka@redhat.com
> > > Cc: stable@vger.kernel.org
> > >
> > > ---
> > >  drivers/cpufreq/speedstep-lib.c |    3 +++
> > >  drivers/cpufreq/speedstep-smi.c |   12 ++++++++++++
> > >  2 files changed, 15 insertions(+)
> > 
> > It looks it was reviewed/Acked long time back, what happened
> > then ?
> 
> I don't know. You acknowledged it, but didn't put it upstream.

That's probably my fault then, because I didn't apply it.

OK, I'll queue it up for the next pull request with an ACK from Viresh.
diff mbox

Patch

Index: linux-3.14-rc1/drivers/cpufreq/speedstep-smi.c
===================================================================
--- linux-3.14-rc1.orig/drivers/cpufreq/speedstep-smi.c	2014-02-03 18:56:44.000000000 +0100
+++ linux-3.14-rc1/drivers/cpufreq/speedstep-smi.c	2014-02-03 19:06:21.000000000 +0100
@@ -156,6 +156,7 @@  static void speedstep_set_state(unsigned
 		return;
 
 	/* Disable IRQs */
+	preempt_disable();
 	local_irq_save(flags);
 
 	command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
@@ -166,9 +167,19 @@  static void speedstep_set_state(unsigned
 
 	do {
 		if (retry) {
+			/*
+			 * We need to enable interrupts, otherwise the blockage
+			 * won't resolve.
+			 *
+			 * We disable preemption so that other processes don't
+			 * run. If other processes were running, they could
+			 * submit more DMA requests, making the blockage worse.
+			 */
 			pr_debug("retry %u, previous result %u, waiting...\n",
 					retry, result);
+			local_irq_enable();
 			mdelay(retry * 50);
+			local_irq_disable();
 		}
 		retry++;
 		__asm__ __volatile__(
@@ -185,6 +196,7 @@  static void speedstep_set_state(unsigned
 
 	/* enable IRQs */
 	local_irq_restore(flags);
+	preempt_enable();
 
 	if (new_state == state)
 		pr_debug("change to %u MHz succeeded after %u tries "
Index: linux-3.14-rc1/drivers/cpufreq/speedstep-lib.c
===================================================================
--- linux-3.14-rc1.orig/drivers/cpufreq/speedstep-lib.c	2014-02-03 18:54:39.000000000 +0100
+++ linux-3.14-rc1/drivers/cpufreq/speedstep-lib.c	2014-02-03 19:06:21.000000000 +0100
@@ -400,6 +400,7 @@  unsigned int speedstep_get_freqs(enum sp
 
 	pr_debug("previous speed is %u\n", prev_speed);
 
+	preempt_disable();
 	local_irq_save(flags);
 
 	/* switch to low state */
@@ -464,6 +465,8 @@  unsigned int speedstep_get_freqs(enum sp
 
 out:
 	local_irq_restore(flags);
+	preempt_enable();
+
 	return ret;
 }
 EXPORT_SYMBOL_GPL(speedstep_get_freqs);