aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding/bond_alb.c
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2012-06-11 19:23:07 +0000
committerDavid S. Miller <davem@davemloft.net>2012-06-12 18:51:09 -0700
commitde063b7040dcd9fbc9a1847fa44f0af13e19d6de (patch)
treed828ad11df0863ae1594be4461bfdbcb5388c4a8 /drivers/net/bonding/bond_alb.c
parentusbnet: don't initialize transfer buffer before submit status URB (diff)
downloadlinux-dev-de063b7040dcd9fbc9a1847fa44f0af13e19d6de.tar.xz
linux-dev-de063b7040dcd9fbc9a1847fa44f0af13e19d6de.zip
bonding: remove packet cloning in recv_probe()
Cloning all packets in input path have a significant cost. Use skb_header_pointer()/skb_copy_bits() instead of pskb_may_pull() so that recv_probe handlers (bond_3ad_lacpdu_recv / bond_arp_rcv / rlb_arp_recv ) dont touch input skb. bond_handle_frame() can avoid the skb_clone()/dev_kfree_skb() Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Jay Vosburgh <fubar@us.ibm.com> Cc: Andy Gospodarek <andy@greyhouse.net> Cc: Jiri Bohac <jbohac@suse.cz> Cc: Nicolas de Pesloüan <nicolas.2p.debian@free.fr> Cc: Maciej Żenczykowski <maze@google.com> Signed-off-by: Jay Vosburgh <fubar@us.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bonding/bond_alb.c')
-rw-r--r--drivers/net/bonding/bond_alb.c20
1 files changed, 5 insertions, 15 deletions
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 0f59c1564e53..ef3791a09ad8 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -342,27 +342,17 @@ static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp)
_unlock_rx_hashtbl_bh(bond);
}
-static int rlb_arp_recv(struct sk_buff *skb, struct bonding *bond,
- struct slave *slave)
+static int rlb_arp_recv(const struct sk_buff *skb, struct bonding *bond,
+ struct slave *slave)
{
- struct arp_pkt *arp;
+ struct arp_pkt *arp, _arp;
if (skb->protocol != cpu_to_be16(ETH_P_ARP))
goto out;
- arp = (struct arp_pkt *) skb->data;
- if (!arp) {
- pr_debug("Packet has no ARP data\n");
+ arp = skb_header_pointer(skb, 0, sizeof(_arp), &_arp);
+ if (!arp)
goto out;
- }
-
- if (!pskb_may_pull(skb, arp_hdr_len(bond->dev)))
- goto out;
-
- if (skb->len < sizeof(struct arp_pkt)) {
- pr_debug("Packet is too small to be an ARP\n");
- goto out;
- }
if (arp->op_code == htons(ARPOP_REPLY)) {
/* update rx hash table for this ARP */