* [PATCH 0/3] ucc_geth: Some more fixes
@ 2009-12-24 15:30 Anton Vorontsov
2009-12-24 15:31 ` Anton Vorontsov
` (3 more replies)
0 siblings, 4 replies; 16+ messages in thread
From: Anton Vorontsov @ 2009-12-24 15:30 UTC (permalink / raw)
To: David Miller; +Cc: linuxppc-dev, netdev, Lennart Sorensen
Hi all,
Here are some more fixes and one small enhancement for the ucc_geth
driver.
Thanks,
--
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2
^ permalink raw reply [flat|nested] 16+ messages in thread* [PATCH 1/3] ucc_geth: Fix empty TX queue processing 2009-12-24 15:30 [PATCH 0/3] ucc_geth: Some more fixes Anton Vorontsov @ 2009-12-24 15:31 ` Anton Vorontsov 2009-12-24 15:31 ` Anton Vorontsov ` (2 subsequent siblings) 3 siblings, 0 replies; 16+ messages in thread From: Anton Vorontsov @ 2009-12-24 15:31 UTC (permalink / raw) To: David Miller; +Cc: linuxppc-dev, netdev, Lennart Sorensen Following oops was seen with the ucc_geth driver: Unable to handle kernel paging request for data at address 0x00000058 Faulting instruction address: 0xc024f2fc Oops: Kernel access of bad area, sig: 11 [#1] [...] NIP [c024f2fc] skb_recycle_check+0x14/0x100 LR [e30aa0a4] ucc_geth_poll+0xd8/0x4e0 [ucc_geth_driver] Call Trace: [df857d50] [c000b03c] __ipipe_grab_irq+0x3c/0xa4 (unreliable) [df857d60] [e30aa0a4] ucc_geth_poll+0xd8/0x4e0 [ucc_geth_driver] [df857dd0] [c0258cf8] net_rx_action+0xf8/0x1b8 [df857e10] [c0032a38] __do_softirq+0xb8/0x13c [df857e60] [c00065cc] do_softirq+0xa0/0xac [...] This is because ucc_geth_tx() tries to process an empty queue when queues are logically stopped. Stopping the queues doesn't disable polling, and since nowadays ucc_geth_tx() is actually called from the polling routine, the oops above might pop up. Fix this by removing 'netif_queue_stopped() == 0' check. Reported-by: Lennart Sorensen <lsorense@csclub.uwaterloo.ca> Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> Tested-by: Lennart Sorensen <lsorense@csclub.uwaterloo.ca> Cc: Stable <stable@vger.kernel.org> [2.6.32] --- drivers/net/ucc_geth.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index afaf088..0f8c99e 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3273,7 +3273,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) /* Handle the transmitted buffer and release */ /* the BD to be used with the current frame */ - if ((bd == ugeth->txBd[txQ]) && (netif_queue_stopped(dev) == 0)) + if (bd == ugeth->txBd[txQ]) /* queue empty? */ break; dev->stats.tx_packets++; -- 1.6.3.3 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 1/3] ucc_geth: Fix empty TX queue processing @ 2009-12-24 15:31 ` Anton Vorontsov 0 siblings, 0 replies; 16+ messages in thread From: Anton Vorontsov @ 2009-12-24 15:31 UTC (permalink / raw) To: David Miller; +Cc: Lennart Sorensen, Li Yang, netdev, linuxppc-dev Following oops was seen with the ucc_geth driver: Unable to handle kernel paging request for data at address 0x00000058 Faulting instruction address: 0xc024f2fc Oops: Kernel access of bad area, sig: 11 [#1] [...] NIP [c024f2fc] skb_recycle_check+0x14/0x100 LR [e30aa0a4] ucc_geth_poll+0xd8/0x4e0 [ucc_geth_driver] Call Trace: [df857d50] [c000b03c] __ipipe_grab_irq+0x3c/0xa4 (unreliable) [df857d60] [e30aa0a4] ucc_geth_poll+0xd8/0x4e0 [ucc_geth_driver] [df857dd0] [c0258cf8] net_rx_action+0xf8/0x1b8 [df857e10] [c0032a38] __do_softirq+0xb8/0x13c [df857e60] [c00065cc] do_softirq+0xa0/0xac [...] This is because ucc_geth_tx() tries to process an empty queue when queues are logically stopped. Stopping the queues doesn't disable polling, and since nowadays ucc_geth_tx() is actually called from the polling routine, the oops above might pop up. Fix this by removing 'netif_queue_stopped() == 0' check. Reported-by: Lennart Sorensen <lsorense@csclub.uwaterloo.ca> Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> Tested-by: Lennart Sorensen <lsorense@csclub.uwaterloo.ca> Cc: Stable <stable@vger.kernel.org> [2.6.32] --- drivers/net/ucc_geth.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index afaf088..0f8c99e 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3273,7 +3273,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) /* Handle the transmitted buffer and release */ /* the BD to be used with the current frame */ - if ((bd == ugeth->txBd[txQ]) && (netif_queue_stopped(dev) == 0)) + if (bd == ugeth->txBd[txQ]) /* queue empty? */ break; dev->stats.tx_packets++; -- 1.6.3.3 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 2/3] ucc_geth: Fix netdev watchdog triggering on link changes 2009-12-24 15:30 [PATCH 0/3] ucc_geth: Some more fixes Anton Vorontsov @ 2009-12-24 15:31 ` Anton Vorontsov 2009-12-24 15:31 ` Anton Vorontsov ` (2 subsequent siblings) 3 siblings, 0 replies; 16+ messages in thread From: Anton Vorontsov @ 2009-12-24 15:31 UTC (permalink / raw) To: David Miller; +Cc: linuxppc-dev, netdev, Lennart Sorensen Since commit 864fdf884e82bacbe8ca5e93bd43393a61d2e2b4 ("ucc_geth: Fix hangs after switching from full to half duplex") ucc_geth driver disables the controller during MAC configuration changes. Though, disabling the controller might take quite awhile, and so the netdev watchdog might get upset: NETDEV WATCHDOG: eth2 (ucc_geth): transmit queue 0 timed out ------------[ cut here ]------------ Badness at c02729a8 [verbose debug info unavailable] NIP: c02729a8 LR: c02729a8 CTR: c01b6088 REGS: c0451c40 TRAP: 0700 Not tainted (2.6.32-trunk-8360e) [...] NIP [c02729a8] dev_watchdog+0x280/0x290 LR [c02729a8] dev_watchdog+0x280/0x290 Call Trace: [c0451cf0] [c02729a8] dev_watchdog+0x280/0x290 (unreliable) [c0451d50] [c00377c4] run_timer_softirq+0x164/0x224 [c0451da0] [c0032a38] __do_softirq+0xb8/0x13c [c0451df0] [c00065cc] do_softirq+0xa0/0xac [c0451e00] [c003280c] irq_exit+0x7c/0x9c [c0451e10] [c00640c4] __ipipe_sync_stage+0x248/0x24c [...] This patch fixes the issue by detaching the netdev during the time we change the configuration. Reported-by: Lennart Sorensen <lsorense@csclub.uwaterloo.ca> Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> Tested-by: Lennart Sorensen <lsorense@csclub.uwaterloo.ca> Cc: Stable <stable@vger.kernel.org> [2.6.32] --- drivers/net/ucc_geth.c | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 0f8c99e..7fff4c5 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -1563,7 +1563,10 @@ static int ugeth_disable(struct ucc_geth_private *ugeth, enum comm_dir mode) static void ugeth_quiesce(struct ucc_geth_private *ugeth) { - /* Wait for and prevent any further xmits. */ + /* Prevent any further xmits, plus detach the device. */ + netif_device_detach(ugeth->ndev); + + /* Wait for any current xmits to finish. */ netif_tx_disable(ugeth->ndev); /* Disable the interrupt to avoid NAPI rescheduling. */ @@ -1577,7 +1580,7 @@ static void ugeth_activate(struct ucc_geth_private *ugeth) { napi_enable(&ugeth->napi); enable_irq(ugeth->ug_info->uf_info.irq); - netif_tx_wake_all_queues(ugeth->ndev); + netif_device_attach(ugeth->ndev); } /* Called every time the controller might need to be made -- 1.6.3.3 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 2/3] ucc_geth: Fix netdev watchdog triggering on link changes @ 2009-12-24 15:31 ` Anton Vorontsov 0 siblings, 0 replies; 16+ messages in thread From: Anton Vorontsov @ 2009-12-24 15:31 UTC (permalink / raw) To: David Miller; +Cc: Lennart Sorensen, Li Yang, netdev, linuxppc-dev Since commit 864fdf884e82bacbe8ca5e93bd43393a61d2e2b4 ("ucc_geth: Fix hangs after switching from full to half duplex") ucc_geth driver disables the controller during MAC configuration changes. Though, disabling the controller might take quite awhile, and so the netdev watchdog might get upset: NETDEV WATCHDOG: eth2 (ucc_geth): transmit queue 0 timed out ------------[ cut here ]------------ Badness at c02729a8 [verbose debug info unavailable] NIP: c02729a8 LR: c02729a8 CTR: c01b6088 REGS: c0451c40 TRAP: 0700 Not tainted (2.6.32-trunk-8360e) [...] NIP [c02729a8] dev_watchdog+0x280/0x290 LR [c02729a8] dev_watchdog+0x280/0x290 Call Trace: [c0451cf0] [c02729a8] dev_watchdog+0x280/0x290 (unreliable) [c0451d50] [c00377c4] run_timer_softirq+0x164/0x224 [c0451da0] [c0032a38] __do_softirq+0xb8/0x13c [c0451df0] [c00065cc] do_softirq+0xa0/0xac [c0451e00] [c003280c] irq_exit+0x7c/0x9c [c0451e10] [c00640c4] __ipipe_sync_stage+0x248/0x24c [...] This patch fixes the issue by detaching the netdev during the time we change the configuration. Reported-by: Lennart Sorensen <lsorense@csclub.uwaterloo.ca> Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> Tested-by: Lennart Sorensen <lsorense@csclub.uwaterloo.ca> Cc: Stable <stable@vger.kernel.org> [2.6.32] --- drivers/net/ucc_geth.c | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 0f8c99e..7fff4c5 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -1563,7 +1563,10 @@ static int ugeth_disable(struct ucc_geth_private *ugeth, enum comm_dir mode) static void ugeth_quiesce(struct ucc_geth_private *ugeth) { - /* Wait for and prevent any further xmits. */ + /* Prevent any further xmits, plus detach the device. */ + netif_device_detach(ugeth->ndev); + + /* Wait for any current xmits to finish. */ netif_tx_disable(ugeth->ndev); /* Disable the interrupt to avoid NAPI rescheduling. */ @@ -1577,7 +1580,7 @@ static void ugeth_activate(struct ucc_geth_private *ugeth) { napi_enable(&ugeth->napi); enable_irq(ugeth->ug_info->uf_info.irq); - netif_tx_wake_all_queues(ugeth->ndev); + netif_device_attach(ugeth->ndev); } /* Called every time the controller might need to be made -- 1.6.3.3 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 3/3] ucc_geth: Don't needlessly change MAC settings in adjust_link() 2009-12-24 15:30 [PATCH 0/3] ucc_geth: Some more fixes Anton Vorontsov @ 2009-12-24 15:31 ` Anton Vorontsov 2009-12-24 15:31 ` Anton Vorontsov ` (2 subsequent siblings) 3 siblings, 0 replies; 16+ messages in thread From: Anton Vorontsov @ 2009-12-24 15:31 UTC (permalink / raw) To: David Miller; +Cc: linuxppc-dev, netdev, Lennart Sorensen If PHY doesn't have an IRQ, phylib would poll for link changes, and would call adjust_link() every second. In that case we disable and enable the controller every second. Let's better check if there is actually anything changed, and, if so, change the MAC settings. Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> --- drivers/net/ucc_geth.c | 33 ++++++++++++++++++--------------- 1 files changed, 18 insertions(+), 15 deletions(-) diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 7fff4c5..41ad2f3 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -1651,25 +1651,28 @@ static void adjust_link(struct net_device *dev) ugeth->oldspeed = phydev->speed; } - /* - * To change the MAC configuration we need to disable the - * controller. To do so, we have to either grab ugeth->lock, - * which is a bad idea since 'graceful stop' commands might - * take quite a while, or we can quiesce driver's activity. - */ - ugeth_quiesce(ugeth); - ugeth_disable(ugeth, COMM_DIR_RX_AND_TX); - - out_be32(&ug_regs->maccfg2, tempval); - out_be32(&uf_regs->upsmr, upsmr); - - ugeth_enable(ugeth, COMM_DIR_RX_AND_TX); - ugeth_activate(ugeth); - if (!ugeth->oldlink) { new_state = 1; ugeth->oldlink = 1; } + + if (new_state) { + /* + * To change the MAC configuration we need to disable + * the controller. To do so, we have to either grab + * ugeth->lock, which is a bad idea since 'graceful + * stop' commands might take quite a while, or we can + * quiesce driver's activity. + */ + ugeth_quiesce(ugeth); + ugeth_disable(ugeth, COMM_DIR_RX_AND_TX); + + out_be32(&ug_regs->maccfg2, tempval); + out_be32(&uf_regs->upsmr, upsmr); + + ugeth_enable(ugeth, COMM_DIR_RX_AND_TX); + ugeth_activate(ugeth); + } } else if (ugeth->oldlink) { new_state = 1; ugeth->oldlink = 0; -- 1.6.3.3 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 3/3] ucc_geth: Don't needlessly change MAC settings in adjust_link() @ 2009-12-24 15:31 ` Anton Vorontsov 0 siblings, 0 replies; 16+ messages in thread From: Anton Vorontsov @ 2009-12-24 15:31 UTC (permalink / raw) To: David Miller; +Cc: Lennart Sorensen, Li Yang, netdev, linuxppc-dev If PHY doesn't have an IRQ, phylib would poll for link changes, and would call adjust_link() every second. In that case we disable and enable the controller every second. Let's better check if there is actually anything changed, and, if so, change the MAC settings. Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> --- drivers/net/ucc_geth.c | 33 ++++++++++++++++++--------------- 1 files changed, 18 insertions(+), 15 deletions(-) diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 7fff4c5..41ad2f3 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -1651,25 +1651,28 @@ static void adjust_link(struct net_device *dev) ugeth->oldspeed = phydev->speed; } - /* - * To change the MAC configuration we need to disable the - * controller. To do so, we have to either grab ugeth->lock, - * which is a bad idea since 'graceful stop' commands might - * take quite a while, or we can quiesce driver's activity. - */ - ugeth_quiesce(ugeth); - ugeth_disable(ugeth, COMM_DIR_RX_AND_TX); - - out_be32(&ug_regs->maccfg2, tempval); - out_be32(&uf_regs->upsmr, upsmr); - - ugeth_enable(ugeth, COMM_DIR_RX_AND_TX); - ugeth_activate(ugeth); - if (!ugeth->oldlink) { new_state = 1; ugeth->oldlink = 1; } + + if (new_state) { + /* + * To change the MAC configuration we need to disable + * the controller. To do so, we have to either grab + * ugeth->lock, which is a bad idea since 'graceful + * stop' commands might take quite a while, or we can + * quiesce driver's activity. + */ + ugeth_quiesce(ugeth); + ugeth_disable(ugeth, COMM_DIR_RX_AND_TX); + + out_be32(&ug_regs->maccfg2, tempval); + out_be32(&uf_regs->upsmr, upsmr); + + ugeth_enable(ugeth, COMM_DIR_RX_AND_TX); + ugeth_activate(ugeth); + } } else if (ugeth->oldlink) { new_state = 1; ugeth->oldlink = 0; -- 1.6.3.3 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH 0/3] ucc_geth: Some more fixes 2009-12-24 15:30 [PATCH 0/3] ucc_geth: Some more fixes Anton Vorontsov @ 2009-12-27 4:25 ` David Miller 2009-12-24 15:31 ` Anton Vorontsov ` (2 subsequent siblings) 3 siblings, 0 replies; 16+ messages in thread From: David Miller @ 2009-12-27 4:25 UTC (permalink / raw) To: avorontsov; +Cc: linuxppc-dev, netdev, lsorense From: Anton Vorontsov <avorontsov@ru.mvista.com> Date: Thu, 24 Dec 2009 18:30:34 +0300 > Here are some more fixes and one small enhancement for the ucc_geth > driver. All 3 patches applied, thanks a lot! ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 0/3] ucc_geth: Some more fixes @ 2009-12-27 4:25 ` David Miller 0 siblings, 0 replies; 16+ messages in thread From: David Miller @ 2009-12-27 4:25 UTC (permalink / raw) To: avorontsov; +Cc: lsorense, leoli, netdev, linuxppc-dev From: Anton Vorontsov <avorontsov@ru.mvista.com> Date: Thu, 24 Dec 2009 18:30:34 +0300 > Here are some more fixes and one small enhancement for the ucc_geth > driver. All 3 patches applied, thanks a lot! ^ permalink raw reply [flat|nested] 16+ messages in thread
[parent not found: <0A1FE637C2C7E148B9573BB60CC630E56C3E90@zch01exm26.fsl.freescale.net>]
* RE: [PATCH 1/3] ucc_geth: Fix empty TX queue processing [not found] <0A1FE637C2C7E148B9573BB60CC630E56C3E90@zch01exm26.fsl.freescale.net> @ 2010-01-11 3:47 ` Wu Jiajun-B06378 0 siblings, 0 replies; 16+ messages in thread From: Wu Jiajun-B06378 @ 2010-01-11 3:47 UTC (permalink / raw) To: avorontsov; +Cc: linuxppc-dev, lsorense, davem, netdev =20 'bd =3D=3D ugeth->txBd[txQ]' has two possible statuses: 1)full queue. 2)empty queue. Removing 'netif_queue_stopped() =3D=3D 0' will make transmitting = stopping when the queue is full.=20 I made a new patch for this oops. >From 726765194352d01dc8ea672d97612589b67cec3f Mon Sep 17 00:00:00 2001 From: Jiajun Wu <b06378@freescale.com> Date: Mon, 11 Jan 2010 10:57:22 +0800 Subject: [PATCH] ucc_geth: Fix empty TX queue processing Signed-off-by: Jiajun Wu <b06378@freescale.com> --- drivers/net/ucc_geth.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index f982220..34345f0 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3576,17 +3576,17 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) while ((bd_status & T_R) =3D=3D 0) { struct sk_buff *skb; =20 + skb =3D ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]; + /* BD contains already transmitted buffer. */ /* Handle the transmitted buffer and release */ /* the BD to be used with the current frame */ =20 - if ((bd =3D=3D ugeth->txBd[txQ]) && (netif_queue_stopped(dev) =3D=3D 0)) + if ((bd =3D=3D ugeth->txBd[txQ]) && (skb =3D=3D NULL)) break; =20 dev->stats.tx_packets++; =20 - skb =3D ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]; - if (skb_queue_len(&ugeth->rx_recycle) < RX_BD_RING_LEN && skb_recycle_check(skb, =20 ugeth->ug_info->uf_info.max_rx_buf_length + --=20 1.5.6.3 -----Original Message----- From: linuxppc-dev-bounces+b13201=3Dfreescale.com@lists.ozlabs.org [mailto:linuxppc-dev-bounces+b13201=3Dfreescale.com@lists.ozlabs.org] On Behalf Of Anton Vorontsov Sent: Thursday, December 24, 2009 11:31 PM To: David Miller Cc: linuxppc-dev@ozlabs.org; netdev@vger.kernel.org; Lennart Sorensen Subject: [PATCH 1/3] ucc_geth: Fix empty TX queue processing ----------- Following oops was seen with the ucc_geth driver: Unable to handle kernel paging request for data at address 0x00000058 Faulting instruction address: 0xc024f2fc Oops: Kernel access of bad area, sig: 11 [#1] [...] NIP [c024f2fc] skb_recycle_check+0x14/0x100 LR [e30aa0a4] ucc_geth_poll+0xd8/0x4e0 [ucc_geth_driver] Call Trace: [df857d50] [c000b03c] __ipipe_grab_irq+0x3c/0xa4 (unreliable) [df857d60] [e30aa0a4] ucc_geth_poll+0xd8/0x4e0 [ucc_geth_driver] [df857dd0] [c0258cf8] net_rx_action+0xf8/0x1b8 [df857e10] [c0032a38] __do_softirq+0xb8/0x13c [df857e60] [c00065cc] do_softirq+0xa0/0xac [...] This is because ucc_geth_tx() tries to process an empty queue when queues are logically stopped. Stopping the queues doesn't disable polling, and since nowadays ucc_geth_tx() is actually called from the polling routine, the oops above might pop up. Fix this by removing 'netif_queue_stopped() =3D=3D 0' check. Reported-by: Lennart Sorensen <lsorense@csclub.uwaterloo.ca> Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> Tested-by: Lennart Sorensen <lsorense@csclub.uwaterloo.ca> Cc: Stable <stable@vger.kernel.org> [2.6.32] --- drivers/net/ucc_geth.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index afaf088..0f8c99e 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3273,7 +3273,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) /* Handle the transmitted buffer and release */ /* the BD to be used with the current frame */ =20 - if ((bd =3D=3D ugeth->txBd[txQ]) && (netif_queue_stopped(dev) =3D=3D 0)) + if (bd =3D=3D ugeth->txBd[txQ]) /* queue empty? */ break; =20 dev->stats.tx_packets++; -- 1.6.3.3 _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev ^ permalink raw reply related [flat|nested] 16+ messages in thread
* RE: [PATCH 1/3] ucc_geth: Fix empty TX queue processing @ 2010-01-11 3:47 ` Wu Jiajun-B06378 0 siblings, 0 replies; 16+ messages in thread From: Wu Jiajun-B06378 @ 2010-01-11 3:47 UTC (permalink / raw) To: avorontsov; +Cc: linuxppc-dev, netdev, lsorense, davem 'bd == ugeth->txBd[txQ]' has two possible statuses: 1)full queue. 2)empty queue. Removing 'netif_queue_stopped() == 0' will make transmitting stopping when the queue is full. I made a new patch for this oops. >From 726765194352d01dc8ea672d97612589b67cec3f Mon Sep 17 00:00:00 2001 From: Jiajun Wu <b06378@freescale.com> Date: Mon, 11 Jan 2010 10:57:22 +0800 Subject: [PATCH] ucc_geth: Fix empty TX queue processing Signed-off-by: Jiajun Wu <b06378@freescale.com> --- drivers/net/ucc_geth.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index f982220..34345f0 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3576,17 +3576,17 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) while ((bd_status & T_R) == 0) { struct sk_buff *skb; + skb = ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]; + /* BD contains already transmitted buffer. */ /* Handle the transmitted buffer and release */ /* the BD to be used with the current frame */ - if ((bd == ugeth->txBd[txQ]) && (netif_queue_stopped(dev) == 0)) + if ((bd == ugeth->txBd[txQ]) && (skb == NULL)) break; dev->stats.tx_packets++; - skb = ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]; - if (skb_queue_len(&ugeth->rx_recycle) < RX_BD_RING_LEN && skb_recycle_check(skb, ugeth->ug_info->uf_info.max_rx_buf_length + -- 1.5.6.3 -----Original Message----- From: linuxppc-dev-bounces+b13201=freescale.com@lists.ozlabs.org [mailto:linuxppc-dev-bounces+b13201=freescale.com@lists.ozlabs.org] On Behalf Of Anton Vorontsov Sent: Thursday, December 24, 2009 11:31 PM To: David Miller Cc: linuxppc-dev@ozlabs.org; netdev@vger.kernel.org; Lennart Sorensen Subject: [PATCH 1/3] ucc_geth: Fix empty TX queue processing ----------- Following oops was seen with the ucc_geth driver: Unable to handle kernel paging request for data at address 0x00000058 Faulting instruction address: 0xc024f2fc Oops: Kernel access of bad area, sig: 11 [#1] [...] NIP [c024f2fc] skb_recycle_check+0x14/0x100 LR [e30aa0a4] ucc_geth_poll+0xd8/0x4e0 [ucc_geth_driver] Call Trace: [df857d50] [c000b03c] __ipipe_grab_irq+0x3c/0xa4 (unreliable) [df857d60] [e30aa0a4] ucc_geth_poll+0xd8/0x4e0 [ucc_geth_driver] [df857dd0] [c0258cf8] net_rx_action+0xf8/0x1b8 [df857e10] [c0032a38] __do_softirq+0xb8/0x13c [df857e60] [c00065cc] do_softirq+0xa0/0xac [...] This is because ucc_geth_tx() tries to process an empty queue when queues are logically stopped. Stopping the queues doesn't disable polling, and since nowadays ucc_geth_tx() is actually called from the polling routine, the oops above might pop up. Fix this by removing 'netif_queue_stopped() == 0' check. Reported-by: Lennart Sorensen <lsorense@csclub.uwaterloo.ca> Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> Tested-by: Lennart Sorensen <lsorense@csclub.uwaterloo.ca> Cc: Stable <stable@vger.kernel.org> [2.6.32] --- drivers/net/ucc_geth.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index afaf088..0f8c99e 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3273,7 +3273,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) /* Handle the transmitted buffer and release */ /* the BD to be used with the current frame */ - if ((bd == ugeth->txBd[txQ]) && (netif_queue_stopped(dev) == 0)) + if (bd == ugeth->txBd[txQ]) /* queue empty? */ break; dev->stats.tx_packets++; -- 1.6.3.3 _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH 1/3] ucc_geth: Fix empty TX queue processing 2010-01-11 3:47 ` Wu Jiajun-B06378 @ 2010-01-11 10:52 ` Anton Vorontsov -1 siblings, 0 replies; 16+ messages in thread From: Anton Vorontsov @ 2010-01-11 10:52 UTC (permalink / raw) To: Wu Jiajun-B06378; +Cc: linuxppc-dev, lsorense, davem, netdev On Mon, Jan 11, 2010 at 11:47:37AM +0800, Wu Jiajun-B06378 wrote: > > 'bd == ugeth->txBd[txQ]' has two possible statuses: 1)full queue. > 2)empty queue. > Removing 'netif_queue_stopped() == 0' will make transmitting stopping > when the queue is full. > > I made a new patch for this oops. [...] > + if ((bd == ugeth->txBd[txQ]) && (skb == NULL)) > break; Hm. I wonder why do we need the 'bd == ugeth->txBd[txQ]' check at all? The null skb will cause a kernel oops anyway. I think the patch below should be sufficient for the fix. Can you try it? Or if you tell me how to reproduce the issue you observe, I can try it myself. Thanks a lot! diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 41ad2f3..a1a6d06 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3279,13 +3279,12 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) /* Handle the transmitted buffer and release */ /* the BD to be used with the current frame */ - if (bd == ugeth->txBd[txQ]) /* queue empty? */ + skb = ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]; + if (!skb) break; dev->stats.tx_packets++; - skb = ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]; - if (skb_queue_len(&ugeth->rx_recycle) < RX_BD_RING_LEN && skb_recycle_check(skb, ugeth->ug_info->uf_info.max_rx_buf_length + ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH 1/3] ucc_geth: Fix empty TX queue processing @ 2010-01-11 10:52 ` Anton Vorontsov 0 siblings, 0 replies; 16+ messages in thread From: Anton Vorontsov @ 2010-01-11 10:52 UTC (permalink / raw) To: Wu Jiajun-B06378; +Cc: linuxppc-dev, netdev, lsorense, davem On Mon, Jan 11, 2010 at 11:47:37AM +0800, Wu Jiajun-B06378 wrote: > > 'bd == ugeth->txBd[txQ]' has two possible statuses: 1)full queue. > 2)empty queue. > Removing 'netif_queue_stopped() == 0' will make transmitting stopping > when the queue is full. > > I made a new patch for this oops. [...] > + if ((bd == ugeth->txBd[txQ]) && (skb == NULL)) > break; Hm. I wonder why do we need the 'bd == ugeth->txBd[txQ]' check at all? The null skb will cause a kernel oops anyway. I think the patch below should be sufficient for the fix. Can you try it? Or if you tell me how to reproduce the issue you observe, I can try it myself. Thanks a lot! diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 41ad2f3..a1a6d06 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3279,13 +3279,12 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) /* Handle the transmitted buffer and release */ /* the BD to be used with the current frame */ - if (bd == ugeth->txBd[txQ]) /* queue empty? */ + skb = ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]; + if (!skb) break; dev->stats.tx_packets++; - skb = ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]; - if (skb_queue_len(&ugeth->rx_recycle) < RX_BD_RING_LEN && skb_recycle_check(skb, ugeth->ug_info->uf_info.max_rx_buf_length + ^ permalink raw reply related [flat|nested] 16+ messages in thread
* RE: [PATCH 1/3] ucc_geth: Fix empty TX queue processing 2010-01-11 10:52 ` Anton Vorontsov @ 2010-01-11 11:52 ` Wu Jiajun-B06378 -1 siblings, 0 replies; 16+ messages in thread From: Wu Jiajun-B06378 @ 2010-01-11 11:52 UTC (permalink / raw) To: avorontsov; +Cc: linuxppc-dev, lsorense, davem, netdev Yes,'if (!skb)' is enough. You can reproduce transmitting stopping if you use 'if ((bd =3D=3D = ugeth->txBd[txQ])' and run ipforwarding with MTU=3D64 1Gbps = 100%linerate. -----Original Message----- From: Anton Vorontsov [mailto:avorontsov@ru.mvista.com]=20 Sent: 2010=C4=EA1=D4=C211=C8=D5 18:53 To: Wu Jiajun-B06378 Cc: linuxppc-dev@ozlabs.org; netdev@vger.kernel.org; = lsorense@csclub.uwaterloo.ca; davem@davemloft.net Subject: Re: [PATCH 1/3] ucc_geth: Fix empty TX queue processing On Mon, Jan 11, 2010 at 11:47:37AM +0800, Wu Jiajun-B06378 wrote: > =20 > 'bd =3D=3D ugeth->txBd[txQ]' has two possible statuses: 1)full queue. > 2)empty queue. > Removing 'netif_queue_stopped() =3D=3D 0' will make transmitting = stopping=20 > when the queue is full. >=20 > I made a new patch for this oops. [...] > + if ((bd =3D=3D ugeth->txBd[txQ]) && (skb =3D=3D NULL)) > break; Hm. I wonder why do we need the 'bd =3D=3D ugeth->txBd[txQ]' check at = all? The null skb will cause a kernel oops anyway. I think the patch below should be sufficient for the fix. Can you try it? Or if you tell me how to reproduce the issue you = observe, I can try it myself. Thanks a lot! diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index = 41ad2f3..a1a6d06 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3279,13 +3279,12 @@ static int ucc_geth_tx(struct net_device *dev, = u8 txQ) /* Handle the transmitted buffer and release */ /* the BD to be used with the current frame */ =20 - if (bd =3D=3D ugeth->txBd[txQ]) /* queue empty? */ + skb =3D ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]; + if (!skb) break; =20 dev->stats.tx_packets++; =20 - skb =3D ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]; - if (skb_queue_len(&ugeth->rx_recycle) < RX_BD_RING_LEN && skb_recycle_check(skb, ugeth->ug_info->uf_info.max_rx_buf_length + ^ permalink raw reply [flat|nested] 16+ messages in thread
* RE: [PATCH 1/3] ucc_geth: Fix empty TX queue processing @ 2010-01-11 11:52 ` Wu Jiajun-B06378 0 siblings, 0 replies; 16+ messages in thread From: Wu Jiajun-B06378 @ 2010-01-11 11:52 UTC (permalink / raw) To: avorontsov; +Cc: linuxppc-dev, netdev, lsorense, davem Yes,'if (!skb)' is enough. You can reproduce transmitting stopping if you use 'if ((bd == ugeth->txBd[txQ])' and run ipforwarding with MTU=64 1Gbps 100%linerate. -----Original Message----- From: Anton Vorontsov [mailto:avorontsov@ru.mvista.com] Sent: 2010年1月11日 18:53 To: Wu Jiajun-B06378 Cc: linuxppc-dev@ozlabs.org; netdev@vger.kernel.org; lsorense@csclub.uwaterloo.ca; davem@davemloft.net Subject: Re: [PATCH 1/3] ucc_geth: Fix empty TX queue processing On Mon, Jan 11, 2010 at 11:47:37AM +0800, Wu Jiajun-B06378 wrote: > > 'bd == ugeth->txBd[txQ]' has two possible statuses: 1)full queue. > 2)empty queue. > Removing 'netif_queue_stopped() == 0' will make transmitting stopping > when the queue is full. > > I made a new patch for this oops. [...] > + if ((bd == ugeth->txBd[txQ]) && (skb == NULL)) > break; Hm. I wonder why do we need the 'bd == ugeth->txBd[txQ]' check at all? The null skb will cause a kernel oops anyway. I think the patch below should be sufficient for the fix. Can you try it? Or if you tell me how to reproduce the issue you observe, I can try it myself. Thanks a lot! diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 41ad2f3..a1a6d06 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3279,13 +3279,12 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) /* Handle the transmitted buffer and release */ /* the BD to be used with the current frame */ - if (bd == ugeth->txBd[txQ]) /* queue empty? */ + skb = ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]; + if (!skb) break; dev->stats.tx_packets++; - skb = ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]; - if (skb_queue_len(&ugeth->rx_recycle) < RX_BD_RING_LEN && skb_recycle_check(skb, ugeth->ug_info->uf_info.max_rx_buf_length + ^ permalink raw reply [flat|nested] 16+ messages in thread
* [stable] Please apply ucc_geth driver fixes to 2.6.32-stable @ 2010-06-22 13:02 Petri Lehtinen 2010-06-22 13:02 ` [PATCH 1/3] ucc_geth: Fix empty TX queue processing Petri Lehtinen 0 siblings, 1 reply; 16+ messages in thread From: Petri Lehtinen @ 2010-06-22 13:02 UTC (permalink / raw) To: linux-kernel; +Cc: stable, netdev (I already sent these patches a few weeks ago and got no reply. I also sent them to some of the recipients a few minutes ago and failed to use git-send-email properly. So sorry for the noise.) Please include the following three patches to 2.6.32-stable. They fix serious flaws in the ucc_geth ethernet driver, making it unusable (at least on my system). They have been included in 2.6.33 and apply cleanly on top of 2.6.32-stable. ^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 1/3] ucc_geth: Fix empty TX queue processing 2010-06-22 13:02 [stable] Please apply ucc_geth driver fixes to 2.6.32-stable Petri Lehtinen @ 2010-06-22 13:02 ` Petri Lehtinen 0 siblings, 0 replies; 16+ messages in thread From: Petri Lehtinen @ 2010-06-22 13:02 UTC (permalink / raw) To: linux-kernel Cc: stable, netdev, Anton Vorontsov, Stable, "[2.6.32]", David S. Miller From: Anton Vorontsov <avorontsov@ru.mvista.com> Following oops was seen with the ucc_geth driver: Unable to handle kernel paging request for data at address 0x00000058 Faulting instruction address: 0xc024f2fc Oops: Kernel access of bad area, sig: 11 [#1] [...] NIP [c024f2fc] skb_recycle_check+0x14/0x100 LR [e30aa0a4] ucc_geth_poll+0xd8/0x4e0 [ucc_geth_driver] Call Trace: [df857d50] [c000b03c] __ipipe_grab_irq+0x3c/0xa4 (unreliable) [df857d60] [e30aa0a4] ucc_geth_poll+0xd8/0x4e0 [ucc_geth_driver] [df857dd0] [c0258cf8] net_rx_action+0xf8/0x1b8 [df857e10] [c0032a38] __do_softirq+0xb8/0x13c [df857e60] [c00065cc] do_softirq+0xa0/0xac [...] This is because ucc_geth_tx() tries to process an empty queue when queues are logically stopped. Stopping the queues doesn't disable polling, and since nowadays ucc_geth_tx() is actually called from the polling routine, the oops above might pop up. Fix this by removing 'netif_queue_stopped() == 0' check. Reported-by: Lennart Sorensen <lsorense@csclub.uwaterloo.ca> Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com> Tested-by: Lennart Sorensen <lsorense@csclub.uwaterloo.ca> Cc: Stable <stable@vger.kernel.org> [2.6.32] Signed-off-by: David S. Miller <davem@davemloft.net> (cherry picked from commit 7583605b6d29f1f7f6fc505b883328089f3485ad) --- drivers/net/ucc_geth.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 4469f24..20aa5b5 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3273,7 +3273,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ) /* Handle the transmitted buffer and release */ /* the BD to be used with the current frame */ - if ((bd == ugeth->txBd[txQ]) && (netif_queue_stopped(dev) == 0)) + if (bd == ugeth->txBd[txQ]) /* queue empty? */ break; dev->stats.tx_packets++; -- 1.7.1 ^ permalink raw reply related [flat|nested] 16+ messages in thread
end of thread, other threads:[~2010-06-22 13:02 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-12-24 15:30 [PATCH 0/3] ucc_geth: Some more fixes Anton Vorontsov
2009-12-24 15:31 ` [PATCH 1/3] ucc_geth: Fix empty TX queue processing Anton Vorontsov
2009-12-24 15:31 ` Anton Vorontsov
2009-12-24 15:31 ` [PATCH 2/3] ucc_geth: Fix netdev watchdog triggering on link changes Anton Vorontsov
2009-12-24 15:31 ` Anton Vorontsov
2009-12-24 15:31 ` [PATCH 3/3] ucc_geth: Don't needlessly change MAC settings in adjust_link() Anton Vorontsov
2009-12-24 15:31 ` Anton Vorontsov
2009-12-27 4:25 ` [PATCH 0/3] ucc_geth: Some more fixes David Miller
2009-12-27 4:25 ` David Miller
[not found] <0A1FE637C2C7E148B9573BB60CC630E56C3E90@zch01exm26.fsl.freescale.net>
2010-01-11 3:47 ` [PATCH 1/3] ucc_geth: Fix empty TX queue processing Wu Jiajun-B06378
2010-01-11 3:47 ` Wu Jiajun-B06378
2010-01-11 10:52 ` Anton Vorontsov
2010-01-11 10:52 ` Anton Vorontsov
2010-01-11 11:52 ` Wu Jiajun-B06378
2010-01-11 11:52 ` Wu Jiajun-B06378
-- strict thread matches above, loose matches on Subject: below --
2010-06-22 13:02 [stable] Please apply ucc_geth driver fixes to 2.6.32-stable Petri Lehtinen
2010-06-22 13:02 ` [PATCH 1/3] ucc_geth: Fix empty TX queue processing Petri Lehtinen
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.