Re: IDE + CPU Scaling problem on Via EPIA systems

From: Dave Jones
Date: Tue Dec 06 2005 - 12:04:54 EST


On Sun, Dec 04, 2005 at 04:22:03PM +0000, Alan Cox wrote:
> On Llu, 2005-11-28 at 01:32 -0500, Dave Jones wrote:
> > On some variants of the VIA C3, we need to quiesce all DMA operations
> > before we do a speed transition. We currently don't do that.
> > I do have a patch from someone which adds support in the longhaul
> > driver to wait for IDE transactions to stop, but to do it cleanly,
> > we really need some callbacks into the IDE layer.
>
> I was under the impression you could turn the IO/MEM enable on the root
> bridge off momentarily to get the needed DMA pause safely ? Or does it
> abort rather than retry at that point ?

I haven't tried that. Is that a safe thing to do ?
We do now disable mastering on all pci devices around the transition
as mandated in the spec, but that didn't really do much either.

Here's the patch I got from one user, which 'worked'...


Subject: [CPUFREQ] longhaul - avoid ide timeouts when bus mastering is off.

I really don't like this. Really.
Unfortunatly its necessary, otherwise after the transition, we live
for just a few minutes, and then just lockup. In an ideal world,
the pm layer would allow some means of walking the device tree
quiescing DMA. Sadly, we don't live in an ideal world.

I'm open to suggestions on better ways to do this, as I'd rather
not push this to Linus' tree.

>From patch by: Ken Staton <ken_staton@xxxxxxxxxxx>
Signed-off-by: Dave Jones <davej@xxxxxxxxxx>

--- linux-2.6.11/arch/i386/kernel/cpu/cpufreq/longhaul.c~ 2005-05-24 01:51:51.000000000 -0400
+++ linux-2.6.11/arch/i386/kernel/cpu/cpufreq/longhaul.c 2005-05-24 01:52:07.000000000 -0400
@@ -30,6 +30,8 @@
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/pci.h>
+#include <linux/ide.h>
+#include <linux/delay.h>

#include <asm/msr.h>
#include <asm/timex.h>
@@ -91,6 +91,25 @@ static char *print_speed(int speed)
}
#endif

+static void ide_idle(void)
+ {
+ int i;
+ ide_hwif_t *hwif = ide_hwifs;
+ ide_drive_t *drive;
+
+ i = 0;
+ do {
+ drive = &hwif->drives[i];
+ i++;
+ if (strncmp(drive->name,"hd",2) == 0) {
+ while (drive->waiting_for_dma)
+ udelay(10);
+ } else {
+ i = 0;
+ }
+ } while (i != 0);
+}
+

static unsigned int calc_speed(int mult)
{
@@ -146,6 +165,7 @@ static void do_powersaver(union msr_long
longhaul->bits.RevisionKey = 0;

preempt_disable();
+ ide_idle(); /* avoid ide timeouts when bus master off */
local_irq_save(flags);

/*

Whilst it may work fine, and 99.9% of VIA systems are likely IDE, it does
nothing about SCSI, so it's not quite perfect.

That said, even a 99% coverage is better than a 0% coverage we currently have.

It also seems quite racy, as it does nothing to prevent new transactions
from beginning after the drive has become idle.

Dave

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/