Commit 8c838f53 authored by Ioana Ciornei's avatar Ioana Ciornei Committed by David S. Miller
Browse files

dpaa2-eth: fix race condition with bql frame accounting



It might happen that Tx conf acknowledges a frame before it was
subscribed in bql, as subscribing was previously done after the enqueue
operation.

This patch moves the netdev_tx_sent_queue call before the actual frame
enqueue, so that this can never happen.

Fixes: 569dac6a ("dpaa2-eth: bql support")
Signed-off-by: default avatarIoana Ciornei <ioana.ciornei@nxp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 047a013f
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line
@@ -815,6 +815,14 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct net_device *net_dev)
	 */
	queue_mapping = skb_get_queue_mapping(skb);
	fq = &priv->fq[queue_mapping];

	fd_len = dpaa2_fd_get_len(&fd);
	nq = netdev_get_tx_queue(net_dev, queue_mapping);
	netdev_tx_sent_queue(nq, fd_len);

	/* Everything that happens after this enqueues might race with
	 * the Tx confirmation callback for this frame
	 */
	for (i = 0; i < DPAA2_ETH_ENQUEUE_RETRIES; i++) {
		err = priv->enqueue(priv, fq, &fd, 0);
		if (err != -EBUSY)
@@ -825,13 +833,10 @@ static netdev_tx_t dpaa2_eth_tx(struct sk_buff *skb, struct net_device *net_dev)
		percpu_stats->tx_errors++;
		/* Clean up everything, including freeing the skb */
		free_tx_fd(priv, fq, &fd, false);
		netdev_tx_completed_queue(nq, 1, fd_len);
	} else {
		fd_len = dpaa2_fd_get_len(&fd);
		percpu_stats->tx_packets++;
		percpu_stats->tx_bytes += fd_len;

		nq = netdev_get_tx_queue(net_dev, queue_mapping);
		netdev_tx_sent_queue(nq, fd_len);
	}

	return NETDEV_TX_OK;