Переглянути джерело

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
Jinwei Chen 4 роки тому
батько
коміт
b79fd0c6ec
1 змінених файлів з 4 додано та 1 видалено
  1. 4 1
      core/hdd/src/wlan_hdd_tx_rx.c

+ 4 - 1
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;