@@ -927,6 +927,34 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
return NULL;
}
+static struct sk_buff *receive_small_build_skb(struct virtnet_info *vi,
+ unsigned int xdp_headroom,
+ void *buf,
+ unsigned int len)
+{
+ unsigned int header_offset;
+ unsigned int headroom;
+ unsigned int buflen;
+ struct sk_buff *skb;
+
+ header_offset = VIRTNET_RX_PAD + xdp_headroom;
+ headroom = vi->hdr_len + header_offset;
+ buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+
+ skb = build_skb(buf, buflen);
+ if (!skb)
+ return NULL;
+
+ skb_reserve(skb, headroom);
+ skb_put(skb, len);
+
+ buf += header_offset;
+ memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
+
+ return skb;
+}
+
static struct sk_buff *receive_small_xdp(struct net_device *dev,
struct virtnet_info *vi,
struct receive_queue *rq,
@@ -1026,9 +1054,6 @@ static struct sk_buff *receive_small(struct net_device *dev,
{
unsigned int xdp_headroom = (unsigned long)ctx;
struct page *page = virt_to_head_page(buf);
- unsigned int header_offset;
- unsigned int headroom;
- unsigned int buflen;
struct sk_buff *skb;
len -= vi->hdr_len;
@@ -1056,20 +1081,9 @@ static struct sk_buff *receive_small(struct net_device *dev,
rcu_read_unlock();
}
- header_offset = VIRTNET_RX_PAD + xdp_headroom;
- headroom = vi->hdr_len + header_offset;
- buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
- SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
-
- skb = build_skb(buf, buflen);
- if (!skb)
- goto err;
- skb_reserve(skb, headroom);
- skb_put(skb, len);
-
- buf += header_offset;
- memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
- return skb;
+ skb = receive_small_build_skb(vi, xdp_headroom, buf, len);
+ if (likely(skb))
+ return skb;
err:
stats->drops++;