nfp: reorganize nfp_net_rx() to get packet offsets early
authorJakub Kicinski <jakub.kicinski@netronome.com>
Thu, 3 Nov 2016 17:12:05 +0000 (17:12 +0000)
committerDavid S. Miller <davem@davemloft.net>
Fri, 4 Nov 2016 18:56:15 +0000 (14:56 -0400)
Calculate packet offsets early in nfp_net_rx() so that we will be
able to use them in upcoming XDP handler.  While at it move relevant
variables into the loop scope.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/netronome/nfp/nfp_net_common.c

index 506362729607c29bf393b937e0f7730148eb9523..2ab63661a6fdd149100ecab9f329a78f80cbe324 100644 (file)
@@ -1383,16 +1383,17 @@ static int nfp_net_rx(struct nfp_net_rx_ring *rx_ring, int budget)
 {
        struct nfp_net_r_vector *r_vec = rx_ring->r_vec;
        struct nfp_net *nn = r_vec->nfp_net;
-       unsigned int data_len, meta_len;
-       struct nfp_net_rx_buf *rxbuf;
-       struct nfp_net_rx_desc *rxd;
-       dma_addr_t new_dma_addr;
        struct sk_buff *skb;
        int pkts_polled = 0;
-       void *new_frag;
        int idx;
 
        while (pkts_polled < budget) {
+               unsigned int meta_len, data_len, data_off, pkt_len, pkt_off;
+               struct nfp_net_rx_buf *rxbuf;
+               struct nfp_net_rx_desc *rxd;
+               dma_addr_t new_dma_addr;
+               void *new_frag;
+
                idx = rx_ring->rd_p & (rx_ring->cnt - 1);
 
                rxd = &rx_ring->rxds[idx];
@@ -1408,22 +1409,6 @@ static int nfp_net_rx(struct nfp_net_rx_ring *rx_ring, int budget)
                pkts_polled++;
 
                rxbuf = &rx_ring->rxbufs[idx];
-               skb = build_skb(rxbuf->frag, nn->fl_bufsz);
-               if (unlikely(!skb)) {
-                       nfp_net_rx_drop(r_vec, rx_ring, rxbuf, NULL);
-                       continue;
-               }
-               new_frag = nfp_net_napi_alloc_one(nn, &new_dma_addr);
-               if (unlikely(!new_frag)) {
-                       nfp_net_rx_drop(r_vec, rx_ring, rxbuf, skb);
-                       continue;
-               }
-
-               nfp_net_dma_unmap_rx(nn, rx_ring->rxbufs[idx].dma_addr,
-                                    nn->fl_bufsz, DMA_FROM_DEVICE);
-
-               nfp_net_rx_give_one(rx_ring, new_frag, new_dma_addr);
-
                /*         < meta_len >
                 *  <-- [rx_offset] -->
                 *  ---------------------------------------------------------
@@ -1438,20 +1423,39 @@ static int nfp_net_rx(struct nfp_net_rx_ring *rx_ring, int budget)
                 */
                meta_len = rxd->rxd.meta_len_dd & PCIE_DESC_RX_META_LEN_MASK;
                data_len = le16_to_cpu(rxd->rxd.data_len);
+               pkt_len = data_len - meta_len;
 
                if (nn->rx_offset == NFP_NET_CFG_RX_OFFSET_DYNAMIC)
-                       skb_reserve(skb, NFP_NET_RX_BUF_HEADROOM + meta_len);
+                       pkt_off = meta_len;
                else
-                       skb_reserve(skb,
-                                   NFP_NET_RX_BUF_HEADROOM + nn->rx_offset);
-               skb_put(skb, data_len - meta_len);
+                       pkt_off = nn->rx_offset;
+               data_off = NFP_NET_RX_BUF_HEADROOM + pkt_off;
 
                /* Stats update */
                u64_stats_update_begin(&r_vec->rx_sync);
                r_vec->rx_pkts++;
-               r_vec->rx_bytes += skb->len;
+               r_vec->rx_bytes += pkt_len;
                u64_stats_update_end(&r_vec->rx_sync);
 
+               skb = build_skb(rxbuf->frag, nn->fl_bufsz);
+               if (unlikely(!skb)) {
+                       nfp_net_rx_drop(r_vec, rx_ring, rxbuf, NULL);
+                       continue;
+               }
+               new_frag = nfp_net_napi_alloc_one(nn, &new_dma_addr);
+               if (unlikely(!new_frag)) {
+                       nfp_net_rx_drop(r_vec, rx_ring, rxbuf, skb);
+                       continue;
+               }
+
+               nfp_net_dma_unmap_rx(nn, rx_ring->rxbufs[idx].dma_addr,
+                                    nn->fl_bufsz, DMA_FROM_DEVICE);
+
+               nfp_net_rx_give_one(rx_ring, new_frag, new_dma_addr);
+
+               skb_reserve(skb, data_off);
+               skb_put(skb, pkt_len);
+
                if (nn->fw_ver.major <= 3) {
                        nfp_net_set_hash_desc(nn->netdev, skb, rxd);
                } else if (meta_len) {