On Thu, 29 Aug 2019 11:27:16 -0700, Shannon Nelson wrote:
> +netdev_tx_t ionic_start_xmit(struct sk_buff *skb, struct net_device *netdev)
> +{
> + u16 queue_index = skb_get_queue_mapping(skb);
> + struct ionic_lif *lif = netdev_priv(netdev);
> + struct ionic_queue *q;
> + int ndescs;
> + int err;
> +
> + if (unlikely(!test_bit(IONIC_LIF_UP, lif->state))) {
> + dev_kfree_skb(skb);
> + return NETDEV_TX_OK;
> + }
> +
> + if (likely(lif_to_txqcq(lif, queue_index)))
> + q = lif_to_txq(lif, queue_index);
> + else
> + q = lif_to_txq(lif, 0);
> +
> + ndescs = ionic_tx_descs_needed(q, skb);
> + if (ndescs < 0)
> + goto err_out_drop;
> +
> + if (!ionic_q_has_space(q, ndescs)) {
You should stop the queue in advance, whenever you can't ensure that a
max size frame can be placed on the ring. Requeuing is very expensive
so modern drivers should try to never return NETDEV_TX_BUSY
> + netif_stop_subqueue(netdev, queue_index);
> + q->stop++;
> +
> + /* Might race with ionic_tx_clean, check again */
> + smp_rmb();
> + if (ionic_q_has_space(q, ndescs)) {
> + netif_wake_subqueue(netdev, queue_index);
> + q->wake++;
> + } else {
> + return NETDEV_TX_BUSY;
> + }
> + }
> +
> + if (skb_is_gso(skb))
> + err = ionic_tx_tso(q, skb);
> + else
> + err = ionic_tx(q, skb);
> +
> + if (err)
> + goto err_out_drop;
> +
> + return NETDEV_TX_OK;
> +
> +err_out_drop:
> + netif_stop_subqueue(netdev, queue_index);
This stopping of the queue is suspicious, if ionic_tx() fails there's
no guarantee the queue will ever be woken up, no?
> + q->stop++;
> + q->drop++;
> + dev_kfree_skb(skb);
> + return NETDEV_TX_OK;
> +}