diff options
author | Igor Maravic <igorm@etf.rs> | 2012-03-04 18:01:25 -0500 |
---|---|---|
committer | Francois Romieu <romieu@fr.zoreil.com> | 2012-03-05 18:24:26 -0500 |
commit | 036dafa28da1e2565a8529de2ae663c37b7a0060 (patch) | |
tree | 97df33f26323d324964412939aa2b60dd15c7b88 | |
parent | 8027aa245bbd125350f6a78c5a78771d143aba55 (diff) |
r8169: add byte queue limit support.
Nothing fancy:
- sent bytes count is notified in the start_xmit path right before
updating the owner bit in the hardware Tx descriptor (E. Dumazet)
- avoid useless tp->dev dereferencing in start_xmit (E. Dumazet)
Use of netdev_reset_queue is favored over proper accounting in
rtl8169_tx_clear_range since the latter would need more work for the
same result (nb: said accounting degenerates to nothing in xmit_frags).
Signed-off-by: Igor Maravic <igorm@etf.rs>
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
-rw-r--r-- | drivers/net/ethernet/realtek/r8169.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index a4d7674886a2..515a7edb605c 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c | |||
@@ -5399,6 +5399,7 @@ static void rtl8169_tx_clear(struct rtl8169_private *tp) | |||
5399 | { | 5399 | { |
5400 | rtl8169_tx_clear_range(tp, tp->dirty_tx, NUM_TX_DESC); | 5400 | rtl8169_tx_clear_range(tp, tp->dirty_tx, NUM_TX_DESC); |
5401 | tp->cur_tx = tp->dirty_tx = 0; | 5401 | tp->cur_tx = tp->dirty_tx = 0; |
5402 | netdev_reset_queue(tp->dev); | ||
5402 | } | 5403 | } |
5403 | 5404 | ||
5404 | static void rtl_reset_work(struct rtl8169_private *tp) | 5405 | static void rtl_reset_work(struct rtl8169_private *tp) |
@@ -5553,6 +5554,8 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, | |||
5553 | 5554 | ||
5554 | txd->opts2 = cpu_to_le32(opts[1]); | 5555 | txd->opts2 = cpu_to_le32(opts[1]); |
5555 | 5556 | ||
5557 | netdev_sent_queue(dev, skb->len); | ||
5558 | |||
5556 | wmb(); | 5559 | wmb(); |
5557 | 5560 | ||
5558 | /* Anti gcc 2.95.3 bugware (sic) */ | 5561 | /* Anti gcc 2.95.3 bugware (sic) */ |
@@ -5647,9 +5650,16 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev) | |||
5647 | rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); | 5650 | rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); |
5648 | } | 5651 | } |
5649 | 5652 | ||
5653 | struct rtl_txc { | ||
5654 | int packets; | ||
5655 | int bytes; | ||
5656 | }; | ||
5657 | |||
5650 | static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp) | 5658 | static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp) |
5651 | { | 5659 | { |
5660 | struct rtl8169_stats *tx_stats = &tp->tx_stats; | ||
5652 | unsigned int dirty_tx, tx_left; | 5661 | unsigned int dirty_tx, tx_left; |
5662 | struct rtl_txc txc = { 0, 0 }; | ||
5653 | 5663 | ||
5654 | dirty_tx = tp->dirty_tx; | 5664 | dirty_tx = tp->dirty_tx; |
5655 | smp_rmb(); | 5665 | smp_rmb(); |
@@ -5668,17 +5678,24 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp) | |||
5668 | rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb, | 5678 | rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb, |
5669 | tp->TxDescArray + entry); | 5679 | tp->TxDescArray + entry); |
5670 | if (status & LastFrag) { | 5680 | if (status & LastFrag) { |
5671 | u64_stats_update_begin(&tp->tx_stats.syncp); | 5681 | struct sk_buff *skb = tx_skb->skb; |
5672 | tp->tx_stats.packets++; | 5682 | |
5673 | tp->tx_stats.bytes += tx_skb->skb->len; | 5683 | txc.packets++; |
5674 | u64_stats_update_end(&tp->tx_stats.syncp); | 5684 | txc.bytes += skb->len; |
5675 | dev_kfree_skb(tx_skb->skb); | 5685 | dev_kfree_skb(skb); |
5676 | tx_skb->skb = NULL; | 5686 | tx_skb->skb = NULL; |
5677 | } | 5687 | } |
5678 | dirty_tx++; | 5688 | dirty_tx++; |
5679 | tx_left--; | 5689 | tx_left--; |
5680 | } | 5690 | } |
5681 | 5691 | ||
5692 | u64_stats_update_begin(&tx_stats->syncp); | ||
5693 | tx_stats->packets += txc.packets; | ||
5694 | tx_stats->bytes += txc.bytes; | ||
5695 | u64_stats_update_end(&tx_stats->syncp); | ||
5696 | |||
5697 | netdev_completed_queue(dev, txc.packets, txc.bytes); | ||
5698 | |||
5682 | if (tp->dirty_tx != dirty_tx) { | 5699 | if (tp->dirty_tx != dirty_tx) { |
5683 | tp->dirty_tx = dirty_tx; | 5700 | tp->dirty_tx = dirty_tx; |
5684 | /* Sync with rtl8169_start_xmit: | 5701 | /* Sync with rtl8169_start_xmit: |