linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* imx6q: high interrupt latencies
@ 2012-09-29 21:58 Gilles Chanteperdrix
  2012-10-08  5:20 ` Shawn Guo
  0 siblings, 1 reply; 2+ messages in thread
From: Gilles Chanteperdrix @ 2012-09-29 21:58 UTC (permalink / raw)
  To: linux-arm-kernel


Hi,

I have been observing high interrupt latencies on imx6q, the problem
seems to be in the FEC driver, function fec_enet_tx. The following line:

        while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) {

can take 100us or more to execute, during which the local timer
interrupt are postponed.

As far as I understand, bdp is a pointer to a "struct bufdesc" shared
with the hardware and its status member is updated by the hardware when
the corresponding ethernet packet transmission is complete.

Adding a call to "mb()" or "outer_sync()" before reading the status
seems to avoid the issue, though I do not know if this is the proper fix.

Some more data. The boot logs say:
CPU: ARMv7 Processor [412fc09a] revision 10 (ARMv7), cr=10c53c7d
CPU identified as i.MX6Q, silicon rev 1.0
l2x0: 16 ways, CACHE_ID 0x410000c7

the kernel is compiled with the following errata enabled:
CONFIG_PL310_ERRATA_588369
CONFIG_PL310_ERRATA_727915
CONFIG_ARM_ERRATA_743622
CONFIG_ARM_ERRATA_751472
CONFIG_ARM_ERRATA_754322
CONFIG_ARM_ERRATA_764369
CONFIG_PL310_ERRATA_769419

Regards.

-- 
                                                                Gilles.

^ permalink raw reply	[flat|nested] 2+ messages in thread

* imx6q: high interrupt latencies
  2012-09-29 21:58 imx6q: high interrupt latencies Gilles Chanteperdrix
@ 2012-10-08  5:20 ` Shawn Guo
  0 siblings, 0 replies; 2+ messages in thread
From: Shawn Guo @ 2012-10-08  5:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Sat, Sep 29, 2012 at 11:58:57PM +0200, Gilles Chanteperdrix wrote:
> 
> Hi,
> 
> I have been observing high interrupt latencies on imx6q, the problem
> seems to be in the FEC driver, function fec_enet_tx. The following line:
> 
>         while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) {
> 
> can take 100us or more to execute, during which the local timer
> interrupt are postponed.
> 
> As far as I understand, bdp is a pointer to a "struct bufdesc" shared
> with the hardware and its status member is updated by the hardware when
> the corresponding ethernet packet transmission is complete.
> 
> Adding a call to "mb()" or "outer_sync()" before reading the status
> seems to avoid the issue, though I do not know if this is the proper fix.
> 
> Some more data. The boot logs say:
> CPU: ARMv7 Processor [412fc09a] revision 10 (ARMv7), cr=10c53c7d
> CPU identified as i.MX6Q, silicon rev 1.0
> l2x0: 16 ways, CACHE_ID 0x410000c7
> 
> the kernel is compiled with the following errata enabled:
> CONFIG_PL310_ERRATA_588369
> CONFIG_PL310_ERRATA_727915
> CONFIG_ARM_ERRATA_743622
> CONFIG_ARM_ERRATA_751472
> CONFIG_ARM_ERRATA_754322
> CONFIG_ARM_ERRATA_764369
> CONFIG_PL310_ERRATA_769419
> 
Are you running mainline kernel?  The boot log and the errata settings
are different from what we have with mainline kernel.

I'm using the following patch to measure the time on with v3.6 kernel,
and seeing the output is mostly 2 ~ 4 us.

diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c
index fffd205..f72955a 100644
--- a/drivers/net/ethernet/freescale/fec.c
+++ b/drivers/net/ethernet/freescale/fec.c
@@ -566,11 +566,13 @@ fec_enet_tx(struct net_device *ndev)
        struct bufdesc *bdp;
        unsigned short status;
        struct  sk_buff *skb;
+       struct timeval time1, time2;

        fep = netdev_priv(ndev);
        spin_lock(&fep->hw_lock);
        bdp = fep->dirty_tx;

+       do_gettimeofday(&time1);
        while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) {
                if (bdp == fep->cur_tx && fep->tx_full == 0)
                        break;
@@ -627,6 +629,8 @@ fec_enet_tx(struct net_device *ndev)
                                netif_wake_queue(ndev);
                }
        }
+       do_gettimeofday(&time2);
+       printk("*** %s: %lu\n", __func__, timeval_to_ns(&time2) - timeval_to_ns(&time1));
        fep->dirty_tx = bdp;
        spin_unlock(&fep->hw_lock);
 }

Shawn

^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2012-10-08  5:20 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-09-29 21:58 imx6q: high interrupt latencies Gilles Chanteperdrix
2012-10-08  5:20 ` Shawn Guo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).