* [PATCH] b43: use rx desc underrun interrupt @ 2013-04-15 8:02 Thommy Jakobsson 2013-04-19 14:32 ` Jonas Gorski 0 siblings, 1 reply; 45+ messages in thread From: Thommy Jakobsson @ 2013-04-15 8:02 UTC (permalink / raw) To: b43-dev Hi, long user of b43 driver under openwrt. Not sure if it has been posted previously but using slow and old hardware (as routers running openwrt most of the time is), the CPU is sometimes slower than the NIC. So recently I, and several others, has had problem of wifi going down. See ticket 7552 at openwrt for more info (https://dev.openwrt.org/ticket/7552) I have tracked down the problem to the nic getting into a rx descriptor underrun. Since the driver don't listen to that (or take care of it in any other way), the Wifi seemingly just dies. The CPU is waiting for data from the nic and the nic is waiting for a confirmation that it can keep sending. I created a patch for handling of that interrupt. I have tested it by reducing the number of rx slots to 16 and sending a couple of 100GB of data. Previously Wifi went down within a minute when maxing out the uplink (so rx for AP), now it has been working flawless for a 1.5week. BR, Thommy Jakobsson Index: drivers/net/wireless/b43/dma.c =================================================================== --- compat-wireless-2012-09-07.orig/drivers/net/wireless/b43/dma.c 2013-04-09 17:33:54.325322046 +0200 +++ compat-wireless-2012-09-07/drivers/net/wireless/b43/dma.c 2013-04-09 17:34:43.473565843 +0200 @@ -1688,6 +1688,21 @@ b43_poison_rx_buffer(ring, skb); sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize); } +void b43_dma_rx_discard(struct b43_dmaring *ring) +{ + B43_WARN_ON(ring->tx); + + /* Device has filled all buffers, drop all packets in buffers + * and let TCP decrease speed. + * Set index to one desc after the last one (which is marked) + * so the device will see all slots as free again + */ + /* + *TODO: How to increase rx_drop in mac80211 + */ + b43_dma_write(ring, B43_DMA32_RXINDEX, ring->nr_slots * + sizeof(struct b43_dmadesc32)); +} void b43_dma_rx(struct b43_dmaring *ring) { Index: drivers/net/wireless/b43/dma.h =================================================================== --- compat-wireless-2012-09-07.orig/drivers/net/wireless/b43/dma.h 2013-04-09 17:34:09.561397686 +0200 +++ compat-wireless-2012-09-07/drivers/net/wireless/b43/dma.h 2013-04-09 17:34:43.461565780 +0200 @@ -10,7 +10,8 @@ #define B43_DMAIRQ_FATALMASK ((1 << 10) | (1 << 11) | (1 << 12) \ | (1 << 14) | (1 << 15)) #define B43_DMAIRQ_NONFATALMASK (1 << 13) -#define B43_DMAIRQ_RX_DONE (1 << 16) +#define B43_DMAIRQ_RX_DONE (1 << 16) +#define B43_DMAIRQ_RDESC_UFLOW (1 << 13) /*** 32-bit DMA Engine. ***/ @@ -295,6 +296,8 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, const struct b43_txstatus *status); +void b43_dma_rx_discard(struct b43_dmaring *ring); + void b43_dma_rx(struct b43_dmaring *ring); void b43_dma_direct_fifo_rx(struct b43_wldev *dev, Index: drivers/net/wireless/b43/main.c =================================================================== --- compat-wireless-2012-09-07.orig/drivers/net/wireless/b43/main.c 2013-04-09 17:33:54.325322046 +0200 +++ compat-wireless-2012-09-07/drivers/net/wireless/b43/main.c 2013-04-09 18:08:01.011471215 +0200 @@ -1894,14 +1894,6 @@ b43_controller_restart(dev, "DMA error"); return; } - if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) { - b43err(dev->wl, "DMA error: " - "0x%08X, 0x%08X, 0x%08X, " - "0x%08X, 0x%08X, 0x%08X\n", - dma_reason[0], dma_reason[1], - dma_reason[2], dma_reason[3], - dma_reason[4], dma_reason[5]); - } } if (unlikely(reason & B43_IRQ_UCODE_DEBUG)) @@ -1920,6 +1912,14 @@ handle_irq_noise(dev); /* Check the DMA reason registers for received data. */ + if (dma_reason[0] & B43_DMAIRQ_RDESC_UFLOW) { + //only print 256 time to not flood log + if(!(dev->stats.rxdesc_underruns++&0xFF)){ + b43warn(dev->wl, "Rx descriptor underrun (high cpu load?), throwing packets\n"); + } + b43_dma_rx_discard(dev->dma.rx_ring); + + } if (dma_reason[0] & B43_DMAIRQ_RX_DONE) { if (b43_using_pio_transfers(dev)) b43_pio_rx(dev->pio.rx_queue); @@ -1977,7 +1977,7 @@ return IRQ_NONE; dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON) - & 0x0001DC00; + & 0x0001FC00; dev->dma_reason[1] = b43_read32(dev, B43_MMIO_DMA1_REASON) & 0x0000DC00; dev->dma_reason[2] = b43_read32(dev, B43_MMIO_DMA2_REASON) @@ -3081,7 +3081,7 @@ b43_write32(dev, 0x018C, 0x02000000); } b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, 0x00004000); - b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001DC00); + b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001FC00); b43_write32(dev, B43_MMIO_DMA1_IRQ_MASK, 0x0000DC00); b43_write32(dev, B43_MMIO_DMA2_IRQ_MASK, 0x0000DC00); b43_write32(dev, B43_MMIO_DMA3_IRQ_MASK, 0x0001DC00); =================================================================== --- compat-wireless-2012-09-07.orig/drivers/net/wireless/b43/b43.h 2013-04-09 17:04:51.552680190 +0200 +++ compat-wireless-2012-09-07/drivers/net/wireless/b43/b43.h 2013-04-09 17:46:08.472962612 +0200 @@ -671,6 +671,7 @@ struct b43_stats { u8 link_noise; + u32 rxdesc_underruns; }; struct b43_key { ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-15 8:02 [PATCH] b43: use rx desc underrun interrupt Thommy Jakobsson @ 2013-04-19 14:32 ` Jonas Gorski 2013-04-19 15:55 ` Michael Büsch ` (3 more replies) 0 siblings, 4 replies; 45+ messages in thread From: Jonas Gorski @ 2013-04-19 14:32 UTC (permalink / raw) To: b43-dev Hi, On Mon, Apr 15, 2013 at 10:02 AM, Thommy Jakobsson <thommyj@gmail.com> wrote: > Hi, > > long user of b43 driver under openwrt. Not sure if it has been posted > previously but using slow and old hardware (as routers running openwrt > most of the time is), the CPU is sometimes slower than the NIC. So > recently I, and several others, has had problem of wifi going down. > See ticket 7552 at openwrt for more info > (https://dev.openwrt.org/ticket/7552) > > I have tracked down the problem to the nic getting into a rx > descriptor underrun. Since the driver don't listen to that (or take > care of it in any other way), the Wifi seemingly just dies. The CPU is > waiting for data from the nic and the nic is waiting for a > confirmation that it can keep sending. > > I created a patch for handling of that interrupt. I have tested it by > reducing the number of rx slots to 16 and sending a couple of 100GB of > data. Previously Wifi went down within a minute when maxing out the > uplink (so rx for AP), now it has been working flawless for a 1.5week. Nice, very good to hear. Looks like you found the real issue the rx descriptor count increase was just papering over. Some comments regarding your patch. > > BR, > Thommy Jakobsson > You are missing a "Signed-off-by" - without it the patch can never be accepted. Also your patch is has broken tabs (they were converted to spaces), as well as is line-broken, so it doesn't apply anymore. You can't use gmail's web interface for sending patches. > Index: drivers/net/wireless/b43/dma.c > =================================================================== > --- compat-wireless-2012-09-07.orig/drivers/net/wireless/b43/dma.c > 2013-04-09 17:33:54.325322046 +0200 > +++ compat-wireless-2012-09-07/drivers/net/wireless/b43/dma.c You should make your patch against the newest git tree, so usually wireless-testing or Rafa?'s b43-next. > 2013-04-09 17:34:43.473565843 +0200 > @@ -1688,6 +1688,21 @@ > b43_poison_rx_buffer(ring, skb); > sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize); > } > +void b43_dma_rx_discard(struct b43_dmaring *ring) > +{ > + B43_WARN_ON(ring->tx); > + > + /* Device has filled all buffers, drop all packets in buffers > + * and let TCP decrease speed. > + * Set index to one desc after the last one (which is marked) > + * so the device will see all slots as free again > + */ > + /* > + *TODO: How to increase rx_drop in mac80211 > + */ > + b43_dma_write(ring, B43_DMA32_RXINDEX, ring->nr_slots * > + sizeof(struct b43_dmadesc32)); > +} > > void b43_dma_rx(struct b43_dmaring *ring) > { > > Index: drivers/net/wireless/b43/dma.h > =================================================================== > --- compat-wireless-2012-09-07.orig/drivers/net/wireless/b43/dma.h > 2013-04-09 17:34:09.561397686 +0200 > +++ compat-wireless-2012-09-07/drivers/net/wireless/b43/dma.h > 2013-04-09 17:34:43.461565780 +0200 > @@ -10,7 +10,8 @@ > #define B43_DMAIRQ_FATALMASK ((1 << 10) | (1 << 11) | (1 << 12) \ > | (1 << 14) | (1 << 15)) > #define B43_DMAIRQ_NONFATALMASK (1 << 13) > -#define B43_DMAIRQ_RX_DONE (1 << 16) > +#define B43_DMAIRQ_RX_DONE (1 << 16) Unnecessary whitespace change. > +#define B43_DMAIRQ_RDESC_UFLOW (1 << 13) Why not just rename B43_DMAIRQ_NONFATALMASK ? > > /*** 32-bit DMA Engine. ***/ > > @@ -295,6 +296,8 @@ > void b43_dma_handle_txstatus(struct b43_wldev *dev, > const struct b43_txstatus *status); > > +void b43_dma_rx_discard(struct b43_dmaring *ring); > + > void b43_dma_rx(struct b43_dmaring *ring); > > void b43_dma_direct_fifo_rx(struct b43_wldev *dev, > > Index: drivers/net/wireless/b43/main.c > =================================================================== > --- compat-wireless-2012-09-07.orig/drivers/net/wireless/b43/main.c > 2013-04-09 17:33:54.325322046 +0200 > +++ compat-wireless-2012-09-07/drivers/net/wireless/b43/main.c > 2013-04-09 18:08:01.011471215 +0200 > @@ -1894,14 +1894,6 @@ > b43_controller_restart(dev, "DMA error"); > return; > } > - if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) { > - b43err(dev->wl, "DMA error: " > - "0x%08X, 0x%08X, 0x%08X, " > - "0x%08X, 0x%08X, 0x%08X\n", > - dma_reason[0], dma_reason[1], > - dma_reason[2], dma_reason[3], > - dma_reason[4], dma_reason[5]); > - } You should say why you remove this one, and you should remove the B43_DMAIRQ_NONFATALMASK from the if (unlikely()) enclosing it. > } > > if (unlikely(reason & B43_IRQ_UCODE_DEBUG)) > @@ -1920,6 +1912,14 @@ > handle_irq_noise(dev); > > /* Check the DMA reason registers for received data. */ > + if (dma_reason[0] & B43_DMAIRQ_RDESC_UFLOW) { > + //only print 256 time to not flood log > + if(!(dev->stats.rxdesc_underruns++&0xFF)){ > + b43warn(dev->wl, "Rx descriptor underrun > (high cpu load?), throwing packets\n"); Apart from the style problems, maybe doing a if (printk_ratelimit()) b43warn(...); which will ensure that it won't flood the log, but still won't stop reporting them after the 256th time. > + } > + b43_dma_rx_discard(dev->dma.rx_ring); > + > + } > if (dma_reason[0] & B43_DMAIRQ_RX_DONE) { > if (b43_using_pio_transfers(dev)) > b43_pio_rx(dev->pio.rx_queue); > @@ -1977,7 +1977,7 @@ > return IRQ_NONE; > > dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON) > - & 0x0001DC00; > + & 0x0001FC00; > dev->dma_reason[1] = b43_read32(dev, B43_MMIO_DMA1_REASON) > & 0x0000DC00; > dev->dma_reason[2] = b43_read32(dev, B43_MMIO_DMA2_REASON) > @@ -3081,7 +3081,7 @@ > b43_write32(dev, 0x018C, 0x02000000); > } > b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, 0x00004000); > - b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001DC00); > + b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001FC00); > b43_write32(dev, B43_MMIO_DMA1_IRQ_MASK, 0x0000DC00); > b43_write32(dev, B43_MMIO_DMA2_IRQ_MASK, 0x0000DC00); > b43_write32(dev, B43_MMIO_DMA3_IRQ_MASK, 0x0001DC00); > > =================================================================== > --- compat-wireless-2012-09-07.orig/drivers/net/wireless/b43/b43.h > 2013-04-09 17:04:51.552680190 +0200 > +++ compat-wireless-2012-09-07/drivers/net/wireless/b43/b43.h > 2013-04-09 17:46:08.472962612 +0200 > @@ -671,6 +671,7 @@ > > struct b43_stats { > u8 link_noise; > + u32 rxdesc_underruns; > }; > > struct b43_key { Jonas ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-19 14:32 ` Jonas Gorski @ 2013-04-19 15:55 ` Michael Büsch 2013-04-19 15:59 ` Jonas Gorski 2013-04-19 18:17 ` Larry Finger ` (2 subsequent siblings) 3 siblings, 1 reply; 45+ messages in thread From: Michael Büsch @ 2013-04-19 15:55 UTC (permalink / raw) To: b43-dev On Fri, 19 Apr 2013 16:32:00 +0200 Jonas Gorski <jonas.gorski@gmail.com> wrote: > Apart from the style problems, maybe doing a > if (printk_ratelimit()) > b43warn(...); > > which will ensure that it won't flood the log, but still won't stop > reporting them after the 256th time. All b43 log helpers are ratelimited already. So no need for that. -- Michael -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: not available URL: <http://lists.infradead.org/pipermail/b43-dev/attachments/20130419/a57f356e/attachment.sig> ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-19 15:55 ` Michael Büsch @ 2013-04-19 15:59 ` Jonas Gorski 0 siblings, 0 replies; 45+ messages in thread From: Jonas Gorski @ 2013-04-19 15:59 UTC (permalink / raw) To: b43-dev On Fri, Apr 19, 2013 at 5:55 PM, Michael B?sch <m@bues.ch> wrote: > On Fri, 19 Apr 2013 16:32:00 +0200 > Jonas Gorski <jonas.gorski@gmail.com> wrote: > >> Apart from the style problems, maybe doing a >> if (printk_ratelimit()) >> b43warn(...); >> >> which will ensure that it won't flood the log, but still won't stop >> reporting them after the 256th time. > > All b43 log helpers are ratelimited already. So no need for that. Even better :-) Jonas ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-19 14:32 ` Jonas Gorski 2013-04-19 15:55 ` Michael Büsch @ 2013-04-19 18:17 ` Larry Finger 2013-04-19 18:57 ` Michael Büsch 2013-04-19 20:30 ` Thommy Jakobsson 2013-04-20 14:14 ` Thommy 3 siblings, 1 reply; 45+ messages in thread From: Larry Finger @ 2013-04-19 18:17 UTC (permalink / raw) To: b43-dev On 04/19/2013 09:32 AM, Jonas Gorski wrote: > Hi, > > On Mon, Apr 15, 2013 at 10:02 AM, Thommy Jakobsson <thommyj@gmail.com> wrote: >> Hi, >> >> long user of b43 driver under openwrt. Not sure if it has been posted >> previously but using slow and old hardware (as routers running openwrt >> most of the time is), the CPU is sometimes slower than the NIC. So >> recently I, and several others, has had problem of wifi going down. >> See ticket 7552 at openwrt for more info >> (https://dev.openwrt.org/ticket/7552) >> >> I have tracked down the problem to the nic getting into a rx >> descriptor underrun. Since the driver don't listen to that (or take >> care of it in any other way), the Wifi seemingly just dies. The CPU is >> waiting for data from the nic and the nic is waiting for a >> confirmation that it can keep sending. >> >> I created a patch for handling of that interrupt. I have tested it by >> reducing the number of rx slots to 16 and sending a couple of 100GB of >> data. Previously Wifi went down within a minute when maxing out the >> uplink (so rx for AP), now it has been working flawless for a 1.5week. > > Nice, very good to hear. Looks like you found the real issue the rx > descriptor count increase was just papering over. Some comments > regarding your patch. > >> >> BR, >> Thommy Jakobsson >> > > You are missing a "Signed-off-by" - without it the patch can never be > accepted. Also your patch is has broken tabs (they were converted to > spaces), as well as is line-broken, so it doesn't apply anymore. You > can't use gmail's web interface for sending patches. > >> Index: drivers/net/wireless/b43/dma.c >> =================================================================== >> --- compat-wireless-2012-09-07.orig/drivers/net/wireless/b43/dma.c >> 2013-04-09 17:33:54.325322046 +0200 >> +++ compat-wireless-2012-09-07/drivers/net/wireless/b43/dma.c > > You should make your patch against the newest git tree, so usually > wireless-testing or Rafa?'s b43-next. > >> 2013-04-09 17:34:43.473565843 +0200 >> @@ -1688,6 +1688,21 @@ >> b43_poison_rx_buffer(ring, skb); >> sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize); >> } >> +void b43_dma_rx_discard(struct b43_dmaring *ring) >> +{ >> + B43_WARN_ON(ring->tx); >> + >> + /* Device has filled all buffers, drop all packets in buffers >> + * and let TCP decrease speed. >> + * Set index to one desc after the last one (which is marked) >> + * so the device will see all slots as free again >> + */ >> + /* >> + *TODO: How to increase rx_drop in mac80211 >> + */ >> + b43_dma_write(ring, B43_DMA32_RXINDEX, ring->nr_slots * >> + sizeof(struct b43_dmadesc32)); >> +} >> >> void b43_dma_rx(struct b43_dmaring *ring) >> { >> >> Index: drivers/net/wireless/b43/dma.h >> =================================================================== >> --- compat-wireless-2012-09-07.orig/drivers/net/wireless/b43/dma.h >> 2013-04-09 17:34:09.561397686 +0200 >> +++ compat-wireless-2012-09-07/drivers/net/wireless/b43/dma.h >> 2013-04-09 17:34:43.461565780 +0200 >> @@ -10,7 +10,8 @@ >> #define B43_DMAIRQ_FATALMASK ((1 << 10) | (1 << 11) | (1 << 12) \ >> | (1 << 14) | (1 << 15)) >> #define B43_DMAIRQ_NONFATALMASK (1 << 13) >> -#define B43_DMAIRQ_RX_DONE (1 << 16) >> +#define B43_DMAIRQ_RX_DONE (1 << 16) > > Unnecessary whitespace change. > >> +#define B43_DMAIRQ_RDESC_UFLOW (1 << 13) > > Why not just rename B43_DMAIRQ_NONFATALMASK ? > >> >> /*** 32-bit DMA Engine. ***/ >> >> @@ -295,6 +296,8 @@ >> void b43_dma_handle_txstatus(struct b43_wldev *dev, >> const struct b43_txstatus *status); >> >> +void b43_dma_rx_discard(struct b43_dmaring *ring); >> + >> void b43_dma_rx(struct b43_dmaring *ring); >> >> void b43_dma_direct_fifo_rx(struct b43_wldev *dev, >> >> Index: drivers/net/wireless/b43/main.c >> =================================================================== >> --- compat-wireless-2012-09-07.orig/drivers/net/wireless/b43/main.c >> 2013-04-09 17:33:54.325322046 +0200 >> +++ compat-wireless-2012-09-07/drivers/net/wireless/b43/main.c >> 2013-04-09 18:08:01.011471215 +0200 >> @@ -1894,14 +1894,6 @@ >> b43_controller_restart(dev, "DMA error"); >> return; >> } >> - if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) { >> - b43err(dev->wl, "DMA error: " >> - "0x%08X, 0x%08X, 0x%08X, " >> - "0x%08X, 0x%08X, 0x%08X\n", >> - dma_reason[0], dma_reason[1], >> - dma_reason[2], dma_reason[3], >> - dma_reason[4], dma_reason[5]); >> - } > > You should say why you remove this one, and you should remove the > B43_DMAIRQ_NONFATALMASK from the if (unlikely()) enclosing it. > >> } >> >> if (unlikely(reason & B43_IRQ_UCODE_DEBUG)) >> @@ -1920,6 +1912,14 @@ >> handle_irq_noise(dev); >> >> /* Check the DMA reason registers for received data. */ >> + if (dma_reason[0] & B43_DMAIRQ_RDESC_UFLOW) { >> + //only print 256 time to not flood log >> + if(!(dev->stats.rxdesc_underruns++&0xFF)){ >> + b43warn(dev->wl, "Rx descriptor underrun >> (high cpu load?), throwing packets\n"); > > Apart from the style problems, maybe doing a > if (printk_ratelimit()) > b43warn(...); > > which will ensure that it won't flood the log, but still won't stop > reporting them after the 256th time. > > >> + } >> + b43_dma_rx_discard(dev->dma.rx_ring); >> + >> + } >> if (dma_reason[0] & B43_DMAIRQ_RX_DONE) { >> if (b43_using_pio_transfers(dev)) >> b43_pio_rx(dev->pio.rx_queue); >> @@ -1977,7 +1977,7 @@ >> return IRQ_NONE; >> >> dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON) >> - & 0x0001DC00; >> + & 0x0001FC00; >> dev->dma_reason[1] = b43_read32(dev, B43_MMIO_DMA1_REASON) >> & 0x0000DC00; >> dev->dma_reason[2] = b43_read32(dev, B43_MMIO_DMA2_REASON) >> @@ -3081,7 +3081,7 @@ >> b43_write32(dev, 0x018C, 0x02000000); >> } >> b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, 0x00004000); >> - b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001DC00); >> + b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001FC00); >> b43_write32(dev, B43_MMIO_DMA1_IRQ_MASK, 0x0000DC00); >> b43_write32(dev, B43_MMIO_DMA2_IRQ_MASK, 0x0000DC00); >> b43_write32(dev, B43_MMIO_DMA3_IRQ_MASK, 0x0001DC00); >> >> =================================================================== >> --- compat-wireless-2012-09-07.orig/drivers/net/wireless/b43/b43.h >> 2013-04-09 17:04:51.552680190 +0200 >> +++ compat-wireless-2012-09-07/drivers/net/wireless/b43/b43.h >> 2013-04-09 17:46:08.472962612 +0200 >> @@ -671,6 +671,7 @@ >> >> struct b43_stats { >> u8 link_noise; >> + u32 rxdesc_underruns; >> }; >> >> struct b43_key { Chris, With this patch, can the number of RX descriptors be reduced back to 64 on your system? I realize it will be be hard to apply with the white space errors and line wraps, but perhaps we will get a clean version soon. Larry ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-19 18:17 ` Larry Finger @ 2013-04-19 18:57 ` Michael Büsch 2013-04-19 20:37 ` Thommy Jakobsson 0 siblings, 1 reply; 45+ messages in thread From: Michael Büsch @ 2013-04-19 18:57 UTC (permalink / raw) To: b43-dev On Fri, 19 Apr 2013 13:17:03 -0500 Larry Finger <Larry.Finger@lwfinger.net> wrote: > With this patch, can the number of RX descriptors be reduced back to 64 on your > system? I realize it will be be hard to apply with the white space errors and > line wraps, but perhaps we will get a clean version soon. It would be good to lower the number of RX descriptors as low as possible. Maybe even lower than 64. We should do more tests on that. That certainly could improve performance on low-end devices. -- Michael -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: not available URL: <http://lists.infradead.org/pipermail/b43-dev/attachments/20130419/fe2ab06e/attachment.sig> ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-19 18:57 ` Michael Büsch @ 2013-04-19 20:37 ` Thommy Jakobsson 2013-04-19 20:46 ` Michael Büsch 0 siblings, 1 reply; 45+ messages in thread From: Thommy Jakobsson @ 2013-04-19 20:37 UTC (permalink / raw) To: b43-dev As I mentioned in the original post I lowered it to 16 on my system without any problem (and I'm still running like that). I think that was perhaps a bit too low though, didn't do any real measurements but it felt like it cut off every other burst coming in. But I guess that also depends on the target system. //Thommy On Fri, Apr 19, 2013 at 8:57 PM, Michael B?sch <m@bues.ch> wrote: > On Fri, 19 Apr 2013 13:17:03 -0500 > Larry Finger <Larry.Finger@lwfinger.net> wrote: > >> With this patch, can the number of RX descriptors be reduced back to 64 on your >> system? I realize it will be be hard to apply with the white space errors and >> line wraps, but perhaps we will get a clean version soon. > > It would be good to lower the number of RX descriptors as low as possible. > Maybe even lower than 64. We should do more tests on that. > That certainly could improve performance on low-end devices. > > -- > Michael ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-19 20:37 ` Thommy Jakobsson @ 2013-04-19 20:46 ` Michael Büsch 2013-04-19 21:05 ` Larry Finger 0 siblings, 1 reply; 45+ messages in thread From: Michael Büsch @ 2013-04-19 20:46 UTC (permalink / raw) To: b43-dev On Fri, 19 Apr 2013 22:37:28 +0200 Thommy Jakobsson <thommyj@gmail.com> wrote: > As I mentioned in the original post I lowered it to 16 on my system > without any problem (and I'm still running like that). I think that > was perhaps a bit too low though, didn't do any real measurements but > it felt like it cut off every other burst coming in. But I guess that > also depends on the target system. Yes 16 sounds a little low, but 32 could be a good idea to test. -- Michael -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: not available URL: <http://lists.infradead.org/pipermail/b43-dev/attachments/20130419/18347906/attachment.sig> ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-19 20:46 ` Michael Büsch @ 2013-04-19 21:05 ` Larry Finger 0 siblings, 0 replies; 45+ messages in thread From: Larry Finger @ 2013-04-19 21:05 UTC (permalink / raw) To: b43-dev On 04/19/2013 03:46 PM, Michael B?sch wrote: > On Fri, 19 Apr 2013 22:37:28 +0200 > Thommy Jakobsson <thommyj@gmail.com> wrote: > >> As I mentioned in the original post I lowered it to 16 on my system >> without any problem (and I'm still running like that). I think that >> was perhaps a bit too low though, didn't do any real measurements but >> it felt like it cut off every other burst coming in. But I guess that >> also depends on the target system. > > Yes 16 sounds a little low, but 32 could be a good idea to test. I agree. Larry ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-19 14:32 ` Jonas Gorski 2013-04-19 15:55 ` Michael Büsch 2013-04-19 18:17 ` Larry Finger @ 2013-04-19 20:30 ` Thommy Jakobsson 2013-04-20 14:14 ` Thommy 3 siblings, 0 replies; 45+ messages in thread From: Thommy Jakobsson @ 2013-04-19 20:30 UTC (permalink / raw) To: b43-dev Hi Jonas, thanks for input. As you see I'm not used to send in patches, but I'll give it a new shot as soon as I succeed to download and patch the latest git tree. Otherwise see my comments inline //Thommy On Fri, Apr 19, 2013 at 4:32 PM, Jonas Gorski <jonas.gorski@gmail.com> wrote: > Hi, > > On Mon, Apr 15, 2013 at 10:02 AM, Thommy Jakobsson <thommyj@gmail.com> wrote: >> Hi, >> >> long user of b43 driver under openwrt. Not sure if it has been posted >> previously but using slow and old hardware (as routers running openwrt >> most of the time is), the CPU is sometimes slower than the NIC. So >> recently I, and several others, has had problem of wifi going down. >> See ticket 7552 at openwrt for more info >> (https://dev.openwrt.org/ticket/7552) >> >> I have tracked down the problem to the nic getting into a rx >> descriptor underrun. Since the driver don't listen to that (or take >> care of it in any other way), the Wifi seemingly just dies. The CPU is >> waiting for data from the nic and the nic is waiting for a >> confirmation that it can keep sending. >> >> I created a patch for handling of that interrupt. I have tested it by >> reducing the number of rx slots to 16 and sending a couple of 100GB of >> data. Previously Wifi went down within a minute when maxing out the >> uplink (so rx for AP), now it has been working flawless for a 1.5week. > > Nice, very good to hear. Looks like you found the real issue the rx > descriptor count increase was just papering over. Some comments > regarding your patch. > >> >> BR, >> Thommy Jakobsson >> > > You are missing a "Signed-off-by" - without it the patch can never be > accepted. Also your patch is has broken tabs (they were converted to > spaces), as well as is line-broken, so it doesn't apply anymore. You > can't use gmail's web interface for sending patches. > >> Index: drivers/net/wireless/b43/dma.c >> =================================================================== >> --- compat-wireless-2012-09-07.orig/drivers/net/wireless/b43/dma.c >> 2013-04-09 17:33:54.325322046 +0200 >> +++ compat-wireless-2012-09-07/drivers/net/wireless/b43/dma.c > > You should make your patch against the newest git tree, so usually > wireless-testing or Rafa?'s b43-next. > >> 2013-04-09 17:34:43.473565843 +0200 >> @@ -1688,6 +1688,21 @@ >> b43_poison_rx_buffer(ring, skb); >> sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize); >> } >> +void b43_dma_rx_discard(struct b43_dmaring *ring) >> +{ >> + B43_WARN_ON(ring->tx); >> + >> + /* Device has filled all buffers, drop all packets in buffers >> + * and let TCP decrease speed. >> + * Set index to one desc after the last one (which is marked) >> + * so the device will see all slots as free again >> + */ >> + /* >> + *TODO: How to increase rx_drop in mac80211 >> + */ >> + b43_dma_write(ring, B43_DMA32_RXINDEX, ring->nr_slots * >> + sizeof(struct b43_dmadesc32)); >> +} >> >> void b43_dma_rx(struct b43_dmaring *ring) >> { >> >> Index: drivers/net/wireless/b43/dma.h >> =================================================================== >> --- compat-wireless-2012-09-07.orig/drivers/net/wireless/b43/dma.h >> 2013-04-09 17:34:09.561397686 +0200 >> +++ compat-wireless-2012-09-07/drivers/net/wireless/b43/dma.h >> 2013-04-09 17:34:43.461565780 +0200 >> @@ -10,7 +10,8 @@ >> #define B43_DMAIRQ_FATALMASK ((1 << 10) | (1 << 11) | (1 << 12) \ >> | (1 << 14) | (1 << 15)) >> #define B43_DMAIRQ_NONFATALMASK (1 << 13) >> -#define B43_DMAIRQ_RX_DONE (1 << 16) >> +#define B43_DMAIRQ_RX_DONE (1 << 16) > > Unnecessary whitespace change. > >> +#define B43_DMAIRQ_RDESC_UFLOW (1 << 13) > > Why not just rename B43_DMAIRQ_NONFATALMASK ? > >> >> /*** 32-bit DMA Engine. ***/ >> >> @@ -295,6 +296,8 @@ >> void b43_dma_handle_txstatus(struct b43_wldev *dev, >> const struct b43_txstatus *status); >> >> +void b43_dma_rx_discard(struct b43_dmaring *ring); >> + >> void b43_dma_rx(struct b43_dmaring *ring); >> >> void b43_dma_direct_fifo_rx(struct b43_wldev *dev, >> >> Index: drivers/net/wireless/b43/main.c >> =================================================================== >> --- compat-wireless-2012-09-07.orig/drivers/net/wireless/b43/main.c >> 2013-04-09 17:33:54.325322046 +0200 >> +++ compat-wireless-2012-09-07/drivers/net/wireless/b43/main.c >> 2013-04-09 18:08:01.011471215 +0200 >> @@ -1894,14 +1894,6 @@ >> b43_controller_restart(dev, "DMA error"); >> return; >> } >> - if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) { >> - b43err(dev->wl, "DMA error: " >> - "0x%08X, 0x%08X, 0x%08X, " >> - "0x%08X, 0x%08X, 0x%08X\n", >> - dma_reason[0], dma_reason[1], >> - dma_reason[2], dma_reason[3], >> - dma_reason[4], dma_reason[5]); >> - } > > You should say why you remove this one, and you should remove the > B43_DMAIRQ_NONFATALMASK from the if (unlikely()) enclosing it. [thommy]: I removed it because I didn't want to have a printout each time some non fatal happened. That would mean a printout every time a rx descriptor underrun would happen. Also the printout says "DMA error", which sounds very serious when in fact it isn't (or not in my opinion anyway). > >> } >> >> if (unlikely(reason & B43_IRQ_UCODE_DEBUG)) >> @@ -1920,6 +1912,14 @@ >> handle_irq_noise(dev); >> >> /* Check the DMA reason registers for received data. */ >> + if (dma_reason[0] & B43_DMAIRQ_RDESC_UFLOW) { >> + //only print 256 time to not flood log >> + if(!(dev->stats.rxdesc_underruns++&0xFF)){ >> + b43warn(dev->wl, "Rx descriptor underrun >> (high cpu load?), throwing packets\n"); > > Apart from the style problems, maybe doing a > if (printk_ratelimit()) > b43warn(...); > > which will ensure that it won't flood the log, but still won't stop > reporting them after the 256th time. [thommy]: My comment in the code is wrong. The meaning was to print it every 256th time it happens, not to only to print the 256 first times. As it seems from other messages there are better way of rate limiting that I was unaware of. > > >> + } >> + b43_dma_rx_discard(dev->dma.rx_ring); >> + >> + } >> if (dma_reason[0] & B43_DMAIRQ_RX_DONE) { >> if (b43_using_pio_transfers(dev)) >> b43_pio_rx(dev->pio.rx_queue); >> @@ -1977,7 +1977,7 @@ >> return IRQ_NONE; >> >> dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON) >> - & 0x0001DC00; >> + & 0x0001FC00; >> dev->dma_reason[1] = b43_read32(dev, B43_MMIO_DMA1_REASON) >> & 0x0000DC00; >> dev->dma_reason[2] = b43_read32(dev, B43_MMIO_DMA2_REASON) >> @@ -3081,7 +3081,7 @@ >> b43_write32(dev, 0x018C, 0x02000000); >> } >> b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, 0x00004000); >> - b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001DC00); >> + b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001FC00); >> b43_write32(dev, B43_MMIO_DMA1_IRQ_MASK, 0x0000DC00); >> b43_write32(dev, B43_MMIO_DMA2_IRQ_MASK, 0x0000DC00); >> b43_write32(dev, B43_MMIO_DMA3_IRQ_MASK, 0x0001DC00); >> >> =================================================================== >> --- compat-wireless-2012-09-07.orig/drivers/net/wireless/b43/b43.h >> 2013-04-09 17:04:51.552680190 +0200 >> +++ compat-wireless-2012-09-07/drivers/net/wireless/b43/b43.h >> 2013-04-09 17:46:08.472962612 +0200 >> @@ -671,6 +671,7 @@ >> >> struct b43_stats { >> u8 link_noise; >> + u32 rxdesc_underruns; >> }; >> >> struct b43_key { > > > Jonas ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-19 14:32 ` Jonas Gorski ` (2 preceding siblings ...) 2013-04-19 20:30 ` Thommy Jakobsson @ 2013-04-20 14:14 ` Thommy 2013-04-20 18:35 ` Larry Finger 2013-04-20 19:12 ` Michael Büsch 3 siblings, 2 replies; 45+ messages in thread From: Thommy @ 2013-04-20 14:14 UTC (permalink / raw) To: b43-dev Hi, new try sending in the patch (with pine instead of gmail webclient this time). Patch created on latest wireless-testing BR, Thommy Jakobsson Signed-off-by: Thommy Jakobsson <thommyj@gmail.com> --- drivers/net/wireless/b43/b43.h | 1 + drivers/net/wireless/b43/dma.c | 16 +++++++++++++++ drivers/net/wireless/b43/dma.h | 4 +++- drivers/net/wireless/b43/main.c | 43 ++++++++++++++++----------------------- 4 files changed, 38 insertions(+), 26 deletions(-) diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 7f3d461..fdcd00f 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -680,6 +680,7 @@ struct b43_noise_calculation { struct b43_stats { u8 link_noise; + u32 rxdesc_underruns; }; struct b43_key { diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 1221469..2ae00dd 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c @@ -1733,6 +1733,22 @@ drop_recycle_buffer: sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize); } +void b43_dma_rx_discard(struct b43_dmaring *ring) +{ + B43_WARN_ON(ring->tx); + + /* Device has filled all buffers, drop all packets in buffers + * and let TCP decrease speed. + * Set index to one desc after the last one + * so the device will see all slots as free again + */ + /* + *TODO: How to increase rx_drop in mac80211? + */ + b43_dma_write(ring, B43_DMA32_RXINDEX, ring->nr_slots * + sizeof(struct b43_dmadesc32)); +} + void b43_dma_rx(struct b43_dmaring *ring) { const struct b43_dma_ops *ops = ring->ops; diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h index 9fdd198..fed8163 100644 --- a/drivers/net/wireless/b43/dma.h +++ b/drivers/net/wireless/b43/dma.h @@ -9,7 +9,7 @@ /* DMA-Interrupt reasons. */ #define B43_DMAIRQ_FATALMASK ((1 << 10) | (1 << 11) | (1 << 12) \ | (1 << 14) | (1 << 15)) -#define B43_DMAIRQ_NONFATALMASK (1 << 13) +#define B43_DMAIRQ_RDESC_UFLOW (1 << 13) #define B43_DMAIRQ_RX_DONE (1 << 16) /*** 32-bit DMA Engine. ***/ @@ -295,6 +295,8 @@ int b43_dma_tx(struct b43_wldev *dev, void b43_dma_handle_txstatus(struct b43_wldev *dev, const struct b43_txstatus *status); +void b43_dma_rx_discard(struct b43_dmaring *ring); + void b43_dma_rx(struct b43_dmaring *ring); void b43_dma_direct_fifo_rx(struct b43_wldev *dev, diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index d377f77..277fe75 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -1902,30 +1902,19 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev) } } - if (unlikely(merged_dma_reason & (B43_DMAIRQ_FATALMASK | - B43_DMAIRQ_NONFATALMASK))) { - if (merged_dma_reason & B43_DMAIRQ_FATALMASK) { - b43err(dev->wl, "Fatal DMA error: " - "0x%08X, 0x%08X, 0x%08X, " - "0x%08X, 0x%08X, 0x%08X\n", - dma_reason[0], dma_reason[1], - dma_reason[2], dma_reason[3], - dma_reason[4], dma_reason[5]); - b43err(dev->wl, "This device does not support DMA " + if (unlikely(merged_dma_reason & (B43_DMAIRQ_FATALMASK))) { + b43err(dev->wl, "Fatal DMA error: " + "0x%08X, 0x%08X, 0x%08X, " + "0x%08X, 0x%08X, 0x%08X\n", + dma_reason[0], dma_reason[1], + dma_reason[2], dma_reason[3], + dma_reason[4], dma_reason[5]); + b43err(dev->wl, "This device does not support DMA " "on your system. It will now be switched to PIO.\n"); - /* Fall back to PIO transfers if we get fatal DMA errors! */ - dev->use_pio = true; - b43_controller_restart(dev, "DMA error"); - return; - } - if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) { - b43err(dev->wl, "DMA error: " - "0x%08X, 0x%08X, 0x%08X, " - "0x%08X, 0x%08X, 0x%08X\n", - dma_reason[0], dma_reason[1], - dma_reason[2], dma_reason[3], - dma_reason[4], dma_reason[5]); - } + /* Fall back to PIO transfers if we get fatal DMA errors! */ + dev->use_pio = true; + b43_controller_restart(dev, "DMA error"); + return; } if (unlikely(reason & B43_IRQ_UCODE_DEBUG)) @@ -1944,6 +1933,10 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev) handle_irq_noise(dev); /* Check the DMA reason registers for received data. */ + if (dma_reason[0] & B43_DMAIRQ_RDESC_UFLOW) { + b43warn(dev->wl, "RX descriptor underrun, dropping packets\n"); + b43_dma_rx_discard(dev->dma.rx_ring); + } if (dma_reason[0] & B43_DMAIRQ_RX_DONE) { if (b43_using_pio_transfers(dev)) b43_pio_rx(dev->pio.rx_queue); @@ -2001,7 +1994,7 @@ static irqreturn_t b43_do_interrupt(struct b43_wldev *dev) return IRQ_NONE; dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON) - & 0x0001DC00; + & 0x0001FC00; dev->dma_reason[1] = b43_read32(dev, B43_MMIO_DMA1_REASON) & 0x0000DC00; dev->dma_reason[2] = b43_read32(dev, B43_MMIO_DMA2_REASON) @@ -3130,7 +3123,7 @@ static int b43_chip_init(struct b43_wldev *dev) b43_write32(dev, 0x018C, 0x02000000); } b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, 0x00004000); - b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001DC00); + b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001FC00); b43_write32(dev, B43_MMIO_DMA1_IRQ_MASK, 0x0000DC00); b43_write32(dev, B43_MMIO_DMA2_IRQ_MASK, 0x0000DC00); b43_write32(dev, B43_MMIO_DMA3_IRQ_MASK, 0x0001DC00); -- 1.7.9.5 On Fri, 19 Apr 2013, Jonas Gorski wrote: > Hi, > > On Mon, Apr 15, 2013 at 10:02 AM, Thommy Jakobsson <thommyj@gmail.com> wrote: > > Hi, > > > > long user of b43 driver under openwrt. Not sure if it has been posted > > previously but using slow and old hardware (as routers running openwrt > > most of the time is), the CPU is sometimes slower than the NIC. So > > recently I, and several others, has had problem of wifi going down. > > See ticket 7552 at openwrt for more info > > (https://dev.openwrt.org/ticket/7552) > > > > I have tracked down the problem to the nic getting into a rx > > descriptor underrun. Since the driver don't listen to that (or take > > care of it in any other way), the Wifi seemingly just dies. The CPU is > > waiting for data from the nic and the nic is waiting for a > > confirmation that it can keep sending. > > > > I created a patch for handling of that interrupt. I have tested it by > > reducing the number of rx slots to 16 and sending a couple of 100GB of > > data. Previously Wifi went down within a minute when maxing out the > > uplink (so rx for AP), now it has been working flawless for a 1.5week. > > Nice, very good to hear. Looks like you found the real issue the rx > descriptor count increase was just papering over. Some comments > regarding your patch. > > > > > BR, > > Thommy Jakobsson > > > > You are missing a "Signed-off-by" - without it the patch can never be > accepted. Also your patch is has broken tabs (they were converted to > spaces), as well as is line-broken, so it doesn't apply anymore. You > can't use gmail's web interface for sending patches. > > > Index: drivers/net/wireless/b43/dma.c > > =================================================================== > > --- compat-wireless-2012-09-07.orig/drivers/net/wireless/b43/dma.c > > 2013-04-09 17:33:54.325322046 +0200 > > +++ compat-wireless-2012-09-07/drivers/net/wireless/b43/dma.c > > You should make your patch against the newest git tree, so usually > wireless-testing or Rafa?'s b43-next. > > > 2013-04-09 17:34:43.473565843 +0200 > > @@ -1688,6 +1688,21 @@ > > b43_poison_rx_buffer(ring, skb); > > sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize); > > } > > +void b43_dma_rx_discard(struct b43_dmaring *ring) > > +{ > > + B43_WARN_ON(ring->tx); > > + > > + /* Device has filled all buffers, drop all packets in buffers > > + * and let TCP decrease speed. > > + * Set index to one desc after the last one (which is marked) > > + * so the device will see all slots as free again > > + */ > > + /* > > + *TODO: How to increase rx_drop in mac80211 > > + */ > > + b43_dma_write(ring, B43_DMA32_RXINDEX, ring->nr_slots * > > + sizeof(struct b43_dmadesc32)); > > +} > > > > void b43_dma_rx(struct b43_dmaring *ring) > > { > > > > Index: drivers/net/wireless/b43/dma.h > > =================================================================== > > --- compat-wireless-2012-09-07.orig/drivers/net/wireless/b43/dma.h > > 2013-04-09 17:34:09.561397686 +0200 > > +++ compat-wireless-2012-09-07/drivers/net/wireless/b43/dma.h > > 2013-04-09 17:34:43.461565780 +0200 > > @@ -10,7 +10,8 @@ > > #define B43_DMAIRQ_FATALMASK ((1 << 10) | (1 << 11) | (1 << 12) \ > > | (1 << 14) | (1 << 15)) > > #define B43_DMAIRQ_NONFATALMASK (1 << 13) > > -#define B43_DMAIRQ_RX_DONE (1 << 16) > > +#define B43_DMAIRQ_RX_DONE (1 << 16) > > Unnecessary whitespace change. > > > +#define B43_DMAIRQ_RDESC_UFLOW (1 << 13) > > Why not just rename B43_DMAIRQ_NONFATALMASK ? > > > > > /*** 32-bit DMA Engine. ***/ > > > > @@ -295,6 +296,8 @@ > > void b43_dma_handle_txstatus(struct b43_wldev *dev, > > const struct b43_txstatus *status); > > > > +void b43_dma_rx_discard(struct b43_dmaring *ring); > > + > > void b43_dma_rx(struct b43_dmaring *ring); > > > > void b43_dma_direct_fifo_rx(struct b43_wldev *dev, > > > > Index: drivers/net/wireless/b43/main.c > > =================================================================== > > --- compat-wireless-2012-09-07.orig/drivers/net/wireless/b43/main.c > > 2013-04-09 17:33:54.325322046 +0200 > > +++ compat-wireless-2012-09-07/drivers/net/wireless/b43/main.c > > 2013-04-09 18:08:01.011471215 +0200 > > @@ -1894,14 +1894,6 @@ > > b43_controller_restart(dev, "DMA error"); > > return; > > } > > - if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) { > > - b43err(dev->wl, "DMA error: " > > - "0x%08X, 0x%08X, 0x%08X, " > > - "0x%08X, 0x%08X, 0x%08X\n", > > - dma_reason[0], dma_reason[1], > > - dma_reason[2], dma_reason[3], > > - dma_reason[4], dma_reason[5]); > > - } > > You should say why you remove this one, and you should remove the > B43_DMAIRQ_NONFATALMASK from the if (unlikely()) enclosing it. > > > } > > > > if (unlikely(reason & B43_IRQ_UCODE_DEBUG)) > > @@ -1920,6 +1912,14 @@ > > handle_irq_noise(dev); > > > > /* Check the DMA reason registers for received data. */ > > + if (dma_reason[0] & B43_DMAIRQ_RDESC_UFLOW) { > > + //only print 256 time to not flood log > > + if(!(dev->stats.rxdesc_underruns++&0xFF)){ > > + b43warn(dev->wl, "Rx descriptor underrun > > (high cpu load?), throwing packets\n"); > > Apart from the style problems, maybe doing a > if (printk_ratelimit()) > b43warn(...); > > which will ensure that it won't flood the log, but still won't stop > reporting them after the 256th time. > > > > + } > > + b43_dma_rx_discard(dev->dma.rx_ring); > > + > > + } > > if (dma_reason[0] & B43_DMAIRQ_RX_DONE) { > > if (b43_using_pio_transfers(dev)) > > b43_pio_rx(dev->pio.rx_queue); > > @@ -1977,7 +1977,7 @@ > > return IRQ_NONE; > > > > dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON) > > - & 0x0001DC00; > > + & 0x0001FC00; > > dev->dma_reason[1] = b43_read32(dev, B43_MMIO_DMA1_REASON) > > & 0x0000DC00; > > dev->dma_reason[2] = b43_read32(dev, B43_MMIO_DMA2_REASON) > > @@ -3081,7 +3081,7 @@ > > b43_write32(dev, 0x018C, 0x02000000); > > } > > b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, 0x00004000); > > - b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001DC00); > > + b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001FC00); > > b43_write32(dev, B43_MMIO_DMA1_IRQ_MASK, 0x0000DC00); > > b43_write32(dev, B43_MMIO_DMA2_IRQ_MASK, 0x0000DC00); > > b43_write32(dev, B43_MMIO_DMA3_IRQ_MASK, 0x0001DC00); > > > > =================================================================== > > --- compat-wireless-2012-09-07.orig/drivers/net/wireless/b43/b43.h > > 2013-04-09 17:04:51.552680190 +0200 > > +++ compat-wireless-2012-09-07/drivers/net/wireless/b43/b43.h > > 2013-04-09 17:46:08.472962612 +0200 > > @@ -671,6 +671,7 @@ > > > > struct b43_stats { > > u8 link_noise; > > + u32 rxdesc_underruns; > > }; > > > > struct b43_key { > > > Jonas > ^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-20 14:14 ` Thommy @ 2013-04-20 18:35 ` Larry Finger 2013-04-20 22:47 ` Thommy Jakobsson 2013-04-20 19:12 ` Michael Büsch 1 sibling, 1 reply; 45+ messages in thread From: Larry Finger @ 2013-04-20 18:35 UTC (permalink / raw) To: b43-dev On 04/20/2013 09:14 AM, Thommy wrote: > Hi, > > new try sending in the patch (with pine instead of gmail webclient this > time). Patch created on latest wireless-testing > > BR, > Thommy Jakobsson > > Signed-off-by: Thommy Jakobsson <thommyj@gmail.com> > --- > drivers/net/wireless/b43/b43.h | 1 + > drivers/net/wireless/b43/dma.c | 16 +++++++++++++++ > drivers/net/wireless/b43/dma.h | 4 +++- > drivers/net/wireless/b43/main.c | 43 ++++++++++++++++----------------------- > 4 files changed, 38 insertions(+), 26 deletions(-) > > diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h > index 7f3d461..fdcd00f 100644 > --- a/drivers/net/wireless/b43/b43.h > +++ b/drivers/net/wireless/b43/b43.h > @@ -680,6 +680,7 @@ struct b43_noise_calculation { > > struct b43_stats { > u8 link_noise; > + u32 rxdesc_underruns; > }; > > struct b43_key { > diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c > index 1221469..2ae00dd 100644 > --- a/drivers/net/wireless/b43/dma.c > +++ b/drivers/net/wireless/b43/dma.c > @@ -1733,6 +1733,22 @@ drop_recycle_buffer: > sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize); > } > > +void b43_dma_rx_discard(struct b43_dmaring *ring) > +{ > + B43_WARN_ON(ring->tx); > + > + /* Device has filled all buffers, drop all packets in buffers > + * and let TCP decrease speed. > + * Set index to one desc after the last one > + * so the device will see all slots as free again > + */ > + /* > + *TODO: How to increase rx_drop in mac80211? > + */ > + b43_dma_write(ring, B43_DMA32_RXINDEX, ring->nr_slots * > + sizeof(struct b43_dmadesc32)); > +} > + > void b43_dma_rx(struct b43_dmaring *ring) > { > const struct b43_dma_ops *ops = ring->ops; > diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h > index 9fdd198..fed8163 100644 > --- a/drivers/net/wireless/b43/dma.h > +++ b/drivers/net/wireless/b43/dma.h > @@ -9,7 +9,7 @@ > /* DMA-Interrupt reasons. */ > #define B43_DMAIRQ_FATALMASK ((1 << 10) | (1 << 11) | (1 << 12) \ > | (1 << 14) | (1 << 15)) > -#define B43_DMAIRQ_NONFATALMASK (1 << 13) > +#define B43_DMAIRQ_RDESC_UFLOW (1 << 13) > #define B43_DMAIRQ_RX_DONE (1 << 16) > > /*** 32-bit DMA Engine. ***/ > @@ -295,6 +295,8 @@ int b43_dma_tx(struct b43_wldev *dev, > void b43_dma_handle_txstatus(struct b43_wldev *dev, > const struct b43_txstatus *status); > > +void b43_dma_rx_discard(struct b43_dmaring *ring); > + > void b43_dma_rx(struct b43_dmaring *ring); > > void b43_dma_direct_fifo_rx(struct b43_wldev *dev, > diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c > index d377f77..277fe75 100644 > --- a/drivers/net/wireless/b43/main.c > +++ b/drivers/net/wireless/b43/main.c > @@ -1902,30 +1902,19 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev) > } > } > > - if (unlikely(merged_dma_reason & (B43_DMAIRQ_FATALMASK | > - B43_DMAIRQ_NONFATALMASK))) { > - if (merged_dma_reason & B43_DMAIRQ_FATALMASK) { > - b43err(dev->wl, "Fatal DMA error: " > - "0x%08X, 0x%08X, 0x%08X, " > - "0x%08X, 0x%08X, 0x%08X\n", > - dma_reason[0], dma_reason[1], > - dma_reason[2], dma_reason[3], > - dma_reason[4], dma_reason[5]); > - b43err(dev->wl, "This device does not support DMA " > + if (unlikely(merged_dma_reason & (B43_DMAIRQ_FATALMASK))) { > + b43err(dev->wl, "Fatal DMA error: " > + "0x%08X, 0x%08X, 0x%08X, " > + "0x%08X, 0x%08X, 0x%08X\n", > + dma_reason[0], dma_reason[1], > + dma_reason[2], dma_reason[3], > + dma_reason[4], dma_reason[5]); > + b43err(dev->wl, "This device does not support DMA " > "on your system. It will now be switched to PIO.\n"); > - /* Fall back to PIO transfers if we get fatal DMA errors! */ > - dev->use_pio = true; > - b43_controller_restart(dev, "DMA error"); > - return; > - } > - if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) { > - b43err(dev->wl, "DMA error: " > - "0x%08X, 0x%08X, 0x%08X, " > - "0x%08X, 0x%08X, 0x%08X\n", > - dma_reason[0], dma_reason[1], > - dma_reason[2], dma_reason[3], > - dma_reason[4], dma_reason[5]); > - } > + /* Fall back to PIO transfers if we get fatal DMA errors! */ > + dev->use_pio = true; > + b43_controller_restart(dev, "DMA error"); > + return; > } > > if (unlikely(reason & B43_IRQ_UCODE_DEBUG)) > @@ -1944,6 +1933,10 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev) > handle_irq_noise(dev); > > /* Check the DMA reason registers for received data. */ > + if (dma_reason[0] & B43_DMAIRQ_RDESC_UFLOW) { > + b43warn(dev->wl, "RX descriptor underrun, dropping packets\n"); > + b43_dma_rx_discard(dev->dma.rx_ring); > + } > if (dma_reason[0] & B43_DMAIRQ_RX_DONE) { > if (b43_using_pio_transfers(dev)) > b43_pio_rx(dev->pio.rx_queue); > @@ -2001,7 +1994,7 @@ static irqreturn_t b43_do_interrupt(struct b43_wldev *dev) > return IRQ_NONE; > > dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON) > - & 0x0001DC00; > + & 0x0001FC00; > dev->dma_reason[1] = b43_read32(dev, B43_MMIO_DMA1_REASON) > & 0x0000DC00; > dev->dma_reason[2] = b43_read32(dev, B43_MMIO_DMA2_REASON) > @@ -3130,7 +3123,7 @@ static int b43_chip_init(struct b43_wldev *dev) > b43_write32(dev, 0x018C, 0x02000000); > } > b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, 0x00004000); > - b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001DC00); > + b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001FC00); > b43_write32(dev, B43_MMIO_DMA1_IRQ_MASK, 0x0000DC00); > b43_write32(dev, B43_MMIO_DMA2_IRQ_MASK, 0x0000DC00); > b43_write32(dev, B43_MMIO_DMA3_IRQ_MASK, 0x0001DC00); Thommy, This version did apply cleanly; however, there are still a couple of things that need fixing. With scripts/checkpatch.pl, there is a warning that a quoted string is split over two lines. Although testing for that condition is a recent addition to the script, it is probably best to honor that requirement with new code. To do so, the lines starting at 1907 in main.c should be b43err(dev->wl, "Fatal DMA error: 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X\n", My mailer will likely wrap the string, but ignore that. Yes, that line is longer than 80 characters, but that is OK for quoted strings. The idea is that if they are not split, it is easier to grep for them. In this case, that is not an issue, but I prefer to make all new code be free of errors, warnings, and checks. Your subject and commit message are not appropriate. Have you read Documentation/SubmittingPatches? The info you have at the start would not be appropriate for the permanent kernel record. If you want to add such informal remarks, include a line with --- after the formal commit message, and place informal remarks below that line. Everything is available at patch submission time, but the scripts strip it off before it is included in the git repositories. The b43-dev list is OK for discussions of the patch, but the final patch needs to be sent to John Linville <linville@tuxdriver.com>, with Cc: to b43-dev, and the linux-wireless mailing list <linux-wireless@vger.kernel.org>. When the patch is appropriate for backporting to earlier, stable kernels, and this one certainly fits that criterion, follow the "Signed-off-by" line with one that says "Cc: Stable <stable@vger.kernel.org>". That way, the patch will automatically be included in earlier versions as soon as it is incorporated in the mainline version (Linus's tree). Lastly, I have a question about the patch. Is it necessary to log every underrun? Perhaps you might want to place the b43_warn statement inside an "if (B43_DEBUG)" conditional. That way the condition will be logged for people really interested in debugging the driver, but the general user of a distro kernel will never see the message. Thanks for finding this issue. Larry ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-20 18:35 ` Larry Finger @ 2013-04-20 22:47 ` Thommy Jakobsson 0 siblings, 0 replies; 45+ messages in thread From: Thommy Jakobsson @ 2013-04-20 22:47 UTC (permalink / raw) To: b43-dev On Sat, 20 Apr 2013, Larry Finger wrote: > Thommy, > > This version did apply cleanly; however, there are still a couple of things > that need fixing. > > With scripts/checkpatch.pl, there is a warning that a quoted string is split > over two lines. Although testing for that condition is a recent addition to > the script, it is probably best to honor that requirement with new code. To do > so, the lines starting at 1907 in main.c should be > > b43err(dev->wl, > "Fatal DMA error: 0x%08X, 0x%08X, 0x%08X, 0x%08X, > 0x%08X, 0x%08X\n", > > My mailer will likely wrap the string, but ignore that. Yes, that line is > longer than 80 characters, but that is OK for quoted strings. The idea is that > if they are not split, it is easier to grep for them. In this case, that is > not an issue, but I prefer to make all new code be free of errors, warnings, > and checks. > > Your subject and commit message are not appropriate. Have you read > Documentation/SubmittingPatches? The info you have at the start would not be > appropriate for the permanent kernel record. If you want to add such informal > remarks, include a line with --- after the formal commit message, and place > informal remarks below that line. Everything is available at patch submission > time, but the scripts strip it off before it is included in the git > repositories. The b43-dev list is OK for discussions of the patch, but the > final patch needs to be sent to John Linville <linville@tuxdriver.com>, with > Cc: to b43-dev, and the linux-wireless mailing list > <linux-wireless@vger.kernel.org>. > > When the patch is appropriate for backporting to earlier, stable kernels, and > this one certainly fits that criterion, follow the "Signed-off-by" line with > one that says "Cc: Stable <stable@vger.kernel.org>". That way, the patch will > automatically be included in earlier versions as soon as it is incorporated in > the mainline version (Linus's tree). > > Lastly, I have a question about the patch. Is it necessary to log every > underrun? Perhaps you might want to place the b43_warn statement inside an "if > (B43_DEBUG)" conditional. That way the condition will be logged for people > really interested in debugging the driver, but the general user of a distro > kernel will never see the message. > > Thanks for finding this issue. > > Larry > > New try, think I have fixed everything but have probably missed something. If not Piotras or someone else find a better way I planned to send this in to John. Subject:[PATCH] B43: Handle DMA RX descriptor underrun From: Thommy Jakobsson <thommyj@gmail.com> Add handling of rx descriptor underflow. This fixes a fault that could happen on slow machines, where data is received faster than the CPU can handle. In such a case the device will use up all rx descriptors and refuse to send any more data before confirming that it is ok. This patch enables necessary interrupt to discover such a situation and will handle them by dropping everything in the ring buffer. Signed-off-by: Thommy Jakobsson <thommyj@gmail.com> Cc: Stable <stable@vger.kernel.org> --- drivers/net/wireless/b43/b43.h | 1 + drivers/net/wireless/b43/dma.c | 15 ++++++++++++++ drivers/net/wireless/b43/dma.h | 4 +++- drivers/net/wireless/b43/main.c | 43 ++++++++++++++++----------------------- 4 files changed, 37 insertions(+), 26 deletions(-) diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 7f3d461..fdcd00f 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -680,6 +680,7 @@ struct b43_noise_calculation { struct b43_stats { u8 link_noise; + u32 rxdesc_underruns; }; struct b43_key { diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 1221469..df929b3 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c @@ -1733,6 +1733,21 @@ drop_recycle_buffer: sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize); } +void b43_dma_rx_discard(struct b43_dmaring *ring) +{ + B43_WARN_ON(ring->tx); + + /* Device has filled all buffers, drop all packets in buffers + * and let TCP decrease speed. + * Set index to one desc after the last one + * so the device will see all slots as free again + */ + /* + *TODO: How to increase rx_drop in mac80211? + */ + ring->ops->set_current_rxslot(ring, ring->nr_slots); +} + void b43_dma_rx(struct b43_dmaring *ring) { const struct b43_dma_ops *ops = ring->ops; diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h index 9fdd198..fed8163 100644 --- a/drivers/net/wireless/b43/dma.h +++ b/drivers/net/wireless/b43/dma.h @@ -9,7 +9,7 @@ /* DMA-Interrupt reasons. */ #define B43_DMAIRQ_FATALMASK ((1 << 10) | (1 << 11) | (1 << 12) \ | (1 << 14) | (1 << 15)) -#define B43_DMAIRQ_NONFATALMASK (1 << 13) +#define B43_DMAIRQ_RDESC_UFLOW (1 << 13) #define B43_DMAIRQ_RX_DONE (1 << 16) /*** 32-bit DMA Engine. ***/ @@ -295,6 +295,8 @@ int b43_dma_tx(struct b43_wldev *dev, void b43_dma_handle_txstatus(struct b43_wldev *dev, const struct b43_txstatus *status); +void b43_dma_rx_discard(struct b43_dmaring *ring); + void b43_dma_rx(struct b43_dmaring *ring); void b43_dma_direct_fifo_rx(struct b43_wldev *dev, diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index d377f77..5662f18 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -1902,30 +1902,18 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev) } } - if (unlikely(merged_dma_reason & (B43_DMAIRQ_FATALMASK | - B43_DMAIRQ_NONFATALMASK))) { - if (merged_dma_reason & B43_DMAIRQ_FATALMASK) { - b43err(dev->wl, "Fatal DMA error: " - "0x%08X, 0x%08X, 0x%08X, " - "0x%08X, 0x%08X, 0x%08X\n", - dma_reason[0], dma_reason[1], - dma_reason[2], dma_reason[3], - dma_reason[4], dma_reason[5]); - b43err(dev->wl, "This device does not support DMA " + if (unlikely(merged_dma_reason & (B43_DMAIRQ_FATALMASK))) { + b43err(dev->wl, + "Fatal DMA error: 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X\n", + dma_reason[0], dma_reason[1], + dma_reason[2], dma_reason[3], + dma_reason[4], dma_reason[5]); + b43err(dev->wl, "This device does not support DMA " "on your system. It will now be switched to PIO.\n"); - /* Fall back to PIO transfers if we get fatal DMA errors! */ - dev->use_pio = true; - b43_controller_restart(dev, "DMA error"); - return; - } - if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) { - b43err(dev->wl, "DMA error: " - "0x%08X, 0x%08X, 0x%08X, " - "0x%08X, 0x%08X, 0x%08X\n", - dma_reason[0], dma_reason[1], - dma_reason[2], dma_reason[3], - dma_reason[4], dma_reason[5]); - } + /* Fall back to PIO transfers if we get fatal DMA errors! */ + dev->use_pio = true; + b43_controller_restart(dev, "DMA error"); + return; } if (unlikely(reason & B43_IRQ_UCODE_DEBUG)) @@ -1944,6 +1932,11 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev) handle_irq_noise(dev); /* Check the DMA reason registers for received data. */ + if (dma_reason[0] & B43_DMAIRQ_RDESC_UFLOW) { + if (B43_DEBUG) + b43warn(dev->wl, "RX descriptor underrun\n"); + b43_dma_rx_discard(dev->dma.rx_ring); + } if (dma_reason[0] & B43_DMAIRQ_RX_DONE) { if (b43_using_pio_transfers(dev)) b43_pio_rx(dev->pio.rx_queue); @@ -2001,7 +1994,7 @@ static irqreturn_t b43_do_interrupt(struct b43_wldev *dev) return IRQ_NONE; dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON) - & 0x0001DC00; + & 0x0001FC00; dev->dma_reason[1] = b43_read32(dev, B43_MMIO_DMA1_REASON) & 0x0000DC00; dev->dma_reason[2] = b43_read32(dev, B43_MMIO_DMA2_REASON) @@ -3130,7 +3123,7 @@ static int b43_chip_init(struct b43_wldev *dev) b43_write32(dev, 0x018C, 0x02000000); } b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, 0x00004000); - b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001DC00); + b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001FC00); b43_write32(dev, B43_MMIO_DMA1_IRQ_MASK, 0x0000DC00); b43_write32(dev, B43_MMIO_DMA2_IRQ_MASK, 0x0000DC00); b43_write32(dev, B43_MMIO_DMA3_IRQ_MASK, 0x0001DC00); -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-20 14:14 ` Thommy 2013-04-20 18:35 ` Larry Finger @ 2013-04-20 19:12 ` Michael Büsch 2013-04-20 19:47 ` Thommy Jakobsson 1 sibling, 1 reply; 45+ messages in thread From: Michael Büsch @ 2013-04-20 19:12 UTC (permalink / raw) To: b43-dev On Sat, 20 Apr 2013 16:14:09 +0200 (CEST) Thommy <thommyj@gmail.com> wrote: > +void b43_dma_rx_discard(struct b43_dmaring *ring) > +{ > + B43_WARN_ON(ring->tx); > + > + /* Device has filled all buffers, drop all packets in buffers > + * and let TCP decrease speed. > + * Set index to one desc after the last one > + * so the device will see all slots as free again > + */ > + /* > + *TODO: How to increase rx_drop in mac80211? > + */ > + b43_dma_write(ring, B43_DMA32_RXINDEX, ring->nr_slots * > + sizeof(struct b43_dmadesc32)); > +} You need to check whether this is a 32bit or 64bit DMA engine and write to B43_DMA32_RXINDEX or B43_DMA64_RXINDEX. You could simply use the ring->ops->set_current_rxslot() dmaop for that. And I think you need to set ring->current_slot to the value of ring->ops->get_current_slot(). Not 100% sure, though, since it is years since I worked on that code. -- Michael -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: not available URL: <http://lists.infradead.org/pipermail/b43-dev/attachments/20130420/8697d8d4/attachment.sig> ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-20 19:12 ` Michael Büsch @ 2013-04-20 19:47 ` Thommy Jakobsson 2013-04-20 19:50 ` Michael Büsch 0 siblings, 1 reply; 45+ messages in thread From: Thommy Jakobsson @ 2013-04-20 19:47 UTC (permalink / raw) To: b43-dev On Sat, 20 Apr 2013, Michael B?sch wrote: > On Sat, 20 Apr 2013 16:14:09 +0200 (CEST) > Thommy <thommyj@gmail.com> wrote: > > > +void b43_dma_rx_discard(struct b43_dmaring *ring) > > +{ > > + B43_WARN_ON(ring->tx); > > + > > + /* Device has filled all buffers, drop all packets in buffers > > + * and let TCP decrease speed. > > + * Set index to one desc after the last one > > + * so the device will see all slots as free again > > + */ > > + /* > > + *TODO: How to increase rx_drop in mac80211? > > + */ > > + b43_dma_write(ring, B43_DMA32_RXINDEX, ring->nr_slots * > > + sizeof(struct b43_dmadesc32)); > > +} > > You need to check whether this is a 32bit or 64bit DMA engine and > write to B43_DMA32_RXINDEX or B43_DMA64_RXINDEX. > You could simply use the ring->ops->set_current_rxslot() dmaop for that. > Good point, I'll fix that > And I think you need to set ring->current_slot to the value of ring->ops->get_current_slot(). > Not 100% sure, though, since it is years since I worked on that code. > Is that really needed? They should already be the same since the device has thrown the underflow interrupt, or do I miss some race condition? //thommy ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-20 19:47 ` Thommy Jakobsson @ 2013-04-20 19:50 ` Michael Büsch 2013-04-20 20:16 ` Thommy Jakobsson 0 siblings, 1 reply; 45+ messages in thread From: Michael Büsch @ 2013-04-20 19:50 UTC (permalink / raw) To: b43-dev On Sat, 20 Apr 2013 21:47:10 +0200 (CEST) Thommy Jakobsson <thommyj@gmail.com> wrote: > > And I think you need to set ring->current_slot to the value of ring->ops->get_current_slot(). > > Not 100% sure, though, since it is years since I worked on that code. > > > Is that really needed? They should already be the same since the device > has thrown the underflow interrupt Hm not sure. But should be easy to verify. -- Michael -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: not available URL: <http://lists.infradead.org/pipermail/b43-dev/attachments/20130420/333eb764/attachment.sig> ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-20 19:50 ` Michael Büsch @ 2013-04-20 20:16 ` Thommy Jakobsson 2013-04-20 20:38 ` Michael Büsch ` (2 more replies) 0 siblings, 3 replies; 45+ messages in thread From: Thommy Jakobsson @ 2013-04-20 20:16 UTC (permalink / raw) To: b43-dev On Sat, 20 Apr 2013, Michael B?sch wrote: > On Sat, 20 Apr 2013 21:47:10 +0200 (CEST) > Thommy Jakobsson <thommyj@gmail.com> wrote: > > > > And I think you need to set ring->current_slot to the value of ring->ops->get_current_slot(). > > > Not 100% sure, though, since it is years since I worked on that code. > > > > > Is that really needed? They should already be the same since the device > > has thrown the underflow interrupt > > Hm not sure. But should be easy to verify. I did check it in the beginning when I was testing the patch, just printed the indexes in the kernel log. But of course if there is a race condition it could be hard to catch. Have used the patch for several weeks and several 100Gb now, so it does seem to work. The reason for getting this interrupt is that the current descriptor pointer (RXDPTR) has the same value as the descriptor index (RXINDEX). The descriptor index is set at the end of b43_dma_rx with ops->set_current_rxslot. At the next line, and with the same value, the ring->current slot is set. So in my opinion I don't need to set it. But I could have missed something. BR, Thommy ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-20 20:16 ` Thommy Jakobsson @ 2013-04-20 20:38 ` Michael Büsch 2013-04-20 20:56 ` Piotras [not found] ` <CAFzhf4rSUO9mn_RKw4Vehw2LKggFdC_W0v-K_KKCZJez1AwynQ@mail.gmail.com> 2 siblings, 0 replies; 45+ messages in thread From: Michael Büsch @ 2013-04-20 20:38 UTC (permalink / raw) To: b43-dev On Sat, 20 Apr 2013 22:16:26 +0200 (CEST) Thommy Jakobsson <thommyj@gmail.com> wrote: > > > On Sat, 20 Apr 2013, Michael B?sch wrote: > > > On Sat, 20 Apr 2013 21:47:10 +0200 (CEST) > > Thommy Jakobsson <thommyj@gmail.com> wrote: > > > > > > And I think you need to set ring->current_slot to the value of ring->ops->get_current_slot(). > > > > Not 100% sure, though, since it is years since I worked on that code. > > > > > > > Is that really needed? They should already be the same since the device > > > has thrown the underflow interrupt > > > > Hm not sure. But should be easy to verify. > I did check it in the beginning when I was testing the patch, just printed > the indexes in the kernel log. But of course if there is a race condition > it could be hard to catch. Ok. I don't think there should be a race. Thanks for checking. -- Michael -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: not available URL: <http://lists.infradead.org/pipermail/b43-dev/attachments/20130420/cefb6f3a/attachment-0001.sig> ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-20 20:16 ` Thommy Jakobsson 2013-04-20 20:38 ` Michael Büsch @ 2013-04-20 20:56 ` Piotras [not found] ` <CAFzhf4rSUO9mn_RKw4Vehw2LKggFdC_W0v-K_KKCZJez1AwynQ@mail.gmail.com> 2 siblings, 0 replies; 45+ messages in thread From: Piotras @ 2013-04-20 20:56 UTC (permalink / raw) To: b43-dev (resending with some corrections after original email bounced) Hi all, I tested original version of this patch and it happen to fix the issue on Linksys WRT54GL (based on Broadcom 5352 SoC). However I think that the bug is still present. After closer look it seems that DMA buffers may be used incorrectly in b43_dma_rx. I don't have documentation for Broadcom WLAN chipsets, but DMA engine used by for BCM440X apparently has similar design. Looking at "RECEIVE DESCRIPTOR TABLE POINTER REGISTER" (page 35 of http://www.broadcom.com/collateral/pg/440X-PG02-R.pdf), B43_DMA32_RXINDEX should be left pointing after last valid descriptor as initialized in dmacontroller_setup. Notice that the last valid descriptor already has B43_DMA32_DCTL_DTABLEEND set, so DMA should operate in a round-robin fashion. B43_DMA32_RXINDEX is reprogrammed from b43_dma_rx, by calling ops->set_current_rxslot(ring, slot). The patch from Thommy simply reprogrammes the register back with the same value as initialized in dmacontroller_setup. I suspect that with set_current_rxslot call removed, the patch from Thommy will not be necessary anymore. I'm currently testing such fix and will report back in a few days. Regards, Piotr On Sat, Apr 20, 2013 at 9:16 PM, Thommy Jakobsson <thommyj@gmail.com> wrote: > > > On Sat, 20 Apr 2013, Michael B?sch wrote: > >> On Sat, 20 Apr 2013 21:47:10 +0200 (CEST) >> Thommy Jakobsson <thommyj@gmail.com> wrote: >> >> > > And I think you need to set ring->current_slot to the value of ring->ops->get_current_slot(). >> > > Not 100% sure, though, since it is years since I worked on that code. >> > > >> > Is that really needed? They should already be the same since the device >> > has thrown the underflow interrupt >> >> Hm not sure. But should be easy to verify. > I did check it in the beginning when I was testing the patch, just printed > the indexes in the kernel log. But of course if there is a race condition > it could be hard to catch. Have used the patch for several weeks > and several 100Gb now, so it does seem to work. > > The reason for getting this interrupt is that the current descriptor > pointer (RXDPTR) has the same value as the descriptor index (RXINDEX). The > descriptor index is set at the end of b43_dma_rx with > ops->set_current_rxslot. At the next line, and with the same value, the > ring->current slot is set. So in my opinion I don't need to set it. But I > could have missed something. > > BR, > Thommy > _______________________________________________ > b43-dev mailing list > b43-dev at lists.infradead.org > http://lists.infradead.org/mailman/listinfo/b43-dev > ^ permalink raw reply [flat|nested] 45+ messages in thread
[parent not found: <CAFzhf4rSUO9mn_RKw4Vehw2LKggFdC_W0v-K_KKCZJez1AwynQ@mail.gmail.com>]
* [PATCH] b43: use rx desc underrun interrupt [not found] ` <CAFzhf4rSUO9mn_RKw4Vehw2LKggFdC_W0v-K_KKCZJez1AwynQ@mail.gmail.com> @ 2013-04-20 21:01 ` Thommy Jakobsson 2013-04-20 21:10 ` Thommy Jakobsson 0 siblings, 1 reply; 45+ messages in thread From: Thommy Jakobsson @ 2013-04-20 21:01 UTC (permalink / raw) To: b43-dev On Sat, 20 Apr 2013, Piotras wrote: > Hi all, > > I tested original version of this patch and it happen to fix the issue > on Linksys WRT54GL (based on Broadcom 5352 SoC). However I think that > the original cause is still present. > > After closer look it seems that DMA buffers may be used incorrectly in > b43_dma_rx. I don't have documentation for Broadcom WLAN chipsets, but > DMA engine used by for BCM440X apparently has similar design. Looking > at "RECEIVE DESCRIPTOR TABLE POINTER REGISTER" > (page 35 of http://www.broadcom.com/collateral/pg/440X-PG02-R.pdf), > B43_DMA32_RXINDEX should be left pointing after last valid descriptor > as initialized in dmacontroller_setup (the referred descriptor already > has B43_DMA32_DCTL_DTABLEEND set). > > B43_DMA32_RXINDEX is reprogrammed from b43_dma_rx, by calling > ops->set_current_rxslot(ring, slot). The patch from Thommy simply > reprogramms the register back to the value initialized used in > dmacontroller_setup. > > I suspect that with set_current_rxslot call removed, the patch from > Thommy will not be necessary anymore. I'm currently testing such fix > and will report back in a few days. > > > Regards, > > Piotr > Hi, yes I also saw that datasheet and funny enough I also reacted on the same thing. But if you keep the rxindex pointing after the last descriptor all the time, how can you know if you had an underflow? Of course you could argue that it doesn't matter, the device will just keep on sending data since the current descriptor index will never reach the descriptor index. But that also means that you could start reading a packet at the same time as the device is overwriting it with an other, right? I didn't read it to carefully but the datasheet doesn't prohibit a change of the rxpointer, does it? //Thommy ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-20 21:01 ` Thommy Jakobsson @ 2013-04-20 21:10 ` Thommy Jakobsson 2013-04-20 21:23 ` Thommy Jakobsson 0 siblings, 1 reply; 45+ messages in thread From: Thommy Jakobsson @ 2013-04-20 21:10 UTC (permalink / raw) To: b43-dev On Sat, 20 Apr 2013, Thommy Jakobsson wrote: > > > On Sat, 20 Apr 2013, Piotras wrote: > > > Hi all, > > > > I tested original version of this patch and it happen to fix the issue > > on Linksys WRT54GL (based on Broadcom 5352 SoC). However I think that > > the original cause is still present. > > > > After closer look it seems that DMA buffers may be used incorrectly in > > b43_dma_rx. I don't have documentation for Broadcom WLAN chipsets, but > > DMA engine used by for BCM440X apparently has similar design. Looking > > at "RECEIVE DESCRIPTOR TABLE POINTER REGISTER" > > (page 35 of http://www.broadcom.com/collateral/pg/440X-PG02-R.pdf), > > B43_DMA32_RXINDEX should be left pointing after last valid descriptor > > as initialized in dmacontroller_setup (the referred descriptor already > > has B43_DMA32_DCTL_DTABLEEND set). > > > > B43_DMA32_RXINDEX is reprogrammed from b43_dma_rx, by calling > > ops->set_current_rxslot(ring, slot). The patch from Thommy simply > > reprogramms the register back to the value initialized used in > > dmacontroller_setup. > > > > I suspect that with set_current_rxslot call removed, the patch from > > Thommy will not be necessary anymore. I'm currently testing such fix > > and will report back in a few days. > > > > > > Regards, > > > > Piotr > > > Hi, > > yes I also saw that datasheet and funny enough I also reacted on the same > thing. But if you keep the rxindex pointing after the last descriptor all > the time, how can you know if you had an underflow? Of course you could > argue that it doesn't matter, the device will just keep on sending data > since the current descriptor index will never reach the descriptor index. > But that also means that you could start reading a packet at the same time > as the device is overwriting it with an other, right? I didn't read it to > carefully but the datasheet doesn't prohibit a change of the rxpointer, > does it? > > //Thommy > Sorry I mean that the datasheet doesn't prohibit a change of the rx descriptor index, does it? Where the rx descriptor index in the reversed broadcom documentation and code would be translated to the LastDscr in the BCM440X datasheet (even has the same offset). //Thommy ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-20 21:10 ` Thommy Jakobsson @ 2013-04-20 21:23 ` Thommy Jakobsson 2013-04-21 6:38 ` Michael Büsch 0 siblings, 1 reply; 45+ messages in thread From: Thommy Jakobsson @ 2013-04-20 21:23 UTC (permalink / raw) To: b43-dev On Sat, 20 Apr 2013, Thommy Jakobsson wrote: > > > On Sat, 20 Apr 2013, Thommy Jakobsson wrote: > > > > > > > On Sat, 20 Apr 2013, Piotras wrote: > > > > > Hi all, > > > > > > I tested original version of this patch and it happen to fix the issue > > > on Linksys WRT54GL (based on Broadcom 5352 SoC). However I think that > > > the original cause is still present. > > > > > > After closer look it seems that DMA buffers may be used incorrectly in > > > b43_dma_rx. I don't have documentation for Broadcom WLAN chipsets, but > > > DMA engine used by for BCM440X apparently has similar design. Looking > > > at "RECEIVE DESCRIPTOR TABLE POINTER REGISTER" > > > (page 35 of http://www.broadcom.com/collateral/pg/440X-PG02-R.pdf), > > > B43_DMA32_RXINDEX should be left pointing after last valid descriptor > > > as initialized in dmacontroller_setup (the referred descriptor already > > > has B43_DMA32_DCTL_DTABLEEND set). > > > > > > B43_DMA32_RXINDEX is reprogrammed from b43_dma_rx, by calling > > > ops->set_current_rxslot(ring, slot). The patch from Thommy simply > > > reprogramms the register back to the value initialized used in > > > dmacontroller_setup. > > > > > > I suspect that with set_current_rxslot call removed, the patch from > > > Thommy will not be necessary anymore. I'm currently testing such fix > > > and will report back in a few days. > > > > > > > > > Regards, > > > > > > Piotr > > > > > Hi, > > > > yes I also saw that datasheet and funny enough I also reacted on the same > > thing. But if you keep the rxindex pointing after the last descriptor all > > the time, how can you know if you had an underflow? Of course you could > > argue that it doesn't matter, the device will just keep on sending data > > since the current descriptor index will never reach the descriptor index. > > But that also means that you could start reading a packet at the same time > > as the device is overwriting it with an other, right? I didn't read it to > > carefully but the datasheet doesn't prohibit a change of the rxpointer, > > does it? > > > > //Thommy > > > Sorry I mean that the datasheet doesn't prohibit a change of the rx > descriptor index, does it? Where the rx descriptor index in the reversed > broadcom documentation and code would be translated to the LastDscr > in the BCM440X datasheet (even has the same offset). > > //Thommy > Looking a bit more carefully in the datasheet I find "Software makes the new descriptors available for use by updating the LastDscr field of the XmtPtr register (see ?Receive Descriptor Table Pointer Register (RcvPtr, offset 0x218)? on page 35) to point to the entry after the new last valid descriptor." on page 40 Isn't that exactly what we do in b43_dma_rx? The initial rx descriptor index is just to make the device to start. Theoretically you could get into a fault situation if the device succeds in using up all descriptors between b43_dma_rx_discard (added by my patch) and the call to b43_dma_rx. Because then you could start reading the same packet as the device is writing to. //Thommy ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-20 21:23 ` Thommy Jakobsson @ 2013-04-21 6:38 ` Michael Büsch 2013-04-21 8:22 ` Thommy Jakobsson 2013-04-21 14:27 ` Piotras 0 siblings, 2 replies; 45+ messages in thread From: Michael Büsch @ 2013-04-21 6:38 UTC (permalink / raw) To: b43-dev On Sat, 20 Apr 2013 23:23:54 +0200 (CEST) Thommy Jakobsson <thommyj@gmail.com> wrote: > Isn't that exactly what we do in b43_dma_rx? The initial rx descriptor > index is just to make the device to start. Theoretically you could get > into a fault situation if the device succeds in using up all descriptors > between b43_dma_rx_discard (added by my patch) and the call to b43_dma_rx. > Because then you could start reading the same packet as the device is > writing to. Yes this is true. And thus I'm currently unsure why we need this patch at all. _Why_ does the DMA stall as soon as the ring is filled up? -- Michael -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: not available URL: <http://lists.infradead.org/pipermail/b43-dev/attachments/20130421/201e5823/attachment.sig> ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-21 6:38 ` Michael Büsch @ 2013-04-21 8:22 ` Thommy Jakobsson 2013-04-21 8:44 ` Michael Büsch 2013-04-21 14:27 ` Piotras 1 sibling, 1 reply; 45+ messages in thread From: Thommy Jakobsson @ 2013-04-21 8:22 UTC (permalink / raw) To: b43-dev On Sun, 21 Apr 2013, Michael B?sch wrote: > On Sat, 20 Apr 2013 23:23:54 +0200 (CEST) > Thommy Jakobsson <thommyj@gmail.com> wrote: > > > Isn't that exactly what we do in b43_dma_rx? The initial rx descriptor > > index is just to make the device to start. Theoretically you could get > > into a fault situation if the device succeds in using up all descriptors > > between b43_dma_rx_discard (added by my patch) and the call to b43_dma_rx. > > Because then you could start reading the same packet as the device is > > writing to. > > Yes this is true. > And thus I'm currently unsure why we need this patch at all. > _Why_ does the DMA stall as soon as the ring is filled up? The device stops sending when it hits the rx index. Thats what rx index is, the address after the last slot the device is allowed to use. In the driver it is used as the last slot handled, so if the device would continue it will overwrite slots that hasn't been read. So you need to handle that in someway. One way is using my patch, another is to never let it hit rx index (as Piotras is working on). This is how I see the problem: 1. the driver get an interrupt that there is data in the ring, the interrupt thread is scheduled 2. the interrupt thread (in b43_dma_rx) checks how many slots that the device has filled 3. it then loops through them and sends the packets in the ring to the kernel (dma_rx). It also allocates new skb_buf:s 4. after all slots has been handled the rx index is updated 5. In the meantime the device continues to pump data in to the ring 6. If the cpu is slow, and we don't have that many slots, there is a chance that the device have time to loop through all and hitting rx index. If we don't update the rx index in such a situation the device will never continue. Since it has hit the end of available descriptors, it doesn't have much of a choice, where would it write next? Normally the device never hit the rx index, and in such case it will just use the next descriptor in the table. If it finds a descriptor with END set, it will jump back to the beginning. Forming the ring //Thomy ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-21 8:22 ` Thommy Jakobsson @ 2013-04-21 8:44 ` Michael Büsch 2013-04-21 9:01 ` Thommy Jakobsson 2013-04-21 18:07 ` Thommy Jakobsson 0 siblings, 2 replies; 45+ messages in thread From: Michael Büsch @ 2013-04-21 8:44 UTC (permalink / raw) To: b43-dev On Sun, 21 Apr 2013 10:22:51 +0200 (CEST) Thommy Jakobsson <thommyj@gmail.com> wrote: > The device stops sending when it hits the rx index. Thats what rx index > is, the address after the last slot the device is allowed to use. In the > driver it is used as the last slot handled, so if the device would > continue it will overwrite slots that hasn't been read. So you need to > handle that in someway. One way is using my patch, another is to never let > it hit rx index (as Piotras is working on). Yeah I get that. But why do we need to handle that by putting the stop index right beyond the ring? That requires us to get another RX interrupt before the ring fills up again. Why can't we set it so that the ring is fully writable again, but not set it beyond the ring boundary? I guess that is decrementing it by one, perhaps, honoring 0-index-wrapover. > Normally the device never hit the rx index, and in such case it will just > use the next descriptor in the table. If it finds a descriptor with END > set, it will jump back to the beginning. Forming the ring I know how that basic stuff works, because I wrote most of the code ;D -- Michael -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: not available URL: <http://lists.infradead.org/pipermail/b43-dev/attachments/20130421/59279114/attachment.sig> ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-21 8:44 ` Michael Büsch @ 2013-04-21 9:01 ` Thommy Jakobsson 2013-04-21 9:21 ` Michael Büsch 2013-04-21 18:07 ` Thommy Jakobsson 1 sibling, 1 reply; 45+ messages in thread From: Thommy Jakobsson @ 2013-04-21 9:01 UTC (permalink / raw) To: b43-dev On Sun, 21 Apr 2013, Michael B?sch wrote: > On Sun, 21 Apr 2013 10:22:51 +0200 (CEST) > Thommy Jakobsson <thommyj@gmail.com> wrote: > > > The device stops sending when it hits the rx index. Thats what rx index > > is, the address after the last slot the device is allowed to use. In the > > driver it is used as the last slot handled, so if the device would > > continue it will overwrite slots that hasn't been read. So you need to > > handle that in someway. One way is using my patch, another is to never let > > it hit rx index (as Piotras is working on). > > Yeah I get that. But why do we need to handle that by putting the stop index > right beyond the ring? That requires us to get another RX interrupt before the > ring fills up again. Why can't we set it so that the ring is fully writable again, > but not set it beyond the ring boundary? I guess that is decrementing it by one, > perhaps, honoring 0-index-wrapover. > All times that I had extra debugging on I always got a normal rx interrupt at the same time as the underflow interrupt. So the b43_dma_rx is called just after the b43_rx_discard, and the rx index is updated again to something better. Writing the rx index to index-1 was my initial plan, the only reason why I chose beyond the ring boundary was because thats how it is initialised. I never tried index-1, so I don't know if it works though. It did try to write the same value back again, but of course that didn't work. Why is it set to to beyond the ring when it is initilised? > > Normally the device never hit the rx index, and in such case it will just > > use the next descriptor in the table. If it finds a descriptor with END > > set, it will jump back to the beginning. Forming the ring > > I know how that basic stuff works, because I wrote most of the code ;D and yet you didn't fix this problem... =) Just kidding, to be honest I didn't understand what in my patch your question concerned. So I pretty much wrote down all I know about how it works (or how I think it works). Thanks, Thommy ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-21 9:01 ` Thommy Jakobsson @ 2013-04-21 9:21 ` Michael Büsch 2013-04-21 12:12 ` Thommy Jakobsson 0 siblings, 1 reply; 45+ messages in thread From: Michael Büsch @ 2013-04-21 9:21 UTC (permalink / raw) To: b43-dev On Sun, 21 Apr 2013 11:01:11 +0200 (CEST) Thommy Jakobsson <thommyj@gmail.com> wrote: > Why is it set to to beyond the ring when it is initilised? That's what broadcom does in their implementation. I guess that's the only reason. -- Michael -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: not available URL: <http://lists.infradead.org/pipermail/b43-dev/attachments/20130421/a25c76e8/attachment.sig> ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-21 9:21 ` Michael Büsch @ 2013-04-21 12:12 ` Thommy Jakobsson 2013-04-21 14:46 ` Piotras 0 siblings, 1 reply; 45+ messages in thread From: Thommy Jakobsson @ 2013-04-21 12:12 UTC (permalink / raw) To: b43-dev On Sun, 21 Apr 2013, Michael B?sch wrote: > On Sun, 21 Apr 2013 11:01:11 +0200 (CEST) > Thommy Jakobsson <thommyj@gmail.com> wrote: > > > Why is it set to to beyond the ring when it is initilised? > > That's what broadcom does in their implementation. I guess that's the only reason. > Check, I'll give index-1 a go. It should be quite obvious if it works or not. //thommy ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-21 12:12 ` Thommy Jakobsson @ 2013-04-21 14:46 ` Piotras 2013-04-21 14:59 ` Michael Büsch 2013-04-21 15:11 ` Thommy Jakobsson 0 siblings, 2 replies; 45+ messages in thread From: Piotras @ 2013-04-21 14:46 UTC (permalink / raw) To: b43-dev On Sun, Apr 21, 2013 at 1:12 PM, Thommy Jakobsson <thommyj@gmail.com> wrote: > > > On Sun, 21 Apr 2013, Michael B?sch wrote: > >> On Sun, 21 Apr 2013 11:01:11 +0200 (CEST) >> Thommy Jakobsson <thommyj@gmail.com> wrote: >> >> > Why is it set to to beyond the ring when it is initilised? >> >> That's what broadcom does in their implementation. I guess that's the only reason. >> > Check, I'll give index-1 a go. It should be quite obvious if it works or > not. Thommy, I had the same thought, but notice that you also need to update ring->current_slot in b43_dma_rx_discard. When ring->current_slot update is missing (as in your original patch), you will introduce the same problem I hit by removing ops->set_current_rxslot(ring, slot) from b43_dma_rx (disabling RX underflow detection). Basically we break assumptions about ownership of descriptors (which descriptors are exclusively used by host and which can be written by DMA processor). So next time b43_dma_rx is called it may process descriptors that are updated by DMA processor at the same time (race condition). I guess the following could be used to mark all descriptors for DMA use from RX underflow interrupt or whenever we decide that number of free descriptors is too low (not tested): slot = prev_slot(ring, ops->get_current_rxslot(ring)); wmb(); ops->set_current_rxslot(ring, slot); ring->current_slot = slot; The above code simply puts back all the already filled descriptors back for DMA processor to be overwritten with new data. I'm still concerned about FIFO overruns. When descriptor underflow condition occurs while CPU is busy with b43_dma_rx, we still wait for b43_dma_rx to finish processing all received packets before any descriptors become available for DMA to use. Depending on FIFO size and CPU load we may still hit fatal receive FIFO underflow error. This should cause driver to reset (possible explanation of why "discards" and "slot_usage" files disappeared when Richlv tested your patch in https://dev.openwrt.org/ticket/7552#comment:94). I suspect that driver reset after FIFO underflow interrupt triggers is not handled correctly, but not sure why. Possibly this is not expected by hostapd, so it needs restart? Not sure if FIFO overruns are really an issue and how to prevent them. Maybe RX underflow should be handled in top half and reprogram device to suspend receives (is this possible)? Or maybe we could clean and set B43_DMA32_RXENABLE bit in B43_DMA32_RXCTL to reset DMA channel without resetting the driver? Ideas? Piotr > > //thommy ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-21 14:46 ` Piotras @ 2013-04-21 14:59 ` Michael Büsch 2013-04-21 15:24 ` Piotras 2013-04-21 15:11 ` Thommy Jakobsson 1 sibling, 1 reply; 45+ messages in thread From: Michael Büsch @ 2013-04-21 14:59 UTC (permalink / raw) To: b43-dev On Sun, 21 Apr 2013 15:46:03 +0100 Piotras <piotras@gmail.com> wrote: > On Sun, Apr 21, 2013 at 1:12 PM, Thommy Jakobsson <thommyj@gmail.com> wrote: > > > > > > On Sun, 21 Apr 2013, Michael B?sch wrote: > > > >> On Sun, 21 Apr 2013 11:01:11 +0200 (CEST) > >> Thommy Jakobsson <thommyj@gmail.com> wrote: > >> > >> > Why is it set to to beyond the ring when it is initilised? > >> > >> That's what broadcom does in their implementation. I guess that's the only reason. > >> > > Check, I'll give index-1 a go. It should be quite obvious if it works or > > not. > > Thommy, > > I had the same thought, but notice that you also need to update > ring->current_slot in b43_dma_rx_discard. I don't think so. We don't modify the descriptor pointer, but the stop index. > I guess the following could be used to mark all descriptors for DMA > use from RX underflow interrupt or whenever we decide that number of > free descriptors is too low (not tested): > > slot = prev_slot(ring, ops->get_current_rxslot(ring)); > wmb(); > ops->set_current_rxslot(ring, slot); get_current_rxslot() reads a different register than set_current_rxslot(). get_current_rxslot() returns the descriptor pointer that the device is pointing to. set_current_rxslot() sets the _stop_ index. Yes, at least the last one is misnamed. > Not sure if FIFO overruns are really an issue and how to prevent them. > Maybe RX underflow should be handled in top half and reprogram device > to suspend receives (is this possible)? What is "top half"? -- Michael -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: not available URL: <http://lists.infradead.org/pipermail/b43-dev/attachments/20130421/4c5e94bf/attachment.sig> ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-21 14:59 ` Michael Büsch @ 2013-04-21 15:24 ` Piotras 2013-04-21 16:35 ` Michael Büsch 0 siblings, 1 reply; 45+ messages in thread From: Piotras @ 2013-04-21 15:24 UTC (permalink / raw) To: b43-dev On Sun, Apr 21, 2013 at 3:59 PM, Michael B?sch <m@bues.ch> wrote: > On Sun, 21 Apr 2013 15:46:03 +0100 > Piotras <piotras@gmail.com> wrote: > >> On Sun, Apr 21, 2013 at 1:12 PM, Thommy Jakobsson <thommyj@gmail.com> wrote: >> > >> > >> > On Sun, 21 Apr 2013, Michael B?sch wrote: >> > >> >> On Sun, 21 Apr 2013 11:01:11 +0200 (CEST) >> >> Thommy Jakobsson <thommyj@gmail.com> wrote: >> >> >> >> > Why is it set to to beyond the ring when it is initilised? >> >> >> >> That's what broadcom does in their implementation. I guess that's the only reason. >> >> >> > Check, I'll give index-1 a go. It should be quite obvious if it works or >> > not. >> >> Thommy, >> >> I had the same thought, but notice that you also need to update >> ring->current_slot in b43_dma_rx_discard. > > I don't think so. > We don't modify the descriptor pointer, but the stop index. Yes. My code was incorrect as I should ensure that ring->current_slot is equal ops->get_current_rxslot(ring). As we are in the RX underflow, B43_DMA32_RXSTATUS, B43_DMA32_RXINDEX and ring->current_slot should already point to the same descriptor, so only set_current_rxslot is needed. > >> I guess the following could be used to mark all descriptors for DMA >> use from RX underflow interrupt or whenever we decide that number of >> free descriptors is too low (not tested): >> >> slot = prev_slot(ring, ops->get_current_rxslot(ring)); >> wmb(); >> ops->set_current_rxslot(ring, slot); > > get_current_rxslot() reads a different register than set_current_rxslot(). > > get_current_rxslot() returns the descriptor pointer that the device is pointing to. > set_current_rxslot() sets the _stop_ index. > Yes, at least the last one is misnamed. > >> Not sure if FIFO overruns are really an issue and how to prevent them. >> Maybe RX underflow should be handled in top half and reprogram device >> to suspend receives (is this possible)? > > What is "top half"? Top half interrupt handler (b43_do_interrupt). > > -- > Michael ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-21 15:24 ` Piotras @ 2013-04-21 16:35 ` Michael Büsch 0 siblings, 0 replies; 45+ messages in thread From: Michael Büsch @ 2013-04-21 16:35 UTC (permalink / raw) To: b43-dev On Sun, 21 Apr 2013 16:24:18 +0100 Piotras <piotras@gmail.com> wrote: > >> Not sure if FIFO overruns are really an issue and how to prevent them. > >> Maybe RX underflow should be handled in top half and reprogram device > >> to suspend receives (is this possible)? > > > > What is "top half"? > > Top half interrupt handler (b43_do_interrupt). No way. Interrupts are properly blocked before leaving the top-half handler and re-enabled before leaving the bottom-half handler already. Adding stuff to the top-half handler would only introduce serious locking and latency issues and it would fix nothing. -- Michael -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: not available URL: <http://lists.infradead.org/pipermail/b43-dev/attachments/20130421/36056889/attachment.sig> ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-21 14:46 ` Piotras 2013-04-21 14:59 ` Michael Büsch @ 2013-04-21 15:11 ` Thommy Jakobsson 2013-04-21 16:31 ` Michael Büsch 1 sibling, 1 reply; 45+ messages in thread From: Thommy Jakobsson @ 2013-04-21 15:11 UTC (permalink / raw) To: b43-dev > I had the same thought, but notice that you also need to update > ring->current_slot in b43_dma_rx_discard. > > When ring->current_slot update is missing (as in your original > patch), you will introduce the same problem I hit by removing > ops->set_current_rxslot(ring, slot) from b43_dma_rx (disabling > RX underflow detection). Basically we break assumptions about > ownership of descriptors (which descriptors are exclusively used > by host and which can be written by DMA processor). So next time > b43_dma_rx is called it may process descriptors that are updated > by DMA processor at the same time (race condition). Why would I update ring->current_slot? That should point where we are in the ring from the drivers perspective. Since that i always updated together with the rx index (set_current_rxslot) it will always be the same as the current index in hw (get_current_rxslot) in the b43_rx_discard. That is also where it should be. It is true that I'll introduce a possibility for ownership problem with the original patch, but that will only last until the next time b43_dma_rx is called. Which is just after the b43_dma_rx_discard has exited since you always will get a rx interrupt at the same time as the underflow interrupt. This is also the case at each startup since rx index is initilised to the same thing as I used. I have tested the index-1 that me and michael talked about, from the initial test is working just fine. Im running with only 8 rxslots to try to find any corner cases, so I see a lot of traffic drops though. This would also fix the ownership problem. BTW, it is confusing that set and get current_rxslot doesn't updated and read the same register. About the FIFO errors I haven't looked at those at all. I did get some other errors when I pumped data at link speed into my router, but that was for TX. //Thommy ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-21 15:11 ` Thommy Jakobsson @ 2013-04-21 16:31 ` Michael Büsch 0 siblings, 0 replies; 45+ messages in thread From: Michael Büsch @ 2013-04-21 16:31 UTC (permalink / raw) To: b43-dev On Sun, 21 Apr 2013 17:11:23 +0200 (CEST) Thommy Jakobsson <thommyj@gmail.com> wrote: > BTW, it is confusing that set and get current_rxslot doesn't updated and > read the same register. Yes the set_current_rxslot() op should be renamed to set_rx_stop_slot() or something like that. -- Michael -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: not available URL: <http://lists.infradead.org/pipermail/b43-dev/attachments/20130421/ad24cd10/attachment.sig> ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-21 8:44 ` Michael Büsch 2013-04-21 9:01 ` Thommy Jakobsson @ 2013-04-21 18:07 ` Thommy Jakobsson 2013-04-21 18:26 ` Michael Büsch 1 sibling, 1 reply; 45+ messages in thread From: Thommy Jakobsson @ 2013-04-21 18:07 UTC (permalink / raw) To: b43-dev On Sun, 21 Apr 2013, Michael B?sch wrote: > Yeah I get that. But why do we need to handle that by putting the stop index > right beyond the ring? That requires us to get another RX interrupt before the > ring fills up again. Why can't we set it so that the ring is fully writable again, > but not set it beyond the ring boundary? I guess that is decrementing it by one, > perhaps, honoring 0-index-wrapover. > Hi again, below you can find the patch that I'm currently trying out. The change is according to the discussion above. Instead of setting the rx index as the driver does during startup, it decrements it by one. It has been running at ~1300KB/s in RX and 100KB/s in TX for the last couple of hours without problems. Approximately there have been one underflow per second. CPU load is constantly over 80%, pretty much just the interrupt thread that is using the CPU. I can see that at the entry of b43_dma_discard all three indexes, ring->current_slot(ring), get_current_rxslot(ring) and b43_dma_read(ring,B43_DMA32_RXINDEX) are always the same. Of course the rx index is in bytes. So this is as expected. B I also has to back my statement that I always see a normal rx interrupt at the same time as the underflow interrupt. I have seen a couple of cases where that didn't happen. So this seems like a better way of doing things than setting rx index to max slots when having underflows. This way device and driver collisions are better avoided. Good idea Michael. //Thommy Subject:[PATCH] B43: Handle DMA RX descriptor underrun From: Thommy Jakobsson <thommyj@gmail.com> Add handling of rx descriptor underflow. This fixes a fault that could happen on slow machines, where data is received faster than the CPU can handle. In such a case the device will use up all rx descriptors and refuse to send any more data before confirming that it is ok. This patch enables necessary interrupt to discover such a situation and will handle them by dropping everything in the ring buffer. Signed-off-by: Thommy Jakobsson <thommyj@gmail.com> --- drivers/net/wireless/b43/b43.h | 1 + drivers/net/wireless/b43/dma.c | 19 +++++++++++++++++ drivers/net/wireless/b43/dma.h | 4 +++- drivers/net/wireless/b43/main.c | 43 ++++++++++++++++----------------------- 4 files changed, 41 insertions(+), 26 deletions(-) diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 7f3d461..fdcd00f 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -680,6 +680,7 @@ struct b43_noise_calculation { struct b43_stats { u8 link_noise; + u32 rxdesc_underruns; }; struct b43_key { diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 1221469..139305e 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c @@ -1733,6 +1733,25 @@ drop_recycle_buffer: sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize); } +void b43_dma_rx_discard(struct b43_dmaring *ring) +{ + int current_slot, previous_slot; + + B43_WARN_ON(ring->tx); + + /* Device has filled all buffers, drop all packets in buffers + * and let TCP decrease speed. + * Set index to one desc after the last one + * so the device will see all slots as free again + */ + /* + *TODO: How to increase rx_drop in mac80211? + */ + current_slot = ring->ops->get_current_rxslot(ring); + previous_slot = prev_slot(ring, current_slot); + ring->ops->set_current_rxslot(ring, previous_slot); +} + void b43_dma_rx(struct b43_dmaring *ring) { const struct b43_dma_ops *ops = ring->ops; diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h index 9fdd198..fed8163 100644 --- a/drivers/net/wireless/b43/dma.h +++ b/drivers/net/wireless/b43/dma.h @@ -9,7 +9,7 @@ /* DMA-Interrupt reasons. */ #define B43_DMAIRQ_FATALMASK ((1 << 10) | (1 << 11) | (1 << 12) \ | (1 << 14) | (1 << 15)) -#define B43_DMAIRQ_NONFATALMASK (1 << 13) +#define B43_DMAIRQ_RDESC_UFLOW (1 << 13) #define B43_DMAIRQ_RX_DONE (1 << 16) /*** 32-bit DMA Engine. ***/ @@ -295,6 +295,8 @@ int b43_dma_tx(struct b43_wldev *dev, void b43_dma_handle_txstatus(struct b43_wldev *dev, const struct b43_txstatus *status); +void b43_dma_rx_discard(struct b43_dmaring *ring); + void b43_dma_rx(struct b43_dmaring *ring); void b43_dma_direct_fifo_rx(struct b43_wldev *dev, diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index d377f77..5662f18 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -1902,30 +1902,18 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev) } } - if (unlikely(merged_dma_reason & (B43_DMAIRQ_FATALMASK | - B43_DMAIRQ_NONFATALMASK))) { - if (merged_dma_reason & B43_DMAIRQ_FATALMASK) { - b43err(dev->wl, "Fatal DMA error: " - "0x%08X, 0x%08X, 0x%08X, " - "0x%08X, 0x%08X, 0x%08X\n", - dma_reason[0], dma_reason[1], - dma_reason[2], dma_reason[3], - dma_reason[4], dma_reason[5]); - b43err(dev->wl, "This device does not support DMA " + if (unlikely(merged_dma_reason & (B43_DMAIRQ_FATALMASK))) { + b43err(dev->wl, + "Fatal DMA error: 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X\n", + dma_reason[0], dma_reason[1], + dma_reason[2], dma_reason[3], + dma_reason[4], dma_reason[5]); + b43err(dev->wl, "This device does not support DMA " "on your system. It will now be switched to PIO.\n"); - /* Fall back to PIO transfers if we get fatal DMA errors! */ - dev->use_pio = true; - b43_controller_restart(dev, "DMA error"); - return; - } - if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) { - b43err(dev->wl, "DMA error: " - "0x%08X, 0x%08X, 0x%08X, " - "0x%08X, 0x%08X, 0x%08X\n", - dma_reason[0], dma_reason[1], - dma_reason[2], dma_reason[3], - dma_reason[4], dma_reason[5]); - } + /* Fall back to PIO transfers if we get fatal DMA errors! */ + dev->use_pio = true; + b43_controller_restart(dev, "DMA error"); + return; } if (unlikely(reason & B43_IRQ_UCODE_DEBUG)) @@ -1944,6 +1932,11 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev) handle_irq_noise(dev); /* Check the DMA reason registers for received data. */ + if (dma_reason[0] & B43_DMAIRQ_RDESC_UFLOW) { + if (B43_DEBUG) + b43warn(dev->wl, "RX descriptor underrun\n"); + b43_dma_rx_discard(dev->dma.rx_ring); + } if (dma_reason[0] & B43_DMAIRQ_RX_DONE) { if (b43_using_pio_transfers(dev)) b43_pio_rx(dev->pio.rx_queue); @@ -2001,7 +1994,7 @@ static irqreturn_t b43_do_interrupt(struct b43_wldev *dev) return IRQ_NONE; dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON) - & 0x0001DC00; + & 0x0001FC00; dev->dma_reason[1] = b43_read32(dev, B43_MMIO_DMA1_REASON) & 0x0000DC00; dev->dma_reason[2] = b43_read32(dev, B43_MMIO_DMA2_REASON) @@ -3130,7 +3123,7 @@ static int b43_chip_init(struct b43_wldev *dev) b43_write32(dev, 0x018C, 0x02000000); } b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, 0x00004000); - b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001DC00); + b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001FC00); b43_write32(dev, B43_MMIO_DMA1_IRQ_MASK, 0x0000DC00); b43_write32(dev, B43_MMIO_DMA2_IRQ_MASK, 0x0000DC00); b43_write32(dev, B43_MMIO_DMA3_IRQ_MASK, 0x0001DC00); -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-21 18:07 ` Thommy Jakobsson @ 2013-04-21 18:26 ` Michael Büsch 2013-04-21 18:44 ` Thommy Jakobsson [not found] ` <CAOTQ16LCWpAOndQsHBxN1-X_8SLpcU8V=mM41gvcNRocA=GhsA@mail.gmail.com> 0 siblings, 2 replies; 45+ messages in thread From: Michael Büsch @ 2013-04-21 18:26 UTC (permalink / raw) To: b43-dev On Sun, 21 Apr 2013 20:07:39 +0200 (CEST) Thommy Jakobsson <thommyj@gmail.com> wrote: > +void b43_dma_rx_discard(struct b43_dmaring *ring) > +{ > + int current_slot, previous_slot; > + > + B43_WARN_ON(ring->tx); > + > + /* Device has filled all buffers, drop all packets in buffers > + * and let TCP decrease speed. > + * Set index to one desc after the last one > + * so the device will see all slots as free again > + */ > + /* > + *TODO: How to increase rx_drop in mac80211? > + */ > + current_slot = ring->ops->get_current_rxslot(ring); > + previous_slot = prev_slot(ring, current_slot); > + ring->ops->set_current_rxslot(ring, previous_slot); Hmmm. While this does work (because the register and ring->current_slot contain the same value at this point), I'd prefer if you write ring->current_slot - 1 to the stop-index-register. Also, the comment needs to be updated. PS: I'll send a patch that renames set_current_rxslot() later, because it's really confusing. -- Michael -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: not available URL: <http://lists.infradead.org/pipermail/b43-dev/attachments/20130421/30d76e76/attachment.sig> ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-21 18:26 ` Michael Büsch @ 2013-04-21 18:44 ` Thommy Jakobsson [not found] ` <CAOTQ16LCWpAOndQsHBxN1-X_8SLpcU8V=mM41gvcNRocA=GhsA@mail.gmail.com> 1 sibling, 0 replies; 45+ messages in thread From: Thommy Jakobsson @ 2013-04-21 18:44 UTC (permalink / raw) To: b43-dev New response since my phone answered with html On Sun, 21 Apr 2013, Michael B?sch wrote: > Hmmm. While this does work (because the register and ring->current_slot contain the same > value at this point), I'd prefer if you write ring->current_slot - 1 > to the stop-index-register. The reason for the interrupt is because the current index in the device is the same as the last index. That's why I read the value from the device. But I fix it, don't have a strong opinion about it. > Also, the comment needs to be updated Crap, missed that. /thommy ^ permalink raw reply [flat|nested] 45+ messages in thread
[parent not found: <CAOTQ16LCWpAOndQsHBxN1-X_8SLpcU8V=mM41gvcNRocA=GhsA@mail.gmail.com>]
* [PATCH] b43: use rx desc underrun interrupt [not found] ` <CAOTQ16LCWpAOndQsHBxN1-X_8SLpcU8V=mM41gvcNRocA=GhsA@mail.gmail.com> @ 2013-04-21 18:44 ` Michael Büsch 2013-04-21 20:13 ` Thommy Jakobsson 0 siblings, 1 reply; 45+ messages in thread From: Michael Büsch @ 2013-04-21 18:44 UTC (permalink / raw) To: b43-dev On Sun, 21 Apr 2013 20:39:49 +0200 Thommy Jakobsson <thommyj@gmail.com> wrote: > On Apr 21, 2013 8:26 PM, "Michael B?sch" <m@bues.ch> wrote: > > > > On Sun, 21 Apr 2013 20:07:39 +0200 (CEST) > > Thommy Jakobsson <thommyj@gmail.com> wrote: > > > > > +void b43_dma_rx_discard(struct b43_dmaring *ring) > > > +{ > > > + int current_slot, previous_slot; > > > + > > > + B43_WARN_ON(ring->tx); > > > + > > > + /* Device has filled all buffers, drop all packets in buffers > > > + * and let TCP decrease speed. > > > + * Set index to one desc after the last one > > > + * so the device will see all slots as free again > > > + */ > > > + /* > > > + *TODO: How to increase rx_drop in mac80211? > > > + */ > > > + current_slot = ring->ops->get_current_rxslot(ring); > > > + previous_slot = prev_slot(ring, current_slot); > > > + ring->ops->set_current_rxslot(ring, previous_slot); > > > > Hmmm. While this does work (because the register and ring->current_slot > contain the same > > value at this point), I'd prefer if you write ring->current_slot - 1 > > to the stop-index-register. > The reason for the interrupt is because the current index in the device is > the same as the last index. That's why I read the value from the device. > But I fix it, don't have a strong opinion about it. Hm, ok. Well, sounds plausible. So you may keep it as-is. But you should probably rename the function to b43_dma_handle_rx_overflow(), because the discard does not work properly, if the function is called without an overflow in progress. -- Michael -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: not available URL: <http://lists.infradead.org/pipermail/b43-dev/attachments/20130421/a18e0cde/attachment-0001.sig> ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-21 18:44 ` Michael Büsch @ 2013-04-21 20:13 ` Thommy Jakobsson 2013-04-21 21:53 ` Michael Büsch 0 siblings, 1 reply; 45+ messages in thread From: Thommy Jakobsson @ 2013-04-21 20:13 UTC (permalink / raw) To: b43-dev > Hm, ok. Well, sounds plausible. So you may keep it as-is. > > But you should probably rename the function to b43_dma_handle_rx_overflow(), > because the discard does not work properly, if the function is called without > an overflow in progress. Check, better? //Thommy Subject:[PATCH] B43: Handle DMA RX descriptor underrun From: Thommy Jakobsson <thommyj@gmail.com> Add handling of rx descriptor underflow. This fixes a fault that could happen on slow machines, where data is received faster than the CPU can handle. In such a case the device will use up all rx descriptors and refuse to send any more data before confirming that it is ok. This patch enables necessary interrupt to discover such a situation and will handle them by dropping everything in the ring buffer. Signed-off-by: Thommy Jakobsson <thommyj@gmail.com> --- drivers/net/wireless/b43/b43.h | 1 + drivers/net/wireless/b43/dma.c | 19 +++++++++++++++++ drivers/net/wireless/b43/dma.h | 4 +++- drivers/net/wireless/b43/main.c | 43 ++++++++++++++++----------------------- 4 files changed, 41 insertions(+), 26 deletions(-) diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 7f3d461..fdcd00f 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -680,6 +680,7 @@ struct b43_noise_calculation { struct b43_stats { u8 link_noise; + u32 rxdesc_underruns; }; struct b43_key { diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 1221469..84af9e1 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c @@ -1733,6 +1733,25 @@ drop_recycle_buffer: sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize); } +void b43_dma_handle_rx_overflow(struct b43_dmaring *ring) +{ + int current_slot, previous_slot; + + B43_WARN_ON(ring->tx); + + /* Device has filled all buffers, drop all packets and let TCP + * decrease speed. + * Decrement RX index by one will let the device to see all slots + * as free again + */ + /* + *TODO: How to increase rx_drop in mac80211? + */ + current_slot = ring->ops->get_current_rxslot(ring); + previous_slot = prev_slot(ring, current_slot); + ring->ops->set_current_rxslot(ring, previous_slot); +} + void b43_dma_rx(struct b43_dmaring *ring) { const struct b43_dma_ops *ops = ring->ops; diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h index 9fdd198..df8c8cd 100644 --- a/drivers/net/wireless/b43/dma.h +++ b/drivers/net/wireless/b43/dma.h @@ -9,7 +9,7 @@ /* DMA-Interrupt reasons. */ #define B43_DMAIRQ_FATALMASK ((1 << 10) | (1 << 11) | (1 << 12) \ | (1 << 14) | (1 << 15)) -#define B43_DMAIRQ_NONFATALMASK (1 << 13) +#define B43_DMAIRQ_RDESC_UFLOW (1 << 13) #define B43_DMAIRQ_RX_DONE (1 << 16) /*** 32-bit DMA Engine. ***/ @@ -295,6 +295,8 @@ int b43_dma_tx(struct b43_wldev *dev, void b43_dma_handle_txstatus(struct b43_wldev *dev, const struct b43_txstatus *status); +void b43_dma_handle_rx_overflow(struct b43_dmaring *ring); + void b43_dma_rx(struct b43_dmaring *ring); void b43_dma_direct_fifo_rx(struct b43_wldev *dev, diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index d377f77..618bb03 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -1902,30 +1902,18 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev) } } - if (unlikely(merged_dma_reason & (B43_DMAIRQ_FATALMASK | - B43_DMAIRQ_NONFATALMASK))) { - if (merged_dma_reason & B43_DMAIRQ_FATALMASK) { - b43err(dev->wl, "Fatal DMA error: " - "0x%08X, 0x%08X, 0x%08X, " - "0x%08X, 0x%08X, 0x%08X\n", - dma_reason[0], dma_reason[1], - dma_reason[2], dma_reason[3], - dma_reason[4], dma_reason[5]); - b43err(dev->wl, "This device does not support DMA " + if (unlikely(merged_dma_reason & (B43_DMAIRQ_FATALMASK))) { + b43err(dev->wl, + "Fatal DMA error: 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X\n", + dma_reason[0], dma_reason[1], + dma_reason[2], dma_reason[3], + dma_reason[4], dma_reason[5]); + b43err(dev->wl, "This device does not support DMA " "on your system. It will now be switched to PIO.\n"); - /* Fall back to PIO transfers if we get fatal DMA errors! */ - dev->use_pio = true; - b43_controller_restart(dev, "DMA error"); - return; - } - if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) { - b43err(dev->wl, "DMA error: " - "0x%08X, 0x%08X, 0x%08X, " - "0x%08X, 0x%08X, 0x%08X\n", - dma_reason[0], dma_reason[1], - dma_reason[2], dma_reason[3], - dma_reason[4], dma_reason[5]); - } + /* Fall back to PIO transfers if we get fatal DMA errors! */ + dev->use_pio = true; + b43_controller_restart(dev, "DMA error"); + return; } if (unlikely(reason & B43_IRQ_UCODE_DEBUG)) @@ -1944,6 +1932,11 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev) handle_irq_noise(dev); /* Check the DMA reason registers for received data. */ + if (dma_reason[0] & B43_DMAIRQ_RDESC_UFLOW) { + if (B43_DEBUG) + b43warn(dev->wl, "RX descriptor underrun\n"); + b43_dma_handle_rx_overflow(dev->dma.rx_ring); + } if (dma_reason[0] & B43_DMAIRQ_RX_DONE) { if (b43_using_pio_transfers(dev)) b43_pio_rx(dev->pio.rx_queue); @@ -2001,7 +1994,7 @@ static irqreturn_t b43_do_interrupt(struct b43_wldev *dev) return IRQ_NONE; dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON) - & 0x0001DC00; + & 0x0001FC00; dev->dma_reason[1] = b43_read32(dev, B43_MMIO_DMA1_REASON) & 0x0000DC00; dev->dma_reason[2] = b43_read32(dev, B43_MMIO_DMA2_REASON) @@ -3130,7 +3123,7 @@ static int b43_chip_init(struct b43_wldev *dev) b43_write32(dev, 0x018C, 0x02000000); } b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, 0x00004000); - b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001DC00); + b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001FC00); b43_write32(dev, B43_MMIO_DMA1_IRQ_MASK, 0x0000DC00); b43_write32(dev, B43_MMIO_DMA2_IRQ_MASK, 0x0000DC00); b43_write32(dev, B43_MMIO_DMA3_IRQ_MASK, 0x0001DC00); -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-21 20:13 ` Thommy Jakobsson @ 2013-04-21 21:53 ` Michael Büsch 2013-04-22 8:11 ` Thommy Jakobsson 0 siblings, 1 reply; 45+ messages in thread From: Michael Büsch @ 2013-04-21 21:53 UTC (permalink / raw) To: b43-dev On Sun, 21 Apr 2013 22:13:43 +0200 (CEST) Thommy Jakobsson <thommyj@gmail.com> wrote: > struct b43_stats { > u8 link_noise; > + u32 rxdesc_underruns; Why do we add that? It's not incremented and used anywhere. The rest looks good. -- Michael -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: not available URL: <http://lists.infradead.org/pipermail/b43-dev/attachments/20130421/8eb7d860/attachment.sig> ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-21 21:53 ` Michael Büsch @ 2013-04-22 8:11 ` Thommy Jakobsson 2013-04-22 10:00 ` Michael Büsch 0 siblings, 1 reply; 45+ messages in thread From: Thommy Jakobsson @ 2013-04-22 8:11 UTC (permalink / raw) To: b43-dev On Sun, 21 Apr 2013, Michael B?sch wrote: > > struct b43_stats { > > u8 link_noise; > > + u32 rxdesc_underruns; > > Why do we add that? It's not incremented and used anywhere. > Sorry, seems like I dont do that of a good joob revewing my own patches. It slipped in from one of my debug builts. Should I send in this to John or do you think we have to test it further? It has been running during the entire night with high load on my device. So that seems to work, but that is only on one device of course. //Thommy Subject:[PATCH] B43: Handle DMA RX descriptor underrun From: Thommy Jakobsson <thommyj@gmail.com> Add handling of rx descriptor underflow. This fixes a fault that could happen on slow machines, where data is received faster than the CPU can handle. In such a case the device will use up all rx descriptors and refuse to send any more data before confirming that it is ok. This patch enables necessary interrupt to discover such a situation and will handle them by dropping everything in the ring buffer. Signed-off-by: Thommy Jakobsson <thommyj@gmail.com> Cc: stable <stable@vger.kernel.org> --- drivers/net/wireless/b43/dma.c | 19 +++++++++++++++++ drivers/net/wireless/b43/dma.h | 4 +++- drivers/net/wireless/b43/main.c | 43 ++++++++++++++++----------------------- 3 files changed, 40 insertions(+), 26 deletions(-) diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 1221469..ee3d640 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c @@ -1733,6 +1733,25 @@ drop_recycle_buffer: sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize); } +void b43_dma_handle_rx_overflow(struct b43_dmaring *ring) +{ + int current_slot, previous_slot; + + B43_WARN_ON(ring->tx); + + /* Device has filled all buffers, drop all packets and let TCP + * decrease speed. + * Decrement RX index by one will let the device to see all slots + * as free again + */ + /* + *TODO: How to increase rx_drop in mac80211? + */ + current_slot = ring->ops->get_current_rxslot(ring); + previous_slot = prev_slot(ring, current_slot); + ring->ops->set_current_rxslot(ring, previous_slot); +} + void b43_dma_rx(struct b43_dmaring *ring) { const struct b43_dma_ops *ops = ring->ops; diff --git a/drivers/net/wireless/b43/dma.h b/drivers/net/wireless/b43/dma.h index 9fdd198..df8c8cd 100644 --- a/drivers/net/wireless/b43/dma.h +++ b/drivers/net/wireless/b43/dma.h @@ -9,7 +9,7 @@ /* DMA-Interrupt reasons. */ #define B43_DMAIRQ_FATALMASK ((1 << 10) | (1 << 11) | (1 << 12) \ | (1 << 14) | (1 << 15)) -#define B43_DMAIRQ_NONFATALMASK (1 << 13) +#define B43_DMAIRQ_RDESC_UFLOW (1 << 13) #define B43_DMAIRQ_RX_DONE (1 << 16) /*** 32-bit DMA Engine. ***/ @@ -295,6 +295,8 @@ int b43_dma_tx(struct b43_wldev *dev, void b43_dma_handle_txstatus(struct b43_wldev *dev, const struct b43_txstatus *status); +void b43_dma_handle_rx_overflow(struct b43_dmaring *ring); + void b43_dma_rx(struct b43_dmaring *ring); void b43_dma_direct_fifo_rx(struct b43_wldev *dev, diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index d377f77..6dd07e2 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -1902,30 +1902,18 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev) } } - if (unlikely(merged_dma_reason & (B43_DMAIRQ_FATALMASK | - B43_DMAIRQ_NONFATALMASK))) { - if (merged_dma_reason & B43_DMAIRQ_FATALMASK) { - b43err(dev->wl, "Fatal DMA error: " - "0x%08X, 0x%08X, 0x%08X, " - "0x%08X, 0x%08X, 0x%08X\n", - dma_reason[0], dma_reason[1], - dma_reason[2], dma_reason[3], - dma_reason[4], dma_reason[5]); - b43err(dev->wl, "This device does not support DMA " + if (unlikely(merged_dma_reason & (B43_DMAIRQ_FATALMASK))) { + b43err(dev->wl, + "Fatal DMA error: 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X\n", + dma_reason[0], dma_reason[1], + dma_reason[2], dma_reason[3], + dma_reason[4], dma_reason[5]); + b43err(dev->wl, "This device does not support DMA " "on your system. It will now be switched to PIO.\n"); - /* Fall back to PIO transfers if we get fatal DMA errors! */ - dev->use_pio = true; - b43_controller_restart(dev, "DMA error"); - return; - } - if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) { - b43err(dev->wl, "DMA error: " - "0x%08X, 0x%08X, 0x%08X, " - "0x%08X, 0x%08X, 0x%08X\n", - dma_reason[0], dma_reason[1], - dma_reason[2], dma_reason[3], - dma_reason[4], dma_reason[5]); - } + /* Fall back to PIO transfers if we get fatal DMA errors! */ + dev->use_pio = true; + b43_controller_restart(dev, "DMA error"); + return; } if (unlikely(reason & B43_IRQ_UCODE_DEBUG)) @@ -1944,6 +1932,11 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev) handle_irq_noise(dev); /* Check the DMA reason registers for received data. */ + if (dma_reason[0] & B43_DMAIRQ_RDESC_UFLOW) { + if (B43_DEBUG) + b43warn(dev->wl, "RX descriptor underrun\n"); + b43_dma_handle_rx_overflow(dev->dma.rx_ring); + } if (dma_reason[0] & B43_DMAIRQ_RX_DONE) { if (b43_using_pio_transfers(dev)) b43_pio_rx(dev->pio.rx_queue); @@ -2001,7 +1994,7 @@ static irqreturn_t b43_do_interrupt(struct b43_wldev *dev) return IRQ_NONE; dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON) - & 0x0001DC00; + & 0x0001FC00; dev->dma_reason[1] = b43_read32(dev, B43_MMIO_DMA1_REASON) & 0x0000DC00; dev->dma_reason[2] = b43_read32(dev, B43_MMIO_DMA2_REASON) @@ -3130,7 +3123,7 @@ static int b43_chip_init(struct b43_wldev *dev) b43_write32(dev, 0x018C, 0x02000000); } b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, 0x00004000); - b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001DC00); + b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001FC00); b43_write32(dev, B43_MMIO_DMA1_IRQ_MASK, 0x0000DC00); b43_write32(dev, B43_MMIO_DMA2_IRQ_MASK, 0x0000DC00); b43_write32(dev, B43_MMIO_DMA3_IRQ_MASK, 0x0001DC00); -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-22 8:11 ` Thommy Jakobsson @ 2013-04-22 10:00 ` Michael Büsch 2013-04-23 6:22 ` Michael Büsch 0 siblings, 1 reply; 45+ messages in thread From: Michael Büsch @ 2013-04-22 10:00 UTC (permalink / raw) To: b43-dev On Mon, 22 Apr 2013 10:11:41 +0200 (CEST) Thommy Jakobsson <thommyj@gmail.com> wrote: > On Sun, 21 Apr 2013, Michael B?sch wrote: > > > > struct b43_stats { > > > u8 link_noise; > > > + u32 rxdesc_underruns; > > > > Why do we add that? It's not incremented and used anywhere. > > > Sorry, seems like I dont do that of a good joob revewing my own patches. > It slipped in from one of my debug builts. Should I send in this to John > or do you think we have to test it further? It has been running during the > entire night with high load on my device. So that seems to work, but that > is only on one device of course. Please remove rxdesc_underruns and send the patch (properly signed-off) to John Linville. Cc the linux-wireless mailinglist, b43-dev mailinglist and probably everybody involved in the review discussion. You can also add a Reviewed-by: Michael Buesch <m@bues.ch> -- Michael -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: not available URL: <http://lists.infradead.org/pipermail/b43-dev/attachments/20130422/48db6429/attachment.sig> ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-22 10:00 ` Michael Büsch @ 2013-04-23 6:22 ` Michael Büsch 0 siblings, 0 replies; 45+ messages in thread From: Michael Büsch @ 2013-04-23 6:22 UTC (permalink / raw) To: b43-dev On Mon, 22 Apr 2013 12:00:47 +0200 Michael B?sch <m@bues.ch> wrote: > On Mon, 22 Apr 2013 10:11:41 +0200 (CEST) > Thommy Jakobsson <thommyj@gmail.com> wrote: > > > On Sun, 21 Apr 2013, Michael B?sch wrote: > > > > > > struct b43_stats { > > > > u8 link_noise; > > > > + u32 rxdesc_underruns; > > > > > > Why do we add that? It's not incremented and used anywhere. > > > > > Sorry, seems like I dont do that of a good joob revewing my own patches. > > It slipped in from one of my debug builts. Should I send in this to John > > or do you think we have to test it further? It has been running during the > > entire night with high load on my device. So that seems to work, but that > > is only on one device of course. > > Please remove rxdesc_underruns and send the patch (properly signed-off) > to John Linville. Cc the linux-wireless mailinglist, b43-dev mailinglist > and probably everybody involved in the review discussion. whoops I forgot. Please also add Cc: stable at vger.kernel.org to the signed-off list -- Michael -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: not available URL: <http://lists.infradead.org/pipermail/b43-dev/attachments/20130423/e1c123eb/attachment.sig> ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-21 6:38 ` Michael Büsch 2013-04-21 8:22 ` Thommy Jakobsson @ 2013-04-21 14:27 ` Piotras 2013-04-21 14:51 ` Michael Büsch 1 sibling, 1 reply; 45+ messages in thread From: Piotras @ 2013-04-21 14:27 UTC (permalink / raw) To: b43-dev Michael, Based on BCM440X Programmer's Reference Guide that may or may not apply to DMA processor used in WLAN chipsets, B43_DMA32_RXSTATUS may be updated by hardware to point to the same descriptor as B43_DMA32_RXINDEX. For DMA processor this means that no more free descriptors are available. However b43_dma_rx assumes no data needs to be processed (see how ring->current_slot is updated and used in loop condition on next interrupt). This could explain stalls. I don't expect that changing loop condition is sufficient, as without dropping some packets we will not prevent FIFO overruns. Regards, Piotr On Sun, Apr 21, 2013 at 7:38 AM, Michael B?sch <m@bues.ch> wrote: > On Sat, 20 Apr 2013 23:23:54 +0200 (CEST) > Thommy Jakobsson <thommyj@gmail.com> wrote: > >> Isn't that exactly what we do in b43_dma_rx? The initial rx descriptor >> index is just to make the device to start. Theoretically you could get >> into a fault situation if the device succeds in using up all descriptors >> between b43_dma_rx_discard (added by my patch) and the call to b43_dma_rx. >> Because then you could start reading the same packet as the device is >> writing to. > > Yes this is true. > And thus I'm currently unsure why we need this patch at all. > _Why_ does the DMA stall as soon as the ring is filled up? > > -- > Michael ^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH] b43: use rx desc underrun interrupt 2013-04-21 14:27 ` Piotras @ 2013-04-21 14:51 ` Michael Büsch 0 siblings, 0 replies; 45+ messages in thread From: Michael Büsch @ 2013-04-21 14:51 UTC (permalink / raw) To: b43-dev On Sun, 21 Apr 2013 15:27:49 +0100 Piotras <piotras@gmail.com> wrote: > Based on BCM440X Programmer's Reference Guide that may or may not > apply to DMA processor used in WLAN chipsets, B43_DMA32_RXSTATUS may > be updated by hardware to point to the same descriptor as > B43_DMA32_RXINDEX. > > For DMA processor this means that no more free descriptors are > available. However b43_dma_rx assumes no data needs to be processed > (see how ring->current_slot is updated and used in loop condition on > next interrupt). This could explain stalls. Yes this is why it stalls. But how to fix this without additional counting? I'd rather prefer wiping the whole ring in that case. -- Michael -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: not available URL: <http://lists.infradead.org/pipermail/b43-dev/attachments/20130421/9341395e/attachment.sig> ^ permalink raw reply [flat|nested] 45+ messages in thread
end of thread, other threads:[~2013-04-23 6:22 UTC | newest] Thread overview: 45+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-04-15 8:02 [PATCH] b43: use rx desc underrun interrupt Thommy Jakobsson 2013-04-19 14:32 ` Jonas Gorski 2013-04-19 15:55 ` Michael Büsch 2013-04-19 15:59 ` Jonas Gorski 2013-04-19 18:17 ` Larry Finger 2013-04-19 18:57 ` Michael Büsch 2013-04-19 20:37 ` Thommy Jakobsson 2013-04-19 20:46 ` Michael Büsch 2013-04-19 21:05 ` Larry Finger 2013-04-19 20:30 ` Thommy Jakobsson 2013-04-20 14:14 ` Thommy 2013-04-20 18:35 ` Larry Finger 2013-04-20 22:47 ` Thommy Jakobsson 2013-04-20 19:12 ` Michael Büsch 2013-04-20 19:47 ` Thommy Jakobsson 2013-04-20 19:50 ` Michael Büsch 2013-04-20 20:16 ` Thommy Jakobsson 2013-04-20 20:38 ` Michael Büsch 2013-04-20 20:56 ` Piotras [not found] ` <CAFzhf4rSUO9mn_RKw4Vehw2LKggFdC_W0v-K_KKCZJez1AwynQ@mail.gmail.com> 2013-04-20 21:01 ` Thommy Jakobsson 2013-04-20 21:10 ` Thommy Jakobsson 2013-04-20 21:23 ` Thommy Jakobsson 2013-04-21 6:38 ` Michael Büsch 2013-04-21 8:22 ` Thommy Jakobsson 2013-04-21 8:44 ` Michael Büsch 2013-04-21 9:01 ` Thommy Jakobsson 2013-04-21 9:21 ` Michael Büsch 2013-04-21 12:12 ` Thommy Jakobsson 2013-04-21 14:46 ` Piotras 2013-04-21 14:59 ` Michael Büsch 2013-04-21 15:24 ` Piotras 2013-04-21 16:35 ` Michael Büsch 2013-04-21 15:11 ` Thommy Jakobsson 2013-04-21 16:31 ` Michael Büsch 2013-04-21 18:07 ` Thommy Jakobsson 2013-04-21 18:26 ` Michael Büsch 2013-04-21 18:44 ` Thommy Jakobsson [not found] ` <CAOTQ16LCWpAOndQsHBxN1-X_8SLpcU8V=mM41gvcNRocA=GhsA@mail.gmail.com> 2013-04-21 18:44 ` Michael Büsch 2013-04-21 20:13 ` Thommy Jakobsson 2013-04-21 21:53 ` Michael Büsch 2013-04-22 8:11 ` Thommy Jakobsson 2013-04-22 10:00 ` Michael Büsch 2013-04-23 6:22 ` Michael Büsch 2013-04-21 14:27 ` Piotras 2013-04-21 14:51 ` Michael Büsch
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).