On Mon, 2016-09-12 at 09:21 -0700, Tom Herbert wrote:
> In order to use XDP with non multi-queue drivers (such as e1000) we need
> a method to handle XDP_TX return code from xdp program. Since there is
> only one queue the XDP transmit path needs to share that queue with the
> normal stack path, and in order to do that we can't break the existing
> stack's mechanisms of locking, qdiscs, and BQL for the queue.
> 
> This patch allocates an skbuff when XDP_TX is returned from the XDP
> program and call dev_queue_xmit to transmit the skbuff.
> 
> Note that this is expected to be a performance hit (which needs to be
> quantified) relative to a MQ XDP implementation where we can reserve
> queues to be used by XDP. The first intent of these patches is
> correctness. This should not affect performance in the XDP_DROP path.
> 
> This patch needs to be applied after "e1000: add initial XDP support".
> 
> Tested: I've only built this, need to see if I can find some e1000
> machines. John, if you could try this that would be much appreciated.
> 
> Signed-off-by: Tom Herbert <t...@herbertland.com>
> ---
>  drivers/net/ethernet/intel/e1000/e1000_main.c | 29 
> ++++++++++++++++++++-------
>  1 file changed, 22 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c 
> b/drivers/net/ethernet/intel/e1000/e1000_main.c
> index 91d5c87..f457ea8 100644
> --- a/drivers/net/ethernet/intel/e1000/e1000_main.c
> +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c
> @@ -4338,13 +4338,28 @@ static bool e1000_clean_jumbo_rx_irq(struct 
> e1000_adapter *adapter,
>                       case XDP_PASS:
>                               break;
>                       case XDP_TX:
> -                             dma_sync_single_for_device(&pdev->dev,
> -                                                        dma,
> -                                                        length,
> -                                                        DMA_TO_DEVICE);
> -                             e1000_xmit_raw_frame(buffer_info, length,
> -                                                  netdev, adapter);
> -                             buffer_info->rxbuf.page = NULL;
> +                             /* There is only one transmit queue so we need
> +                              * to inject the packet at the qdisc layer
> +                              * to maintain sanity in the stack. We allocate
> +                              * an skbuff, set up frags with the page, and
> +                              * then do dev_queue_xmit.
> +                              */
> +                             skb = alloc_skb(0, GFP_ATOMIC);
> +                             if (skb) {
> +                                     dma_unmap_page(&pdev->dev,
> +                                                    buffer_info->dma,
> +                                                    adapter->rx_buffer_len,
> +                                                    DMA_FROM_DEVICE);
> +                                     skb->dev = netdev;
> +                                     skb_fill_page_desc(skb, 0,
> +                                             buffer_info->rxbuf.page,
> +                                             0, length);
> +                                     dev_queue_xmit(skb);
> +                                     goto next_desc;
> +                             }
> +                             /* Fallthrough, if we are unable to handle
> +                              * XDP_TX then we need to drop.
> +                              */
>                       case XDP_DROP:
>                       default:
>                               /* re-use mapped page. keep buffer_info->dma

If the intent is correctness, then you'll need to populate skb->len and
skb->data_len.

Also many drivers assume some headers are in skb->head.

e1000 seems to assume skb_headlen() can not be 0




Reply via email to