* [PATCH] net/fec: infinite spin on sirq-net-tx on real-time @ 2012-02-06 9:33 Hector Palacios 2012-02-06 9:56 ` Eric Dumazet 0 siblings, 1 reply; 11+ messages in thread From: Hector Palacios @ 2012-02-06 9:33 UTC (permalink / raw) To: netdev Cc: davem, shawn.guo, jgq516, rostedt, tim.sander, u.kleine-koenig, tglx, Hector Palacios, Zeng Zhaoming, Frank Li If softirqd is a real time task, an inifinite spin is hit if the FEC driver tries to send a packet before the autonegotiation with the PHY has completed. This was seen when booting the platform with DHCP on. The driver sends the DHCP request before the PHY has completed autonegotiation. As a consequence, the driver's dev_hard_start_xmit returns NETDEV_TX_BUSY. NETDEV_TX_BUSY is part of NET_TX_MASK thus the packet is requeued (the skb->next = nskb) in dev_hard_start_xmit(). And the NETDEV_TX_BUSY is passed back to sch_derect_xmit() which calls dev_requeue_skb() which then calls __netif_schedule(q) which will call __netif_reschedule(q) which will then do raise_softirq_irqoff(NET_TX_SOFTIRQ). Thus, as soon as ksoftirq exits this routine, it will restart the process over again. As the fec driver never finished with its negotiations, the process starts over again and we never move forward. Newsgroup reference: linux-rt-users http://www.spinics.net/lists/linux-rt-users/msg07551.html Signed-off-by: Zeng Zhaoming <b32542@freescale.com> Signed-off-by: Frank Li <Frank.Li@freescale.com> Signed-off-by: Hector Palacios <hector.palacios@digi.com> --- drivers/net/ethernet/freescale/fec.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index c136230..3fa7d3b 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -284,6 +284,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) if (!fep->link) { /* Link is down or autonegotiation is in progress. */ + netif_stop_queue(dev); return NETDEV_TX_BUSY; } @@ -530,6 +531,7 @@ fec_stop(struct net_device *ndev) udelay(10); writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); + fep->link = 0; /* We have to keep ENET enabled to have MII interrupt stay working */ if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) @@ -866,6 +868,7 @@ static void fec_enet_adjust_link(struct net_device *ndev) if (phy_dev->link) { if (fep->full_duplex != phy_dev->duplex) { fec_restart(ndev, phy_dev->duplex); + netif_wake_queue(dev); status_change = 1; } } -- 1.7.1 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH] net/fec: infinite spin on sirq-net-tx on real-time 2012-02-06 9:33 [PATCH] net/fec: infinite spin on sirq-net-tx on real-time Hector Palacios @ 2012-02-06 9:56 ` Eric Dumazet 2012-02-06 11:03 ` Hector Palacios 0 siblings, 1 reply; 11+ messages in thread From: Eric Dumazet @ 2012-02-06 9:56 UTC (permalink / raw) To: Hector Palacios Cc: netdev, davem, shawn.guo, jgq516, rostedt, tim.sander, u.kleine-koenig, tglx, Zeng Zhaoming, Frank Li Le lundi 06 février 2012 à 10:33 +0100, Hector Palacios a écrit : > If softirqd is a real time task, an inifinite spin is hit > if the FEC driver tries to send a packet before the autonegotiation > with the PHY has completed. > > This was seen when booting the platform with DHCP on. The driver > sends the DHCP request before the PHY has completed autonegotiation. > As a consequence, the driver's dev_hard_start_xmit returns NETDEV_TX_BUSY. > NETDEV_TX_BUSY is part of NET_TX_MASK thus the packet is requeued (the > skb->next = nskb) in dev_hard_start_xmit(). And the NETDEV_TX_BUSY is > passed back to sch_derect_xmit() which calls dev_requeue_skb() which > then calls __netif_schedule(q) which will call __netif_reschedule(q) > which will then do raise_softirq_irqoff(NET_TX_SOFTIRQ). > > Thus, as soon as ksoftirq exits this routine, it will restart the > process over again. As the fec driver never finished with its > negotiations, the process starts over again and we never move forward. > > Newsgroup reference: linux-rt-users http://www.spinics.net/lists/linux-rt-users/msg07551.html > > Signed-off-by: Zeng Zhaoming <b32542@freescale.com> > Signed-off-by: Frank Li <Frank.Li@freescale.com> > Signed-off-by: Hector Palacios <hector.palacios@digi.com> > --- > drivers/net/ethernet/freescale/fec.c | 3 +++ > 1 files changed, 3 insertions(+), 0 deletions(-) > > diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c > index c136230..3fa7d3b 100644 > --- a/drivers/net/ethernet/freescale/fec.c > +++ b/drivers/net/ethernet/freescale/fec.c > @@ -284,6 +284,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) > > if (!fep->link) { > /* Link is down or autonegotiation is in progress. */ > + netif_stop_queue(dev); This seems odd. IMHO, NETDEV_TX_BUSY should be avoided as much as possible. Its part of the old driver API. If queue was stopped, you would not have to test fep->link at all in fast path, and Qdisc would not have to requeue a packet eventually. > return NETDEV_TX_BUSY; > } > > @@ -530,6 +531,7 @@ fec_stop(struct net_device *ndev) > udelay(10); > writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); > writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); > + fep->link = 0; Why not call netif_stop_queue(dev) here ? > > /* We have to keep ENET enabled to have MII interrupt stay working */ > if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) > @@ -866,6 +868,7 @@ static void fec_enet_adjust_link(struct net_device *ndev) > if (phy_dev->link) { > if (fep->full_duplex != phy_dev->duplex) { > fec_restart(ndev, phy_dev->duplex); > + netif_wake_queue(dev); > status_change = 1; > } > } ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] net/fec: infinite spin on sirq-net-tx on real-time 2012-02-06 9:56 ` Eric Dumazet @ 2012-02-06 11:03 ` Hector Palacios 2012-02-06 12:55 ` Eric Dumazet 2012-02-06 13:25 ` [PATCH] net/fec: infinite spin on sirq-net-tx on real-time Steven Rostedt 0 siblings, 2 replies; 11+ messages in thread From: Hector Palacios @ 2012-02-06 11:03 UTC (permalink / raw) To: Eric Dumazet Cc: netdev@vger.kernel.org, davem@davemloft.net, shawn.guo@linaro.org, jgq516@gmail.com, rostedt@goodmis.org, tim.sander@hbm.com, u.kleine-koenig@pengutronix.de, tglx@linutronix.de, Zeng Zhaoming, Frank Li On 02/06/2012 10:56 AM, Eric Dumazet wrote: > Le lundi 06 février 2012 à 10:33 +0100, Hector Palacios a écrit : >> If softirqd is a real time task, an inifinite spin is hit >> if the FEC driver tries to send a packet before the autonegotiation >> with the PHY has completed. >> >> This was seen when booting the platform with DHCP on. The driver >> sends the DHCP request before the PHY has completed autonegotiation. >> As a consequence, the driver's dev_hard_start_xmit returns NETDEV_TX_BUSY. >> NETDEV_TX_BUSY is part of NET_TX_MASK thus the packet is requeued (the >> skb->next = nskb) in dev_hard_start_xmit(). And the NETDEV_TX_BUSY is >> passed back to sch_derect_xmit() which calls dev_requeue_skb() which >> then calls __netif_schedule(q) which will call __netif_reschedule(q) >> which will then do raise_softirq_irqoff(NET_TX_SOFTIRQ). >> >> Thus, as soon as ksoftirq exits this routine, it will restart the >> process over again. As the fec driver never finished with its >> negotiations, the process starts over again and we never move forward. >> >> Newsgroup reference: linux-rt-users http://www.spinics.net/lists/linux-rt-users/msg07551.html >> >> Signed-off-by: Zeng Zhaoming<b32542@freescale.com> >> Signed-off-by: Frank Li<Frank.Li@freescale.com> >> Signed-off-by: Hector Palacios<hector.palacios@digi.com> >> --- >> drivers/net/ethernet/freescale/fec.c | 3 +++ >> 1 files changed, 3 insertions(+), 0 deletions(-) >> >> diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c >> index c136230..3fa7d3b 100644 >> --- a/drivers/net/ethernet/freescale/fec.c >> +++ b/drivers/net/ethernet/freescale/fec.c >> @@ -284,6 +284,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) >> >> if (!fep->link) { >> /* Link is down or autonegotiation is in progress. */ >> + netif_stop_queue(dev); > > This seems odd. > > IMHO, NETDEV_TX_BUSY should be avoided as much as possible. > > Its part of the old driver API. > > If queue was stopped, you would not have to test fep->link at all in > fast path, and Qdisc would not have to requeue a packet eventually. > >> return NETDEV_TX_BUSY; >> } >> >> @@ -530,6 +531,7 @@ fec_stop(struct net_device *ndev) >> udelay(10); >> writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); >> writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); >> + fep->link = 0; > > > Why not call netif_stop_queue(dev) here ? > >> >> /* We have to keep ENET enabled to have MII interrupt stay working */ >> if (id_entry->driver_data& FEC_QUIRK_ENET_MAC) >> @@ -866,6 +868,7 @@ static void fec_enet_adjust_link(struct net_device *ndev) >> if (phy_dev->link) { >> if (fep->full_duplex != phy_dev->duplex) { >> fec_restart(ndev, phy_dev->duplex); >> + netif_wake_queue(dev); >> status_change = 1; >> } >> } > > I'm no network driver expert so I'll leave it up to others to comment. I just forward ported a patch I came across in Freescale's BSP which solves the problem in mainline and in RT. -- Héctor Palacios ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] net/fec: infinite spin on sirq-net-tx on real-time 2012-02-06 11:03 ` Hector Palacios @ 2012-02-06 12:55 ` Eric Dumazet 2012-02-06 13:43 ` [PATCH]Re: " Tim Sander 2012-02-06 13:44 ` [PATCH] fec: fix tx bounce handling Eric Dumazet 2012-02-06 13:25 ` [PATCH] net/fec: infinite spin on sirq-net-tx on real-time Steven Rostedt 1 sibling, 2 replies; 11+ messages in thread From: Eric Dumazet @ 2012-02-06 12:55 UTC (permalink / raw) To: Hector Palacios Cc: netdev@vger.kernel.org, davem@davemloft.net, shawn.guo@linaro.org, jgq516@gmail.com, rostedt@goodmis.org, tim.sander@hbm.com, u.kleine-koenig@pengutronix.de, tglx@linutronix.de, Zeng Zhaoming, Frank Li, Uwe Kleine-König Le lundi 06 février 2012 à 12:03 +0100, Hector Palacios a écrit : > I'm no network driver expert so I'll leave it up to others to comment. I just forward > ported a patch I came across in Freescale's BSP which solves the problem in mainline > and in RT. I understood you didnt write the patch alone, and my question was addressed to all people involved, not only to you. FEC driver needs some bugfixes, before diverging too much from the state of the art. For example, fec_enet_alloc_buffers() doesnt check for allocation failures : fep->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL); NULL dereferences are then possible later in fec_enet_start_xmit() By the way, I am not even sure kmalloc(2048) has a guarantee on alignement of the result, depending on the slub/slab debugging options. ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH]Re: [PATCH] net/fec: infinite spin on sirq-net-tx on real-time 2012-02-06 12:55 ` Eric Dumazet @ 2012-02-06 13:43 ` Tim Sander 2012-02-06 13:44 ` [PATCH] fec: fix tx bounce handling Eric Dumazet 1 sibling, 0 replies; 11+ messages in thread From: Tim Sander @ 2012-02-06 13:43 UTC (permalink / raw) To: Eric Dumazet Cc: Hector Palacios, netdev, davem, shawn.guo, jgq516, rostedt, u.kleine-koenig, tglx, Zeng Zhaoming, Frank Li Hi I just reworked the driver according to Eric's suggestions. It passes first smoke tests. I don't know how to test the out of memory path. Am Montag, 6. Februar 2012, 13:55:24 schrieb Eric Dumazet: > Le lundi 06 février 2012 à 12:03 +0100, Hector Palacios a écrit : > > I'm no network driver expert so I'll leave it up to others to comment. I > > just forward ported a patch I came across in Freescale's BSP which > > solves the problem in mainline and in RT. > > I understood you didnt write the patch alone, and my question was > addressed to all people involved, not only to you. > > FEC driver needs some bugfixes, before diverging too much from the state > of the art. > > For example, fec_enet_alloc_buffers() doesnt check for allocation > failures : > > fep->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL); > > NULL dereferences are then possible later in fec_enet_start_xmit() > > By the way, I am not even sure kmalloc(2048) has a guarantee on > alignement of the result, depending on the slub/slab debugging options. I have not taken care of the alignment issue mentioned. > If softirqd is a real time task, an inifinite spin is hit > if the FEC driver tries to send a packet before the autonegotiation > with the PHY has completed. > > This was seen when booting the platform with DHCP on. The driver > sends the DHCP request before the PHY has completed autonegotiation. > As a consequence, the driver's dev_hard_start_xmit returns NETDEV_TX_BUSY. > NETDEV_TX_BUSY is part of NET_TX_MASK thus the packet is requeued (the > skb->next = nskb) in dev_hard_start_xmit(). And the NETDEV_TX_BUSY is > passed back to sch_derect_xmit() which calls dev_requeue_skb() which > then calls __netif_schedule(q) which will call __netif_reschedule(q) > which will then do raise_softirq_irqoff(NET_TX_SOFTIRQ). > > Thus, as soon as ksoftirq exits this routine, it will restart the > process over again. As the fec driver never finished with its > negotiations, the process starts over again and we never move forward. > > Newsgroup reference: linux-rt-users http://www.spinics.net/lists/linux-rt-users/msg07551.html Signed-of-by: Tim Sander <tim.sander@hbm.com> diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 885d8ba..f69d95f 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -242,11 +242,6 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) unsigned short status; unsigned long flags; - if (!fep->link) { - /* Link is down or autonegotiation is in progress. */ - return NETDEV_TX_BUSY; - } - spin_lock_irqsave(&fep->hw_lock, flags); /* Fill in a Tx ring entry */ bdp = fep->cur_tx; @@ -470,6 +465,9 @@ fec_stop(struct net_device *ndev) udelay(10); writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); + + netif_stop_queue(ndev); + fep->link = 0; } @@ -787,6 +785,7 @@ static void fec_enet_adjust_link(struct net_device *ndev) if (phy_dev->link) { if (fep->full_duplex != phy_dev->duplex) { fec_restart(ndev, phy_dev->duplex); + netif_wake_queue(ndev); status_change = 1; } } @@ -1118,6 +1117,13 @@ static int fec_enet_alloc_buffers(struct net_device *ndev) bdp = fep->tx_bd_base; for (i = 0; i < TX_RING_SIZE; i++) { fep->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL); + if(!fep->tx_bounce[i]) { + for(j = 0; j < i; j++) { + kfree(fep->tx_bounce[j]); + } + fec_enet_free_buffers(ndev); + return -ENOMEM; + } bdp->cbd_sc = 0; bdp->cbd_bufaddr = 0; Hottinger Baldwin Messtechnik GmbH, Im Tiefen See 45, 64293 Darmstadt, Germany | www.hbm.com Registered as GmbH (German limited liability corporation) in the commercial register at the local court of Darmstadt, HRB 1147 Company domiciled in Darmstadt | CEO: Andreas Huellhorst | Chairman of the board: James Charles Webster Als Gesellschaft mit beschraenkter Haftung eingetragen im Handelsregister des Amtsgerichts Darmstadt unter HRB 1147 Sitz der Gesellschaft: Darmstadt | Geschaeftsfuehrung: Andreas Huellhorst | Aufsichtsratsvorsitzender: James Charles Webster The information in this email is confidential. It is intended solely for the addressee. If you are not the intended recipient, please let me know and delete this email. Die in dieser E-Mail enthaltene Information ist vertraulich und lediglich für den Empfaenger bestimmt. Sollten Sie nicht der eigentliche Empfaenger sein, informieren Sie mich bitte kurz und loeschen diese E-Mail. ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH] fec: fix tx bounce handling 2012-02-06 12:55 ` Eric Dumazet 2012-02-06 13:43 ` [PATCH]Re: " Tim Sander @ 2012-02-06 13:44 ` Eric Dumazet 2012-02-06 16:09 ` Tim Sander 1 sibling, 1 reply; 11+ messages in thread From: Eric Dumazet @ 2012-02-06 13:44 UTC (permalink / raw) To: Hector Palacios Cc: netdev@vger.kernel.org, davem@davemloft.net, shawn.guo@linaro.org, jgq516@gmail.com, rostedt@goodmis.org, tim.sander@hbm.com, u.kleine-koenig@pengutronix.de, tglx@linutronix.de, Zeng Zhaoming, Frank Li fec_enet_alloc_buffers() doesnt check for allocation failures for tx bounce buffers, and assumes kmalloc() returns aligned blocks of memory. This is not always true. Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Cc: Shawn Guo <shawn.guo@linaro.org> --- Compile tested only. drivers/net/ethernet/freescale/fec.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index 7b25e9c..f831d0d 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -319,8 +319,8 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) if (((unsigned long) bufaddr) & FEC_ALIGNMENT) { unsigned int index; index = bdp - fep->tx_bd_base; - memcpy(fep->tx_bounce[index], skb->data, skb->len); - bufaddr = fep->tx_bounce[index]; + bufaddr = PTR_ALIGN(fep->tx_bounce[index], FEC_ALIGNMENT + 1); + memcpy(bufaddr, skb->data, skb->len); } /* @@ -1196,7 +1196,6 @@ static void fec_enet_free_buffers(struct net_device *ndev) bdp++; } - bdp = fep->tx_bd_base; for (i = 0; i < TX_RING_SIZE; i++) kfree(fep->tx_bounce[i]); } @@ -1210,7 +1209,7 @@ static int fec_enet_alloc_buffers(struct net_device *ndev) bdp = fep->rx_bd_base; for (i = 0; i < RX_RING_SIZE; i++) { - skb = dev_alloc_skb(FEC_ENET_RX_FRSIZE); + skb = __dev_alloc_skb(FEC_ENET_RX_FRSIZE, GFP_KERNEL); if (!skb) { fec_enet_free_buffers(ndev); return -ENOMEM; @@ -1230,6 +1229,10 @@ static int fec_enet_alloc_buffers(struct net_device *ndev) bdp = fep->tx_bd_base; for (i = 0; i < TX_RING_SIZE; i++) { fep->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL); + if (!fep->tx_bounce[i]) { + fec_enet_free_buffers(ndev); + return -ENOMEM; + } bdp->cbd_sc = 0; bdp->cbd_bufaddr = 0; ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH] fec: fix tx bounce handling 2012-02-06 13:44 ` [PATCH] fec: fix tx bounce handling Eric Dumazet @ 2012-02-06 16:09 ` Tim Sander 2012-02-06 16:25 ` Eric Dumazet 0 siblings, 1 reply; 11+ messages in thread From: Tim Sander @ 2012-02-06 16:09 UTC (permalink / raw) To: Eric Dumazet Cc: Hector Palacios, netdev, davem, shawn.guo, jgq516, rostedt, u.kleine-koenig, tglx, Zeng Zhaoming, Frank Li Hi I forward ported the patch i have for 3.0-rt (which was working on a quick test) to the net-dev branch with the patch from Eric mixed in. But a quick test revealed that dmesg is full of: eth0: tx queue full!. Not good! Any suggestions on this? Tim Heres my patch for 3.3: diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index 336edd7..74d5865 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -284,11 +284,6 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) unsigned short status; unsigned long flags; - if (!fep->link) { - /* Link is down or autonegotiation is in progress. */ - return NETDEV_TX_BUSY; - } - spin_lock_irqsave(&fep->hw_lock, flags); /* Fill in a Tx ring entry */ bdp = fep->cur_tx; @@ -319,8 +314,8 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) if (((unsigned long) bufaddr) & FEC_ALIGNMENT) { unsigned int index; index = bdp - fep->tx_bd_base; - memcpy(fep->tx_bounce[index], skb->data, skb->len); - bufaddr = fep->tx_bounce[index]; + bufaddr = PTR_ALIGN(fep->tx_bounce[index], FEC_ALIGNMENT + 1); + memcpy(bufaddr, skb->data, skb->len); } /* @@ -542,6 +537,9 @@ fec_stop(struct net_device *ndev) writel(2, fep->hwp + FEC_ECNTRL); writel(rmii_mode, fep->hwp + FEC_R_CNTRL); } + + netif_stop_queue(ndev); + fep->link=0; } @@ -1210,7 +1208,7 @@ static int fec_enet_alloc_buffers(struct net_device *ndev) bdp = fep->rx_bd_base; for (i = 0; i < RX_RING_SIZE; i++) { - skb = dev_alloc_skb(FEC_ENET_RX_FRSIZE); + skb = __dev_alloc_skb(FEC_ENET_RX_FRSIZE, GFP_KERNEL); if (!skb) { fec_enet_free_buffers(ndev); return -ENOMEM; @@ -1230,6 +1228,10 @@ static int fec_enet_alloc_buffers(struct net_device *ndev) bdp = fep->tx_bd_base; for (i = 0; i < TX_RING_SIZE; i++) { fep->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL); + if(!fep->tx_bounce[i]) { + fec_enet_free_buffers(ndev); + return -ENOMEM; + } bdp->cbd_sc = 0; bdp->cbd_bufaddr = 0; Hottinger Baldwin Messtechnik GmbH, Im Tiefen See 45, 64293 Darmstadt, Germany | www.hbm.com Registered as GmbH (German limited liability corporation) in the commercial register at the local court of Darmstadt, HRB 1147 Company domiciled in Darmstadt | CEO: Andreas Huellhorst | Chairman of the board: James Charles Webster Als Gesellschaft mit beschraenkter Haftung eingetragen im Handelsregister des Amtsgerichts Darmstadt unter HRB 1147 Sitz der Gesellschaft: Darmstadt | Geschaeftsfuehrung: Andreas Huellhorst | Aufsichtsratsvorsitzender: James Charles Webster The information in this email is confidential. It is intended solely for the addressee. If you are not the intended recipient, please let me know and delete this email. Die in dieser E-Mail enthaltene Information ist vertraulich und lediglich für den Empfaenger bestimmt. Sollten Sie nicht der eigentliche Empfaenger sein, informieren Sie mich bitte kurz und loeschen diese E-Mail. ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH] fec: fix tx bounce handling 2012-02-06 16:09 ` Tim Sander @ 2012-02-06 16:25 ` Eric Dumazet 0 siblings, 0 replies; 11+ messages in thread From: Eric Dumazet @ 2012-02-06 16:25 UTC (permalink / raw) To: Tim Sander Cc: Hector Palacios, netdev, davem, shawn.guo, jgq516, rostedt, u.kleine-koenig, tglx, Zeng Zhaoming, Frank Li Le lundi 06 février 2012 à 17:09 +0100, Tim Sander a écrit : > Hi > > I forward ported the patch i have for 3.0-rt (which was working on a quick test) > to the net-dev branch with the patch from Eric mixed in. > > But a quick test revealed that dmesg is full of: > eth0: tx queue full!. > Not good! Any suggestions on this? > Please dont mix things. My patch has nothing to do with the TX ring handling. > Tim > > Heres my patch for 3.3: > > diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c > index 336edd7..74d5865 100644 > --- a/drivers/net/ethernet/freescale/fec.c > +++ b/drivers/net/ethernet/freescale/fec.c > @@ -284,11 +284,6 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) > unsigned short status; > unsigned long flags; > > - if (!fep->link) { We first must fix the driver before removing this work around. > - /* Link is down or autonegotiation is in progress. */ > - return NETDEV_TX_BUSY; > - } > - In fact, returning NETDEV_TX_BUSY here is proof driver is buggy. We should not enter fec_enet_start_xmit() is device is not ready to send frames. There are missing netif_stop_queue(dev) in this driver. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] net/fec: infinite spin on sirq-net-tx on real-time 2012-02-06 11:03 ` Hector Palacios 2012-02-06 12:55 ` Eric Dumazet @ 2012-02-06 13:25 ` Steven Rostedt 2012-02-06 13:39 ` Eric Dumazet 1 sibling, 1 reply; 11+ messages in thread From: Steven Rostedt @ 2012-02-06 13:25 UTC (permalink / raw) To: Hector Palacios Cc: Eric Dumazet, netdev@vger.kernel.org, davem@davemloft.net, shawn.guo@linaro.org, jgq516@gmail.com, tim.sander@hbm.com, u.kleine-koenig@pengutronix.de, tglx@linutronix.de, Zeng Zhaoming, Frank Li On Mon, 2012-02-06 at 12:03 +0100, Hector Palacios wrote: > >> > >> @@ -530,6 +531,7 @@ fec_stop(struct net_device *ndev) > >> udelay(10); > >> writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); > >> writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); > >> + fep->link = 0; > > > > > > Why not call netif_stop_queue(dev) here ? > > > I'm no network driver expert so I'll leave it up to others to comment. I just forward > ported a patch I came across in Freescale's BSP which solves the problem in mainline > and in RT. Hector, Eric's suggestion may also work. Could your revert this patch and add the netif_stop_queue(dev) there, and see if it fixes the problems in both mainline and -rt? Thanks! -- Steve ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH] net/fec: infinite spin on sirq-net-tx on real-time 2012-02-06 13:25 ` [PATCH] net/fec: infinite spin on sirq-net-tx on real-time Steven Rostedt @ 2012-02-06 13:39 ` Eric Dumazet 2012-02-07 0:48 ` [PATCH] " Tim Sander 0 siblings, 1 reply; 11+ messages in thread From: Eric Dumazet @ 2012-02-06 13:39 UTC (permalink / raw) To: Steven Rostedt Cc: Hector Palacios, netdev@vger.kernel.org, davem@davemloft.net, shawn.guo@linaro.org, jgq516@gmail.com, tim.sander@hbm.com, u.kleine-koenig@pengutronix.de, tglx@linutronix.de, Zeng Zhaoming, Frank Li Le lundi 06 février 2012 à 08:25 -0500, Steven Rostedt a écrit : > On Mon, 2012-02-06 at 12:03 +0100, Hector Palacios wrote: > > > >> > > >> @@ -530,6 +531,7 @@ fec_stop(struct net_device *ndev) > > >> udelay(10); > > >> writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); > > >> writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); > > >> + fep->link = 0; > > > > > > > > > Why not call netif_stop_queue(dev) here ? > > > > > > I'm no network driver expert so I'll leave it up to others to comment. I just forward > > ported a patch I came across in Freescale's BSP which solves the problem in mainline > > and in RT. > > Hector, > > Eric's suggestion may also work. Could your revert this patch and add > the netif_stop_queue(dev) there, and see if it fixes the problems in > both mainline and -rt? Not sure it will be enough to call netif_stop_queue(dev) in fec_stop() We probably need to start the device with its tx queue stopped, then later when device is really ready wakeup the queue. ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH] Re: [PATCH] net/fec: infinite spin on sirq-net-tx on real-time 2012-02-06 13:39 ` Eric Dumazet @ 2012-02-07 0:48 ` Tim Sander 0 siblings, 0 replies; 11+ messages in thread From: Tim Sander @ 2012-02-07 0:48 UTC (permalink / raw) To: Eric Dumazet Cc: Steven Rostedt, Hector Palacios, netdev@vger.kernel.org, davem@davemloft.net, shawn.guo@linaro.org, jgq516@gmail.com, tim.sander@hbm.com, u.kleine-koenig@pengutronix.de, tglx@linutronix.de, Zeng Zhaoming, Frank Li Hi Am Montag 06 Februar 2012, 14:39:59 schrieb Eric Dumazet: > Le lundi 06 février 2012 à 08:25 -0500, Steven Rostedt a écrit : > > On Mon, 2012-02-06 at 12:03 +0100, Hector Palacios wrote: > > > >> @@ -530,6 +531,7 @@ fec_stop(struct net_device *ndev) > > > >> > > > >> udelay(10); > > > >> writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); > > > >> writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); > > > >> > > > >> + fep->link = 0; > > > > > > > > Why not call netif_stop_queue(dev) here ? > > > > > > I'm no network driver expert so I'll leave it up to others to comment. > > > I just forward ported a patch I came across in Freescale's BSP which > > > solves the problem in mainline and in RT. > > > > Hector, > > > > Eric's suggestion may also work. Could your revert this patch and add > > the netif_stop_queue(dev) there, and see if it fixes the problems in > > both mainline and -rt? > > Not sure it will be enough to call netif_stop_queue(dev) in fec_stop() > > We probably need to start the device with its tx queue stopped, then > later when device is really ready wakeup the queue. I am talking about 3.0-rt33 kernel since this is the one i can test the best. Ok i just found out that removing: if (!fep->link) { /* Link is down or autonegotiation is in progress. */ netif_stop_queue(ndev); return NETDEV_TX_BUSY; } does not seem to work. Also netif_stop_queue seems to be mandantory to get the driver working. If this condition in the hotpath is removed i see the ksoftirq high cpuload problem again. I am not sure if the patch for lines 470 if netif_stop_queue(ndev); is really nessary. I also found an double cleanup in my earlier patch. So heres the next iteration of the fec ksoftirq fix for preempt rt. Tim diff --git a/drivers/net/fec.c b/drivers/net/fec.c index 885d8ba..140cb13 100644 --- a/drivers/net/fec.c +++ b/drivers/net/fec.c @@ -244,6 +244,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) if (!fep->link) { /* Link is down or autonegotiation is in progress. */ + netif_stop_queue(ndev); return NETDEV_TX_BUSY; } @@ -470,6 +471,9 @@ fec_stop(struct net_device *ndev) udelay(10); writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); + + netif_stop_queue(ndev); + fep->link = 0; } @@ -787,6 +791,7 @@ static void fec_enet_adjust_link(struct net_device *ndev) if (phy_dev->link) { if (fep->full_duplex != phy_dev->duplex) { fec_restart(ndev, phy_dev->duplex); + netif_wake_queue(ndev); status_change = 1; } } @@ -1118,6 +1123,10 @@ static int fec_enet_alloc_buffers(struct net_device *ndev) bdp = fep->tx_bd_base; for (i = 0; i < TX_RING_SIZE; i++) { fep->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL); + if(!fep->tx_bounce[i]) { + fec_enet_free_buffers(ndev); + return -ENOMEM; + } bdp->cbd_sc = 0; bdp->cbd_bufaddr = 0; ^ permalink raw reply related [flat|nested] 11+ messages in thread
end of thread, other threads:[~2012-02-07 0:55 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-02-06 9:33 [PATCH] net/fec: infinite spin on sirq-net-tx on real-time Hector Palacios 2012-02-06 9:56 ` Eric Dumazet 2012-02-06 11:03 ` Hector Palacios 2012-02-06 12:55 ` Eric Dumazet 2012-02-06 13:43 ` [PATCH]Re: " Tim Sander 2012-02-06 13:44 ` [PATCH] fec: fix tx bounce handling Eric Dumazet 2012-02-06 16:09 ` Tim Sander 2012-02-06 16:25 ` Eric Dumazet 2012-02-06 13:25 ` [PATCH] net/fec: infinite spin on sirq-net-tx on real-time Steven Rostedt 2012-02-06 13:39 ` Eric Dumazet 2012-02-07 0:48 ` [PATCH] " Tim Sander
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).