diff options
author | Changli Gao <xiaosuo@gmail.com> | 2011-02-22 01:55:18 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-02-28 12:28:50 -0800 |
commit | 696ea472e19c6d1fa843bb1abce73b9c3a414391 (patch) | |
tree | 8b3daa80cdb971246902717ad4e33d5db45d1b0e /net | |
parent | 985076720187af7ac0c2de4dfe912acba9b4f586 (diff) | |
download | linux-696ea472e19c6d1fa843bb1abce73b9c3a414391.tar.gz linux-696ea472e19c6d1fa843bb1abce73b9c3a414391.tar.bz2 linux-696ea472e19c6d1fa843bb1abce73b9c3a414391.zip |
llc: avoid skb_clone() if there is only one handler
Signed-off-by: Changli Gao <xiaosuo@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/llc/llc_input.c | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/net/llc/llc_input.c b/net/llc/llc_input.c index f99687439139..058f1e9a9128 100644 --- a/net/llc/llc_input.c +++ b/net/llc/llc_input.c @@ -181,25 +181,26 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev, * LLC functionality */ rcv = rcu_dereference(sap->rcv_func); - if (rcv) { - struct sk_buff *cskb = skb_clone(skb, GFP_ATOMIC); - if (cskb) - rcv(cskb, dev, pt, orig_dev); - } dest = llc_pdu_type(skb); - if (unlikely(!dest || !llc_type_handlers[dest - 1])) - goto drop_put; - llc_type_handlers[dest - 1](sap, skb); -out_put: + if (unlikely(!dest || !llc_type_handlers[dest - 1])) { + if (rcv) + rcv(skb, dev, pt, orig_dev); + else + kfree_skb(skb); + } else { + if (rcv) { + struct sk_buff *cskb = skb_clone(skb, GFP_ATOMIC); + if (cskb) + rcv(cskb, dev, pt, orig_dev); + } + llc_type_handlers[dest - 1](sap, skb); + } llc_sap_put(sap); out: return 0; drop: kfree_skb(skb); goto out; -drop_put: - kfree_skb(skb); - goto out_put; handle_station: if (!llc_station_handler) goto drop; |