rtnetlink.c (9cbbd694a58bdf24def2462276514c90cab7cf80) | rtnetlink.c (0b5c21bbc01e92745ca1ca4f6fd87d878fa3ea5e) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * INET An implementation of the TCP/IP protocol suite for the LINUX 4 * operating system. INET is implemented using the BSD Socket 5 * interface as the means of communication with the user level. 6 * 7 * Routing netlink socket interface: protocol independent part. 8 * --- 81 unchanged lines hidden (view full) --- 90EXPORT_SYMBOL(rtnl_kfree_skbs); 91 92void __rtnl_unlock(void) 93{ 94 struct sk_buff *head = defer_kfree_skb_list; 95 96 defer_kfree_skb_list = NULL; 97 | 1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * INET An implementation of the TCP/IP protocol suite for the LINUX 4 * operating system. INET is implemented using the BSD Socket 5 * interface as the means of communication with the user level. 6 * 7 * Routing netlink socket interface: protocol independent part. 8 * --- 81 unchanged lines hidden (view full) --- 90EXPORT_SYMBOL(rtnl_kfree_skbs); 91 92void __rtnl_unlock(void) 93{ 94 struct sk_buff *head = defer_kfree_skb_list; 95 96 defer_kfree_skb_list = NULL; 97 |
98 /* Ensure that we didn't actually add any TODO item when __rtnl_unlock() 99 * is used. In some places, e.g. in cfg80211, we have code that will do 100 * something like 101 * rtnl_lock() 102 * wiphy_lock() 103 * ... 104 * rtnl_unlock() 105 * 106 * and because netdev_run_todo() acquires the RTNL for items on the list 107 * we could cause a situation such as this: 108 * Thread 1 Thread 2 109 * rtnl_lock() 110 * unregister_netdevice() 111 * __rtnl_unlock() 112 * rtnl_lock() 113 * wiphy_lock() 114 * rtnl_unlock() 115 * netdev_run_todo() 116 * __rtnl_unlock() 117 * 118 * // list not empty now 119 * // because of thread 2 120 * rtnl_lock() 121 * while (!list_empty(...)) 122 * rtnl_lock() 123 * wiphy_lock() 124 * **** DEADLOCK **** 125 * 126 * However, usage of __rtnl_unlock() is rare, and so we can ensure that 127 * it's not used in cases where something is added to do the list. 128 */ 129 WARN_ON(!list_empty(&net_todo_list)); 130 |
|
98 mutex_unlock(&rtnl_mutex); 99 100 while (head) { 101 struct sk_buff *next = head->next; 102 103 kfree_skb(head); 104 cond_resched(); 105 head = next; --- 6010 unchanged lines hidden --- | 131 mutex_unlock(&rtnl_mutex); 132 133 while (head) { 134 struct sk_buff *next = head->next; 135 136 kfree_skb(head); 137 cond_resched(); 138 head = next; --- 6010 unchanged lines hidden --- |