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;
> +}

Reply via email to