Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

cfg80211: make wdev_list accessible to drivers

There's no harm in having drivers read the list, since they can
use RCU protection or RTNL locking; allow this to not require
each and every driver to also implement its own bookkeeping.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>

+31 -24
+5
include/net/cfg80211.h
··· 3189 3189 * @vht_capa_mod_mask: Specify what VHT capabilities can be over-ridden. 3190 3190 * If null, then none can be over-ridden. 3191 3191 * 3192 + * @wdev_list: the list of associated (virtual) interfaces; this list must 3193 + * not be modified by the driver, but can be read with RTNL/RCU protection. 3194 + * 3192 3195 * @max_acl_mac_addrs: Maximum number of MAC addresses that the device 3193 3196 * supports for ACL. 3194 3197 * ··· 3330 3327 3331 3328 const struct ieee80211_ht_cap *ht_capa_mod_mask; 3332 3329 const struct ieee80211_vht_cap *vht_capa_mod_mask; 3330 + 3331 + struct list_head wdev_list; 3333 3332 3334 3333 /* the network namespace this phy lives in currently */ 3335 3334 possible_net_t _net;
+1 -1
net/wireless/chan.c
··· 739 739 * and thus fail the GO instantiation, consider only the interfaces of 740 740 * the current registered device. 741 741 */ 742 - list_for_each_entry(wdev, &rdev->wdev_list, list) { 742 + list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { 743 743 struct ieee80211_channel *other_chan = NULL; 744 744 int r1, r2; 745 745
+10 -7
net/wireless/core.c
··· 3 3 * 4 4 * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> 5 5 * Copyright 2013-2014 Intel Mobile Communications GmbH 6 + * Copyright 2015 Intel Deutschland GmbH 6 7 */ 7 8 8 9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt ··· 158 157 if (!(rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK)) 159 158 return -EOPNOTSUPP; 160 159 161 - list_for_each_entry(wdev, &rdev->wdev_list, list) { 160 + list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { 162 161 if (!wdev->netdev) 163 162 continue; 164 163 wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL; ··· 172 171 /* failed -- clean up to old netns */ 173 172 net = wiphy_net(&rdev->wiphy); 174 173 175 - list_for_each_entry_continue_reverse(wdev, &rdev->wdev_list, 174 + list_for_each_entry_continue_reverse(wdev, 175 + &rdev->wiphy.wdev_list, 176 176 list) { 177 177 if (!wdev->netdev) 178 178 continue; ··· 232 230 233 231 ASSERT_RTNL(); 234 232 235 - list_for_each_entry(wdev, &rdev->wdev_list, list) { 233 + list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { 236 234 if (wdev->netdev) { 237 235 dev_close(wdev->netdev); 238 236 continue; ··· 300 298 kfree(item); 301 299 spin_unlock_irq(&rdev->destroy_list_lock); 302 300 303 - list_for_each_entry_safe(wdev, tmp, &rdev->wdev_list, list) { 301 + list_for_each_entry_safe(wdev, tmp, 302 + &rdev->wiphy.wdev_list, list) { 304 303 if (nlportid == wdev->owner_nlportid) 305 304 rdev_del_virtual_intf(rdev, wdev); 306 305 } ··· 413 410 dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx); 414 411 } 415 412 416 - INIT_LIST_HEAD(&rdev->wdev_list); 413 + INIT_LIST_HEAD(&rdev->wiphy.wdev_list); 417 414 INIT_LIST_HEAD(&rdev->beacon_registrations); 418 415 spin_lock_init(&rdev->beacon_registrations_lock); 419 416 spin_lock_init(&rdev->bss_lock); ··· 802 799 nl80211_notify_wiphy(rdev, NL80211_CMD_DEL_WIPHY); 803 800 rdev->wiphy.registered = false; 804 801 805 - WARN_ON(!list_empty(&rdev->wdev_list)); 802 + WARN_ON(!list_empty(&rdev->wiphy.wdev_list)); 806 803 807 804 /* 808 805 * First remove the hardware from everywhere, this makes ··· 1024 1021 spin_lock_init(&wdev->mgmt_registrations_lock); 1025 1022 1026 1023 wdev->identifier = ++rdev->wdev_id; 1027 - list_add_rcu(&wdev->list, &rdev->wdev_list); 1024 + list_add_rcu(&wdev->list, &rdev->wiphy.wdev_list); 1028 1025 rdev->devlist_generation++; 1029 1026 /* can only change netns with wiphy */ 1030 1027 dev->features |= NETIF_F_NETNS_LOCAL;
+1 -2
net/wireless/core.h
··· 50 50 /* wiphy index, internal only */ 51 51 int wiphy_idx; 52 52 53 - /* associated wireless interfaces, protected by rtnl or RCU */ 54 - struct list_head wdev_list; 53 + /* protected by RTNL */ 55 54 int devlist_generation, wdev_id; 56 55 int opencount; 57 56 wait_queue_head_t dev_wait;
+8 -8
net/wireless/nl80211.c
··· 103 103 if (have_wdev_id && rdev->wiphy_idx != wiphy_idx) 104 104 continue; 105 105 106 - list_for_each_entry(wdev, &rdev->wdev_list, list) { 106 + list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { 107 107 if (have_ifidx && wdev->netdev && 108 108 wdev->netdev->ifindex == ifidx) { 109 109 result = wdev; ··· 149 149 tmp = cfg80211_rdev_by_wiphy_idx(wdev_id >> 32); 150 150 if (tmp) { 151 151 /* make sure wdev exists */ 152 - list_for_each_entry(wdev, &tmp->wdev_list, list) { 152 + list_for_each_entry(wdev, &tmp->wiphy.wdev_list, list) { 153 153 if (wdev->identifier != (u32)wdev_id) 154 154 continue; 155 155 found = true; ··· 535 535 *rdev = wiphy_to_rdev(wiphy); 536 536 *wdev = NULL; 537 537 538 - list_for_each_entry(tmp, &(*rdev)->wdev_list, list) { 538 + list_for_each_entry(tmp, &(*rdev)->wiphy.wdev_list, list) { 539 539 if (tmp->identifier == cb->args[1]) { 540 540 *wdev = tmp; 541 541 break; ··· 2490 2490 } 2491 2491 if_idx = 0; 2492 2492 2493 - list_for_each_entry(wdev, &rdev->wdev_list, list) { 2493 + list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { 2494 2494 if (if_idx < if_start) { 2495 2495 if_idx++; 2496 2496 continue; ··· 2762 2762 spin_lock_init(&wdev->mgmt_registrations_lock); 2763 2763 2764 2764 wdev->identifier = ++rdev->wdev_id; 2765 - list_add_rcu(&wdev->list, &rdev->wdev_list); 2765 + list_add_rcu(&wdev->list, &rdev->wiphy.wdev_list); 2766 2766 rdev->devlist_generation++; 2767 2767 break; 2768 2768 default: ··· 3298 3298 struct wireless_dev *wdev; 3299 3299 bool ret = false; 3300 3300 3301 - list_for_each_entry(wdev, &rdev->wdev_list, list) { 3301 + list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { 3302 3302 if (wdev->iftype != NL80211_IFTYPE_AP && 3303 3303 wdev->iftype != NL80211_IFTYPE_P2P_GO) 3304 3304 continue; ··· 10392 10392 *wdev = NULL; 10393 10393 10394 10394 if (cb->args[1]) { 10395 - list_for_each_entry(tmp, &(*rdev)->wdev_list, list) { 10395 + list_for_each_entry(tmp, &wiphy->wdev_list, list) { 10396 10396 if (tmp->identifier == cb->args[1] - 1) { 10397 10397 *wdev = tmp; 10398 10398 break; ··· 13413 13413 sched_scan_req->owner_nlportid == notify->portid) 13414 13414 schedule_scan_stop = true; 13415 13415 13416 - list_for_each_entry_rcu(wdev, &rdev->wdev_list, list) { 13416 + list_for_each_entry_rcu(wdev, &rdev->wiphy.wdev_list, list) { 13417 13417 cfg80211_mlme_unregister_socket(wdev, notify->portid); 13418 13418 13419 13419 if (wdev->owner_nlportid == notify->portid)
+1 -1
net/wireless/reg.c
··· 1639 1639 1640 1640 ASSERT_RTNL(); 1641 1641 1642 - list_for_each_entry(wdev, &rdev->wdev_list, list) 1642 + list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) 1643 1643 if (!reg_wdev_chan_valid(wiphy, wdev)) 1644 1644 cfg80211_leave(rdev, wdev); 1645 1645 }
+2 -2
net/wireless/sme.c
··· 223 223 224 224 rtnl_lock(); 225 225 226 - list_for_each_entry(wdev, &rdev->wdev_list, list) { 226 + list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { 227 227 if (!wdev->netdev) 228 228 continue; 229 229 ··· 617 617 * count as new regulatory hints. 618 618 */ 619 619 list_for_each_entry(rdev, &cfg80211_rdev_list, list) { 620 - list_for_each_entry(wdev, &rdev->wdev_list, list) { 620 + list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { 621 621 wdev_lock(wdev); 622 622 if (wdev->conn || wdev->current_bss) 623 623 is_all_idle = false;
+1 -1
net/wireless/sysfs.c
··· 91 91 { 92 92 struct wireless_dev *wdev; 93 93 94 - list_for_each_entry(wdev, &rdev->wdev_list, list) 94 + list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) 95 95 cfg80211_leave(rdev, wdev); 96 96 } 97 97
+2 -2
net/wireless/util.c
··· 986 986 987 987 ASSERT_RTNL(); 988 988 989 - list_for_each_entry(wdev, &rdev->wdev_list, list) 989 + list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) 990 990 cfg80211_process_wdev_events(wdev); 991 991 } 992 992 ··· 1560 1560 if (!beacon_int) 1561 1561 return -EINVAL; 1562 1562 1563 - list_for_each_entry(wdev, &rdev->wdev_list, list) { 1563 + list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) { 1564 1564 if (!wdev->beacon_interval) 1565 1565 continue; 1566 1566 if (wdev->beacon_interval != beacon_int) {