From b79fd0c6ec32c80fdc880c0bc819770d57c2eb88 Mon Sep 17 00:00:00 2001 From: Jinwei Chen Date: Mon, 24 Aug 2020 21:51:51 -0700 Subject: [PATCH] qcacld-3.0: Fix DP thread stuck issue due to rtnl lock scenario: (1) thread A is doing hdd_stop_adapter() and the caller outside of hdd_stop_adapter will acquire the rtnl lock, dp_vdev_detach_wifi3() in hdd_stop_adpater() will notify DP thread B flush stack GRO frames and wait DP thread B response/set vdev delete event. (2) but if DP thread B is under processing RX frames and do local ARP check for ARP request, it will wait and try to acquire rtnl lock as well, dead lock happened. Until thread A wait vdev delete event timeout and corressponding net_dev/hdd_adapter is freed, then DP thread B get chance to acquire rtnl lock but hdd_adapter/net_dev has been freed, hit panic. Use rtnl_trylock() instead of rtnl_lock() in hdd_is_arp_local(), if rtnl_trylock() failed, assume this is local ARP and return, else do the local ARP checking same as before. Change-Id: Ic6724b68f6e09e9d139c430396e4c76bf483d033 CRs-Fixed: 2760979 --- core/hdd/src/wlan_hdd_tx_rx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/hdd/src/wlan_hdd_tx_rx.c b/core/hdd/src/wlan_hdd_tx_rx.c index 33b348b57b36..36d01598bcdb 100644 --- a/core/hdd/src/wlan_hdd_tx_rx.c +++ b/core/hdd/src/wlan_hdd_tx_rx.c @@ -1540,7 +1540,10 @@ static bool hdd_is_arp_local(struct sk_buff *skb) arp = (struct arphdr *)skb->data; if (arp->ar_op == htons(ARPOP_REQUEST)) { - rtnl_lock(); + /* if fail to acquire rtnl lock, assume it's local arp */ + if (!rtnl_trylock()) + return true; + in_dev = __in_dev_get_rtnl(skb->dev); if (in_dev) { for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;