On Mon, 2016-09-12 at 15:13 -0700, John Fastabend wrote: > From: Alexei Starovoitov <a...@fb.com>
> +static void e1000_xmit_raw_frame(struct e1000_rx_buffer *rx_buffer_info, > + u32 len, > + struct net_device *netdev, > + struct e1000_adapter *adapter) > +{ > + struct netdev_queue *txq = netdev_get_tx_queue(netdev, 0); > + struct e1000_hw *hw = &adapter->hw; > + struct e1000_tx_ring *tx_ring; > + > + if (len > E1000_MAX_DATA_PER_TXD) > + return; > + > + /* e1000 only support a single txq at the moment so the queue is being > + * shared with stack. To support this requires locking to ensure the > + * stack and XDP are not running at the same time. Devices with > + * multiple queues should allocate a separate queue space. > + */ > + HARD_TX_LOCK(netdev, txq, smp_processor_id()); > + > + tx_ring = adapter->tx_ring; > + > + if (E1000_DESC_UNUSED(tx_ring) < 2) { > + HARD_TX_UNLOCK(netdev, txq); > + return; > + } > + > + if (netif_xmit_frozen_or_stopped(txq)) > + return; > + > + e1000_tx_map_rxpage(tx_ring, rx_buffer_info, len); > + netdev_sent_queue(netdev, len); > + e1000_tx_queue(adapter, tx_ring, 0/*tx_flags*/, 1); > + > + writel(tx_ring->next_to_use, hw->hw_addr + tx_ring->tdt); > + mmiowb(); > + > + HARD_TX_UNLOCK(netdev, txq); > +} e1000_tx_map() is full of workarounds. Have a look at last_tx_tso for example. /* Workaround for Controller erratum -- * descriptor for non-tso packet in a linear SKB that follows a * tso gets written back prematurely before the data is fully * DMA'd to the controller */ if (!skb->data_len && tx_ring->last_tx_tso && !skb_is_gso(skb)) { tx_ring->last_tx_tso = false; size -= 4; } Look, this XDP_TX thing is hard to properly implement and test on various NIC revisions. Without proper queue management, high prio packets in qdisc wont be sent if NIC is under RX -> XDP_TX flood. Sounds a horrible feature to me.