2009-07-01 13:38:45

by Matthieu CASTET

[permalink] [raw]
Subject: sdhci can turn off irq up to 200 ms

Hi,

sdhci code got tasklets (sdhci_tasklet_card and sdhci_tasklet_finish),
that does :
{
spin_lock_irqsave

if (cond) {
sdhci_reset
sdhci_reset
}

spin_unlock_irqrestore
}

The problem is that sdhci_reset [1] does busy pooling on a register up
to a timeout of 100 ms.
That's not low latency friendly.

On our system, we saw that sdhci_reset take 1 ms. That should be because
we enter in mdelay, even if the hardware clears the bit faster.
I wonder why there is an mdelay(1). Using cpu_relax and
time_is_after_jiffies should make sdhci_reset faster.


Matthieu

[1]
static void sdhci_reset(struct sdhci_host *host, u8 mask)
{
unsigned long timeout;
u32 uninitialized_var(ier);
[...]
sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET);

if (mask & SDHCI_RESET_ALL)
host->clock = 0;

/* Wait max 100 ms */
timeout = 100;

/* hw clears the bit when it's done */
while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask) {
if (timeout == 0) {
printk(KERN_ERR "%s: Reset 0x%x never completed.\n",
mmc_hostname(host->mmc), (int)mask);
sdhci_dumpregs(host);
return;
}
timeout--;
mdelay(1);
}
[...]
}


2009-07-09 10:28:25

by Matthieu CASTET

[permalink] [raw]
Subject: Re: sdhci can turn off irq up to 200 ms

Matthieu CASTET a ?crit :
> Hi,
>
> sdhci code got tasklets (sdhci_tasklet_card and sdhci_tasklet_finish),
> that does :
> {
> spin_lock_irqsave
>
> if (cond) {
> sdhci_reset
> sdhci_reset
> }
>
> spin_unlock_irqrestore
> }
>
> The problem is that sdhci_reset [1] does busy pooling on a register up
> to a timeout of 100 ms.
> That's not low latency friendly.
>
> On our system, we saw that sdhci_reset take 1 ms. That should be because
> we enter in mdelay, even if the hardware clears the bit faster.
> I wonder why there is an mdelay(1). Using cpu_relax and
> time_is_after_jiffies should make sdhci_reset faster.
>
In case somebody cares, here a patch that reduce on our hardware
sdhci_reset from 1 ms to 30 us.


Matthieu


Attachments:
sdhci.diff (763.00 B)

2009-09-06 13:25:45

by Pierre Ossman

[permalink] [raw]
Subject: Re: sdhci can turn off irq up to 200 ms

On Thu, 9 Jul 2009 12:28:01 +0200
Matthieu CASTET <[email protected]> wrote:

> Matthieu CASTET a écrit :
> > Hi,
> >
> > sdhci code got tasklets (sdhci_tasklet_card and sdhci_tasklet_finish),
> > that does :
> > {
> > spin_lock_irqsave
> >
> > if (cond) {
> > sdhci_reset
> > sdhci_reset
> > }
> >
> > spin_unlock_irqrestore
> > }
> >
> > The problem is that sdhci_reset [1] does busy pooling on a register up
> > to a timeout of 100 ms.
> > That's not low latency friendly.
> >
> > On our system, we saw that sdhci_reset take 1 ms. That should be because
> > we enter in mdelay, even if the hardware clears the bit faster.
> > I wonder why there is an mdelay(1). Using cpu_relax and
> > time_is_after_jiffies should make sdhci_reset faster.
> >
> In case somebody cares, here a patch that reduce on our hardware
> sdhci_reset from 1 ms to 30 us.
>

I seem to recall having problems with jiffies not updating with those
locks held (or perhaps it was when inside the isr).

What arch have you been testing this on?

Rgds
--
-- Pierre Ossman

WARNING: This correspondence is being monitored by the
Swedish government. Make sure your server uses encryption
for SMTP traffic and consider using PGP for end-to-end
encryption.


Attachments:
signature.asc (198.00 B)

2009-09-07 09:56:13

by Matthieu CASTET

[permalink] [raw]
Subject: Re: sdhci can turn off irq up to 200 ms

