diff options
author | Olof Johansson <olof@lixom.net> | 2007-08-22 10:13:03 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:50:58 -0400 |
commit | 02df6cfa09c2ccebe685bfd54a708e1f50b00a81 (patch) | |
tree | 77007f4a80ab5aa779d344e22f187af63ddd0f2d /drivers/net/pasemi_mac.c | |
parent | 26fcfa95aef980cab4ff1ea55979c30e772dd0dd (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/pasemi_mac.c')
-rw-r--r-- | drivers/net/pasemi_mac.c | 39 |
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; | ||
561 | restart: | ||
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); |