summaryrefslogtreecommitdiffstats
path: root/net/llc/llc_input.c
diff options
context:
space:
mode:
authorChangli Gao <xiaosuo@gmail.com>2011-02-22 01:55:18 +0000
committerDavid S. Miller <davem@davemloft.net>2011-02-28 12:28:50 -0800
commit696ea472e19c6d1fa843bb1abce73b9c3a414391 (patch)
tree8b3daa80cdb971246902717ad4e33d5db45d1b0e /net/llc/llc_input.c
parent985076720187af7ac0c2de4dfe912acba9b4f586 (diff)
downloadlinux-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/llc/llc_input.c')
-rw-r--r--net/llc/llc_input.c25
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;