Pierre Ossman a écrit :
> On Thu, 9 Jul 2009 12:28:01 +0200
> Matthieu CASTET <[email protected]> wrote:
>
>> Matthieu CASTET a écrit :
>>> Hi,
>>>
>>> sdhci code got tasklets (sdhci_tasklet_card and sdhci_tasklet_finish),
>>> that does :
>>> {
>>> spin_lock_irqsave
>>>
>>> if (cond) {
>>> sdhci_reset
>>> sdhci_reset
>>> }
>>>
>>> spin_unlock_irqrestore
>>> }
>>>
>>> The problem is that sdhci_reset [1] does busy pooling on a register up
>>> to a timeout of 100 ms.
>>> That's not low latency friendly.
>>>
>>> On our system, we saw that sdhci_reset take 1 ms. That should be because
>>> we enter in mdelay, even if the hardware clears the bit faster.
>>> I wonder why there is an mdelay(1). Using cpu_relax and
>>> time_is_after_jiffies should make sdhci_reset faster.
>>>
>> In case somebody cares, here a patch that reduce on our hardware
>> sdhci_reset from 1 ms to 30 us.
>>
>
> I seem to recall having problems with jiffies not updating with those
> locks held (or perhaps it was when inside the isr).
>
> What arch have you been testing this on?
It have been tested on arm.

Matthieu

2009-09-07 17:00:02

by Pierre Ossman

[permalink] [raw]
Subject: Re: sdhci can turn off irq up to 200 ms

On Mon, 7 Sep 2009 11:56:10 +0200
Matthieu CASTET <[email protected]> wrote:

> Pierre Ossman a écrit :
> >
> > I seem to recall having problems with jiffies not updating with those
> > locks held (or perhaps it was when inside the isr).
> >
> > What arch have you been testing this on?
> It have been tested on arm.
>

Things might be different there. I suggest you also try to get it
tested on x86, where this driver sees most of its use.

Rgds
--
-- Pierre Ossman

WARNING: This correspondence is being monitored by the
Swedish government. Make sure your server uses encryption
for SMTP traffic and consider using PGP for end-to-end
encryption.


Attachments:
signature.asc (198.00 B)

2009-09-07 19:47:40

by Daniel J Blueman

[permalink] [raw]
Subject: Re: sdhci can turn off irq up to 200 ms

On Jul 9, 11:30?am, Matthieu CASTET <[email protected]>
wrote:
> Matthieu CASTET a ?crit :
>
> > Hi,
>
> > sdhci code got tasklets (sdhci_tasklet_card and sdhci_tasklet_finish),
> > that does :
> > {
> > spin_lock_irqsave
>
> > if (cond) {
> > sdhci_reset
> > sdhci_reset
> > }
>
> > spin_unlock_irqrestore
> > }
>
> > The problem is that sdhci_reset [1] does busy pooling on a register up
> > to a timeout of 100 ms.
> > That's not low latency friendly.
>
> > On our system, we saw that sdhci_reset take 1 ms. That should be because
> > we enter in mdelay, even if the hardware clears the bit faster.
> > I wonder why there is an mdelay(1). Using cpu_relax and
> > time_is_after_jiffies should make sdhci_reset faster.
>
> In case somebody cares, here a patch that reduce on our hardware
> sdhci_reset from 1 ms to 30 us.

On my Core2Duo, cpu_relax (implementing rep;nop) takes 3.2ns, but a
(synchronous) read over the PCI bus takes 0.5-1us, so it's hard to say
how much benefit the cpu_relax call will give, or am I missing
something?

If the code is reading from a memory location, or perhaps writing to
non-writethrough memory, it's a different story.

Daniel
--
Daniel J Blueman

2009-09-08 08:56:40

by Matthieu CASTET

[permalink] [raw]
Subject: Re: sdhci can turn off irq up to 200 ms

Pierre Ossman a écrit :
> On Mon, 7 Sep 2009 11:56:10 +0200
> Matthieu CASTET <[email protected]> wrote:
>
>> Pierre Ossman a écrit :
>>> I seem to recall having problems with jiffies not updating with those
>>> locks held (or perhaps it was when inside the isr).
>>>
>>> What arch have you been testing this on?
>> It have been tested on arm.
>>
>
> Things might be different there. I suggest you also try to get it
> tested on x86, where this driver sees most of its use.
>
I don't have sdhci device on x86. Can somebody on this list try it ?

Thanks

Matthieu