bh_lock_sock() in sk_receive_skb() is causing unnecessary lock contensions. When PPP is connected, call ppp_input directly. Signed-off-by: Qingfang Deng <dqfext@xxxxxxxxx> --- drivers/net/ppp/pppoe.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c index 2ea4f4890d23..26f86c9730bb 100644 --- a/drivers/net/ppp/pppoe.c +++ b/drivers/net/ppp/pppoe.c @@ -372,9 +372,6 @@ static int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb) * can't change. */ - if (skb->pkt_type == PACKET_OTHERHOST) - goto abort_kfree; - if (sk->sk_state & PPPOX_BOUND) { ppp_input(&po->chan, skb); } else if (sk->sk_state & PPPOX_RELAY) { @@ -416,8 +413,12 @@ static int pppoe_rcv(struct sk_buff *skb, struct net_device *dev, struct pppoe_hdr *ph; struct pppox_sock *po; struct pppoe_net *pn; + struct sock *sk; int len; + if (skb->pkt_type == PACKET_OTHERHOST) + goto drop; + skb = skb_share_check(skb, GFP_ATOMIC); if (!skb) goto out; @@ -448,7 +449,14 @@ static int pppoe_rcv(struct sk_buff *skb, struct net_device *dev, if (!po) goto drop; - return sk_receive_skb(sk_pppox(po), skb, 0); + sk = sk_pppox(po); + if (sk->sk_state & PPPOX_BOUND) { + ppp_input(&po->chan, skb); + sock_put(sk); + return NET_RX_SUCCESS; + } + + return sk_receive_skb(sk, skb, 0); drop: kfree_skb(skb); -- 2.43.0