aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2007-08-22 10:13:03 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:50:58 -0400
commit02df6cfa09c2ccebe685bfd54a708e1f50b00a81 (patch)
tree77007f4a80ab5aa779d344e22f187af63ddd0f2d /drivers/net
parent26fcfa95aef980cab4ff1ea55979c30e772dd0dd (diff)
pasemi_mac: Batch up TX buffer frees
Postpone pci unmap and skb free of the transmitted buffers to outside of the tx ring lock, batching them up 32 at a time. Also increase the count threshold to 128. Signed-off-by: Olof Johansson <olof@lixom.net> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/pasemi_mac.c39
1 files changed, 29 insertions, 10 deletions
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
index f71a6864cdc2..4836d405cd5d 100644
--- a/drivers/net/pasemi_mac.c
+++ b/drivers/net/pasemi_mac.c
@@ -551,37 +551,56 @@ static int pasemi_mac_clean_tx(struct pasemi_mac *mac)
551 int i; 551 int i;
552 struct pasemi_mac_buffer *info; 552 struct pasemi_mac_buffer *info;
553 struct pas_dma_xct_descr *dp; 553 struct pas_dma_xct_descr *dp;
554 int start, count; 554 unsigned int start, count, limit;
555 unsigned int total_count;
555 int flags; 556 int flags;
557 struct sk_buff *skbs[32];
558 dma_addr_t dmas[32];
556 559
560 total_count = 0;
561restart:
557 spin_lock_irqsave(&mac->tx->lock, flags); 562 spin_lock_irqsave(&mac->tx->lock, flags);
558 563
559 start = mac->tx->next_to_clean; 564 start = mac->tx->next_to_clean;
565 limit = min(mac->tx->next_to_use, start+32);
566
560 count = 0; 567 count = 0;
561 568
562 for (i = start; i < mac->tx->next_to_use; i++) { 569 for (i = start; i < limit; i++) {
563 dp = &TX_DESC(mac, i); 570 dp = &TX_DESC(mac, i);
571
564 if (unlikely(dp->mactx & XCT_MACTX_O)) 572 if (unlikely(dp->mactx & XCT_MACTX_O))
573 /* Not yet transmitted */
565 break; 574 break;
566 575
567 count++;
568
569 info = &TX_DESC_INFO(mac, i); 576 info = &TX_DESC_INFO(mac, i);
570 577 skbs[count] = info->skb;
571 pci_unmap_single(mac->dma_pdev, info->dma, 578 dmas[count] = info->dma;
572 info->skb->len, PCI_DMA_TODEVICE);
573 dev_kfree_skb_irq(info->skb);
574 579
575 info->skb = NULL; 580 info->skb = NULL;
576 info->dma = 0; 581 info->dma = 0;
577 dp->mactx = 0; 582 dp->mactx = 0;
578 dp->ptr = 0; 583 dp->ptr = 0;
584
585 count++;
579 } 586 }
580 mac->tx->next_to_clean += count; 587 mac->tx->next_to_clean += count;
581 spin_unlock_irqrestore(&mac->tx->lock, flags); 588 spin_unlock_irqrestore(&mac->tx->lock, flags);
582 netif_wake_queue(mac->netdev); 589 netif_wake_queue(mac->netdev);
583 590
584 return count; 591 for (i = 0; i < count; i++) {
592 pci_unmap_single(mac->dma_pdev, dmas[i],
593 skbs[i]->len, PCI_DMA_TODEVICE);
594 dev_kfree_skb_irq(skbs[i]);
595 }
596
597 total_count += count;
598
599 /* If the batch was full, try to clean more */
600 if (count == 32)
601 goto restart;
602
603 return total_count;
585} 604}
586 605
587 606
@@ -777,7 +796,7 @@ static int pasemi_mac_open(struct net_device *dev)
777 PAS_IOB_DMA_RXCH_CFG_CNTTH(0)); 796 PAS_IOB_DMA_RXCH_CFG_CNTTH(0));
778 797
779 write_iob_reg(mac, PAS_IOB_DMA_TXCH_CFG(mac->dma_txch), 798 write_iob_reg(mac, PAS_IOB_DMA_TXCH_CFG(mac->dma_txch),
780 PAS_IOB_DMA_TXCH_CFG_CNTTH(32)); 799 PAS_IOB_DMA_TXCH_CFG_CNTTH(128));
781 800
782 /* Clear out any residual packet count state from firmware */ 801 /* Clear out any residual packet count state from firmware */
783 pasemi_mac_restart_rx_intr(mac); 802 pasemi_mac_restart_rx_intr(mac);