aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuis R. Rodriguez <lrodriguez@atheros.com>2008-11-20 20:15:12 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-11-25 16:13:08 -0500
commitca0c7e5101fd4f37fed8e851709f08580b92fbb3 (patch)
tree6121ed93a7d14be26b95c3da9eed859f49164a78
parent3dd3b79aeadc6f6abc5cc78724d7df3dfcc1bd0b (diff)
ath9k: Fix SW-IOMMU bounce buffer starvation
This should fix the SW-IOMMU bounce buffer starvation seen ok kernel.org bugzilla 11811: http://bugzilla.kernel.org/show_bug.cgi?id=11811 Users on MacBook Pro 3.1/MacBook v2 would see something like: DMA: Out of SW-IOMMU space for 4224 bytes at device 0000:0b:00.0 Unfortunately its only easy to trigger on MacBook Pro 3.1/MacBook v2 so far so its difficult to debug (even with swiotlb=force). We were pci_unmap_single()'ing less bytes than what we called for with pci_map_single() and as such we were starving the swiotlb from its 64MB amount of bounce buffers. We remain consistent and now always use sc->rxbufsize for RX. While at it we update the beacon DMA maps as well to only use the data portion of the skb, previous to this we were pci_map_single()'ing more data for beaconing than what we tell the hardware it can use, therefore pushing more iotlb abuse. Still not sure why this is so easily triggerable on MacBook Pro 3.1, it may be the hardware configuration tends to use more memory > 3GB mark for DMA. Signed-off-by: Maciej Zenczykowski <zenczykowski@gmail.com> Signed-off-by: Bennyam Malavazi <Bennyam.Malavazi@atheros.com> Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath9k/beacon.c10
-rw-r--r--drivers/net/wireless/ath9k/recv.c6
2 files changed, 8 insertions, 8 deletions
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c
index 9e15c30bbc06..4dd1c1bda0fb 100644
--- a/drivers/net/wireless/ath9k/beacon.c
+++ b/drivers/net/wireless/ath9k/beacon.c
@@ -170,7 +170,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
170 skb = (struct sk_buff *)bf->bf_mpdu; 170 skb = (struct sk_buff *)bf->bf_mpdu;
171 if (skb) { 171 if (skb) {
172 pci_unmap_single(sc->pdev, bf->bf_dmacontext, 172 pci_unmap_single(sc->pdev, bf->bf_dmacontext,
173 skb_end_pointer(skb) - skb->head, 173 skb->len,
174 PCI_DMA_TODEVICE); 174 PCI_DMA_TODEVICE);
175 } 175 }
176 176
@@ -193,7 +193,7 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
193 193
194 bf->bf_buf_addr = bf->bf_dmacontext = 194 bf->bf_buf_addr = bf->bf_dmacontext =
195 pci_map_single(sc->pdev, skb->data, 195 pci_map_single(sc->pdev, skb->data,
196 skb_end_pointer(skb) - skb->head, 196 skb->len,
197 PCI_DMA_TODEVICE); 197 PCI_DMA_TODEVICE);
198 198
199 skb = ieee80211_get_buffered_bc(sc->hw, avp->av_if_data); 199 skb = ieee80211_get_buffered_bc(sc->hw, avp->av_if_data);
@@ -352,7 +352,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
352 if (bf->bf_mpdu != NULL) { 352 if (bf->bf_mpdu != NULL) {
353 skb = (struct sk_buff *)bf->bf_mpdu; 353 skb = (struct sk_buff *)bf->bf_mpdu;
354 pci_unmap_single(sc->pdev, bf->bf_dmacontext, 354 pci_unmap_single(sc->pdev, bf->bf_dmacontext,
355 skb_end_pointer(skb) - skb->head, 355 skb->len,
356 PCI_DMA_TODEVICE); 356 PCI_DMA_TODEVICE);
357 dev_kfree_skb_any(skb); 357 dev_kfree_skb_any(skb);
358 bf->bf_mpdu = NULL; 358 bf->bf_mpdu = NULL;
@@ -412,7 +412,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
412 412
413 bf->bf_buf_addr = bf->bf_dmacontext = 413 bf->bf_buf_addr = bf->bf_dmacontext =
414 pci_map_single(sc->pdev, skb->data, 414 pci_map_single(sc->pdev, skb->data,
415 skb_end_pointer(skb) - skb->head, 415 skb->len,
416 PCI_DMA_TODEVICE); 416 PCI_DMA_TODEVICE);
417 bf->bf_mpdu = skb; 417 bf->bf_mpdu = skb;
418 418
@@ -439,7 +439,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp)
439 if (bf->bf_mpdu != NULL) { 439 if (bf->bf_mpdu != NULL) {
440 struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu; 440 struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
441 pci_unmap_single(sc->pdev, bf->bf_dmacontext, 441 pci_unmap_single(sc->pdev, bf->bf_dmacontext,
442 skb_end_pointer(skb) - skb->head, 442 skb->len,
443 PCI_DMA_TODEVICE); 443 PCI_DMA_TODEVICE);
444 dev_kfree_skb_any(skb); 444 dev_kfree_skb_any(skb);
445 bf->bf_mpdu = NULL; 445 bf->bf_mpdu = NULL;
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c
index 4983402af559..ad5f88879dc4 100644
--- a/drivers/net/wireless/ath9k/recv.c
+++ b/drivers/net/wireless/ath9k/recv.c
@@ -456,7 +456,7 @@ static int ath_rx_indicate(struct ath_softc *sc,
456 if (nskb != NULL) { 456 if (nskb != NULL) {
457 bf->bf_mpdu = nskb; 457 bf->bf_mpdu = nskb;
458 bf->bf_buf_addr = pci_map_single(sc->pdev, nskb->data, 458 bf->bf_buf_addr = pci_map_single(sc->pdev, nskb->data,
459 skb_end_pointer(nskb) - nskb->head, 459 sc->sc_rxbufsize,
460 PCI_DMA_FROMDEVICE); 460 PCI_DMA_FROMDEVICE);
461 bf->bf_dmacontext = bf->bf_buf_addr; 461 bf->bf_dmacontext = bf->bf_buf_addr;
462 ATH_RX_CONTEXT(nskb)->ctx_rxbuf = bf; 462 ATH_RX_CONTEXT(nskb)->ctx_rxbuf = bf;
@@ -542,7 +542,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
542 542
543 bf->bf_mpdu = skb; 543 bf->bf_mpdu = skb;
544 bf->bf_buf_addr = pci_map_single(sc->pdev, skb->data, 544 bf->bf_buf_addr = pci_map_single(sc->pdev, skb->data,
545 skb_end_pointer(skb) - skb->head, 545 sc->sc_rxbufsize,
546 PCI_DMA_FROMDEVICE); 546 PCI_DMA_FROMDEVICE);
547 bf->bf_dmacontext = bf->bf_buf_addr; 547 bf->bf_dmacontext = bf->bf_buf_addr;
548 ATH_RX_CONTEXT(skb)->ctx_rxbuf = bf; 548 ATH_RX_CONTEXT(skb)->ctx_rxbuf = bf;
@@ -1007,7 +1007,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
1007 1007
1008 pci_dma_sync_single_for_cpu(sc->pdev, 1008 pci_dma_sync_single_for_cpu(sc->pdev,
1009 bf->bf_buf_addr, 1009 bf->bf_buf_addr,
1010 skb_tailroom(skb), 1010 sc->sc_rxbufsize,
1011 PCI_DMA_FROMDEVICE); 1011 PCI_DMA_FROMDEVICE);
1012 pci_unmap_single(sc->pdev, 1012 pci_unmap_single(sc->pdev,
1013 bf->bf_buf_addr, 1013 bf->bf_buf_addr,