Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 036dafa2 authored by Igor Maravic's avatar Igor Maravic Committed by Francois Romieu
Browse files

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: default avatarIgor Maravic <igorm@etf.rs>
Signed-off-by: default avatarFrancois Romieu <romieu@fr.zoreil.com>
Acked-by: default avatarEric Dumazet <eric.dumazet@gmail.com>
parent 8027aa24
Loading
Loading
Loading
Loading
+22 −5
Original line number Diff line number Diff line
@@ -5399,6 +5399,7 @@ static void rtl8169_tx_clear(struct rtl8169_private *tp)
{
	rtl8169_tx_clear_range(tp, tp->dirty_tx, NUM_TX_DESC);
	tp->cur_tx = tp->dirty_tx = 0;
	netdev_reset_queue(tp->dev);
}

static void rtl_reset_work(struct rtl8169_private *tp)
@@ -5553,6 +5554,8 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,

	txd->opts2 = cpu_to_le32(opts[1]);

	netdev_sent_queue(dev, skb->len);

	wmb();

	/* Anti gcc 2.95.3 bugware (sic) */
@@ -5647,9 +5650,16 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev)
	rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING);
}

struct rtl_txc {
	int packets;
	int bytes;
};

static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp)
{
	struct rtl8169_stats *tx_stats = &tp->tx_stats;
	unsigned int dirty_tx, tx_left;
	struct rtl_txc txc = { 0, 0 };

	dirty_tx = tp->dirty_tx;
	smp_rmb();
@@ -5668,17 +5678,24 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp)
		rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb,
				     tp->TxDescArray + entry);
		if (status & LastFrag) {
			u64_stats_update_begin(&tp->tx_stats.syncp);
			tp->tx_stats.packets++;
			tp->tx_stats.bytes += tx_skb->skb->len;
			u64_stats_update_end(&tp->tx_stats.syncp);
			dev_kfree_skb(tx_skb->skb);
			struct sk_buff *skb = tx_skb->skb;

			txc.packets++;
			txc.bytes += skb->len;
			dev_kfree_skb(skb);
			tx_skb->skb = NULL;
		}
		dirty_tx++;
		tx_left--;
	}

	u64_stats_update_begin(&tx_stats->syncp);
	tx_stats->packets += txc.packets;
	tx_stats->bytes += txc.bytes;
	u64_stats_update_end(&tx_stats->syncp);

	netdev_completed_queue(dev, txc.packets, txc.bytes);

	if (tp->dirty_tx != dirty_tx) {
		tp->dirty_tx = dirty_tx;
		/* Sync with rtl8169_start_xmit: