diff options
author | Paolo Abeni <pabeni@redhat.com> | 2016-09-30 10:56:45 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-10-03 01:29:57 -0400 |
commit | 63d75463c91a5b5be7c0aca11ceb45ea5a0ae81d (patch) | |
tree | 57c39b309be4ed7e304e956d3fb0035d2a291e00 /net/core/pktgen.c | |
parent | b82d44d78480faff7456e9e0999acb9d38666057 (diff) |
net: pktgen: fix pkt_size
The commit 879c7220e828 ("net: pktgen: Observe needed_headroom
of the device") increased the 'pkt_overhead' field value by
LL_RESERVED_SPACE.
As a side effect the generated packet size, computed as:
/* Eth + IPh + UDPh + mpls */
datalen = pkt_dev->cur_pkt_size - 14 - 20 - 8 -
pkt_dev->pkt_overhead;
is decreased by the same value.
The above changed slightly the behavior of existing pktgen users,
and made the procfs interface somewhat inconsistent.
Fix it by restoring the previous pkt_overhead value and using
LL_RESERVED_SPACE as extralen in skb allocation.
Also, change pktgen_alloc_skb() to only partially reserve
the headroom to allow the caller to prefetch from ll header
start.
v1 -> v2:
- fixed some typos in the comments
Fixes: 879c7220e828 ("net: pktgen: Observe needed_headroom of the device")
Suggested-by: Ben Greear <greearb@candelatech.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/pktgen.c')
-rw-r--r-- | net/core/pktgen.c | 21 |
1 files changed, 10 insertions, 11 deletions
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index bbd118b19aef..5219a9e2127a 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
@@ -2286,7 +2286,7 @@ out: | |||
2286 | 2286 | ||
2287 | static inline void set_pkt_overhead(struct pktgen_dev *pkt_dev) | 2287 | static inline void set_pkt_overhead(struct pktgen_dev *pkt_dev) |
2288 | { | 2288 | { |
2289 | pkt_dev->pkt_overhead = LL_RESERVED_SPACE(pkt_dev->odev); | 2289 | pkt_dev->pkt_overhead = 0; |
2290 | pkt_dev->pkt_overhead += pkt_dev->nr_labels*sizeof(u32); | 2290 | pkt_dev->pkt_overhead += pkt_dev->nr_labels*sizeof(u32); |
2291 | pkt_dev->pkt_overhead += VLAN_TAG_SIZE(pkt_dev); | 2291 | pkt_dev->pkt_overhead += VLAN_TAG_SIZE(pkt_dev); |
2292 | pkt_dev->pkt_overhead += SVLAN_TAG_SIZE(pkt_dev); | 2292 | pkt_dev->pkt_overhead += SVLAN_TAG_SIZE(pkt_dev); |
@@ -2777,13 +2777,13 @@ static void pktgen_finalize_skb(struct pktgen_dev *pkt_dev, struct sk_buff *skb, | |||
2777 | } | 2777 | } |
2778 | 2778 | ||
2779 | static struct sk_buff *pktgen_alloc_skb(struct net_device *dev, | 2779 | static struct sk_buff *pktgen_alloc_skb(struct net_device *dev, |
2780 | struct pktgen_dev *pkt_dev, | 2780 | struct pktgen_dev *pkt_dev) |
2781 | unsigned int extralen) | ||
2782 | { | 2781 | { |
2782 | unsigned int extralen = LL_RESERVED_SPACE(dev); | ||
2783 | struct sk_buff *skb = NULL; | 2783 | struct sk_buff *skb = NULL; |
2784 | unsigned int size = pkt_dev->cur_pkt_size + 64 + extralen + | 2784 | unsigned int size; |
2785 | pkt_dev->pkt_overhead; | ||
2786 | 2785 | ||
2786 | size = pkt_dev->cur_pkt_size + 64 + extralen + pkt_dev->pkt_overhead; | ||
2787 | if (pkt_dev->flags & F_NODE) { | 2787 | if (pkt_dev->flags & F_NODE) { |
2788 | int node = pkt_dev->node >= 0 ? pkt_dev->node : numa_node_id(); | 2788 | int node = pkt_dev->node >= 0 ? pkt_dev->node : numa_node_id(); |
2789 | 2789 | ||
@@ -2796,8 +2796,9 @@ static struct sk_buff *pktgen_alloc_skb(struct net_device *dev, | |||
2796 | skb = __netdev_alloc_skb(dev, size, GFP_NOWAIT); | 2796 | skb = __netdev_alloc_skb(dev, size, GFP_NOWAIT); |
2797 | } | 2797 | } |
2798 | 2798 | ||
2799 | /* the caller pre-fetches from skb->data and reserves for the mac hdr */ | ||
2799 | if (likely(skb)) | 2800 | if (likely(skb)) |
2800 | skb_reserve(skb, LL_RESERVED_SPACE(dev)); | 2801 | skb_reserve(skb, extralen - 16); |
2801 | 2802 | ||
2802 | return skb; | 2803 | return skb; |
2803 | } | 2804 | } |
@@ -2830,16 +2831,14 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev, | |||
2830 | mod_cur_headers(pkt_dev); | 2831 | mod_cur_headers(pkt_dev); |
2831 | queue_map = pkt_dev->cur_queue_map; | 2832 | queue_map = pkt_dev->cur_queue_map; |
2832 | 2833 | ||
2833 | datalen = (odev->hard_header_len + 16) & ~0xf; | 2834 | skb = pktgen_alloc_skb(odev, pkt_dev); |
2834 | |||
2835 | skb = pktgen_alloc_skb(odev, pkt_dev, datalen); | ||
2836 | if (!skb) { | 2835 | if (!skb) { |
2837 | sprintf(pkt_dev->result, "No memory"); | 2836 | sprintf(pkt_dev->result, "No memory"); |
2838 | return NULL; | 2837 | return NULL; |
2839 | } | 2838 | } |
2840 | 2839 | ||
2841 | prefetchw(skb->data); | 2840 | prefetchw(skb->data); |
2842 | skb_reserve(skb, datalen); | 2841 | skb_reserve(skb, 16); |
2843 | 2842 | ||
2844 | /* Reserve for ethernet and IP header */ | 2843 | /* Reserve for ethernet and IP header */ |
2845 | eth = (__u8 *) skb_push(skb, 14); | 2844 | eth = (__u8 *) skb_push(skb, 14); |
@@ -2959,7 +2958,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev, | |||
2959 | mod_cur_headers(pkt_dev); | 2958 | mod_cur_headers(pkt_dev); |
2960 | queue_map = pkt_dev->cur_queue_map; | 2959 | queue_map = pkt_dev->cur_queue_map; |
2961 | 2960 | ||
2962 | skb = pktgen_alloc_skb(odev, pkt_dev, 16); | 2961 | skb = pktgen_alloc_skb(odev, pkt_dev); |
2963 | if (!skb) { | 2962 | if (!skb) { |
2964 | sprintf(pkt_dev->result, "No memory"); | 2963 | sprintf(pkt_dev->result, "No memory"); |
2965 | return NULL; | 2964 | return NULL; |