Commit c2837423 authored by Jose Abreu's avatar Jose Abreu Committed by David S. Miller
Browse files

net: stmmac: Rework TX Coalesce logic



Coalesce logic currently increments the number of packets and sets the
IC bit when the coalesced packets have passed a given limit. This does
not reflect very well what coalesce was meant for as we can have a large
number of packets that are coalesced and then a single one, sent later
on that has the IC bit.

Rework the logic so that it coalesces only upon a limit of packets and
sets the IC bit for large number of packets.

Signed-off-by: default avatarJose Abreu <Jose.Abreu@synopsys.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent da202451
Loading
Loading
Loading
Loading
+42 −19
Original line number Diff line number Diff line
@@ -2916,16 +2916,17 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
	struct stmmac_priv *priv = netdev_priv(dev);
	int nfrags = skb_shinfo(skb)->nr_frags;
	u32 queue = skb_get_queue_mapping(skb);
	unsigned int first_entry, tx_packets;
	int tmp_pay_len = 0, first_tx;
	struct stmmac_tx_queue *tx_q;
	unsigned int first_entry;
	u8 proto_hdr_len, hdr;
	int tmp_pay_len = 0;
	bool has_vlan, set_ic;
	u32 pay_len, mss;
	dma_addr_t des;
	bool has_vlan;
	int i;

	tx_q = &priv->tx_queue[queue];
	first_tx = tx_q->cur_tx;

	/* Compute header lengths */
	if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4) {
@@ -3033,16 +3034,27 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
	tx_q->tx_skbuff[tx_q->cur_tx] = skb;

	/* Manage tx mitigation */
	tx_q->tx_count_frames += nfrags + 1;
	if (likely(priv->tx_coal_frames > tx_q->tx_count_frames) &&
	    !((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
	      priv->hwts_tx_en)) {
		stmmac_tx_timer_arm(priv, queue);
	} else {
	tx_packets = (tx_q->cur_tx + 1) - first_tx;
	tx_q->tx_count_frames += tx_packets;

	if ((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) && priv->hwts_tx_en)
		set_ic = true;
	else if (!priv->tx_coal_frames)
		set_ic = false;
	else if (tx_packets > priv->tx_coal_frames)
		set_ic = true;
	else if ((tx_q->tx_count_frames % priv->tx_coal_frames) < tx_packets)
		set_ic = true;
	else
		set_ic = false;

	if (set_ic) {
		desc = &tx_q->dma_tx[tx_q->cur_tx];
		tx_q->tx_count_frames = 0;
		stmmac_set_tx_ic(priv, desc);
		priv->xstats.tx_set_ic_bit++;
	} else {
		stmmac_tx_timer_arm(priv, queue);
	}

	/* We've used all descriptors we need for this skb, however,
@@ -3133,6 +3145,7 @@ dma_map_err:
 */
static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
{
	unsigned int first_entry, tx_packets, enh_desc;
	struct stmmac_priv *priv = netdev_priv(dev);
	unsigned int nopaged_len = skb_headlen(skb);
	int i, csum_insertion = 0, is_jumbo = 0;
@@ -3141,13 +3154,12 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
	int gso = skb_shinfo(skb)->gso_type;
	struct dma_desc *desc, *first;
	struct stmmac_tx_queue *tx_q;
	unsigned int first_entry;
	unsigned int enh_desc;
	bool has_vlan, set_ic;
	int entry, first_tx;
	dma_addr_t des;
	bool has_vlan;
	int entry;

	tx_q = &priv->tx_queue[queue];
	first_tx = tx_q->cur_tx;

	if (priv->tx_path_in_lpi_mode)
		stmmac_disable_eee_mode(priv);
@@ -3241,12 +3253,21 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
	 * This approach takes care about the fragments: desc is the first
	 * element in case of no SG.
	 */
	tx_q->tx_count_frames += nfrags + 1;
	if (likely(priv->tx_coal_frames > tx_q->tx_count_frames) &&
	    !((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
	      priv->hwts_tx_en)) {
		stmmac_tx_timer_arm(priv, queue);
	} else {
	tx_packets = (entry + 1) - first_tx;
	tx_q->tx_count_frames += tx_packets;

	if ((skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) && priv->hwts_tx_en)
		set_ic = true;
	else if (!priv->tx_coal_frames)
		set_ic = false;
	else if (tx_packets > priv->tx_coal_frames)
		set_ic = true;
	else if ((tx_q->tx_count_frames % priv->tx_coal_frames) < tx_packets)
		set_ic = true;
	else
		set_ic = false;

	if (set_ic) {
		if (likely(priv->extend_desc))
			desc = &tx_q->dma_etx[entry].basic;
		else
@@ -3255,6 +3276,8 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
		tx_q->tx_count_frames = 0;
		stmmac_set_tx_ic(priv, desc);
		priv->xstats.tx_set_ic_bit++;
	} else {
		stmmac_tx_timer_arm(priv, queue);
	}

	/* We've used all descriptors we need for this skb, however,