cfg80211: simplify netlink socket owner interface deletion
There's no need to allocate a portid structure and then, for each of those, walk the interfaces - we can just add a flag to each interface and walk those directly. Due to padding in the struct, we can even do it without any memory cost, and it even simplifies the code. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
127f60bfa9
commit
ab81007a7b
|
@ -3988,6 +3988,7 @@ struct cfg80211_cqm_config;
|
||||||
* @event_list: (private) list for internal event processing
|
* @event_list: (private) list for internal event processing
|
||||||
* @event_lock: (private) lock for event list
|
* @event_lock: (private) lock for event list
|
||||||
* @owner_nlportid: (private) owner socket port ID
|
* @owner_nlportid: (private) owner socket port ID
|
||||||
|
* @nl_owner_dead: (private) owner socket went away
|
||||||
* @cqm_config: (private) nl80211 RSSI monitor state
|
* @cqm_config: (private) nl80211 RSSI monitor state
|
||||||
*/
|
*/
|
||||||
struct wireless_dev {
|
struct wireless_dev {
|
||||||
|
@ -4037,12 +4038,13 @@ struct wireless_dev {
|
||||||
|
|
||||||
u32 ap_unexpected_nlportid;
|
u32 ap_unexpected_nlportid;
|
||||||
|
|
||||||
|
u32 owner_nlportid;
|
||||||
|
bool nl_owner_dead;
|
||||||
|
|
||||||
bool cac_started;
|
bool cac_started;
|
||||||
unsigned long cac_start_time;
|
unsigned long cac_start_time;
|
||||||
unsigned int cac_time_ms;
|
unsigned int cac_time_ms;
|
||||||
|
|
||||||
u32 owner_nlportid;
|
|
||||||
|
|
||||||
#ifdef CONFIG_CFG80211_WEXT
|
#ifdef CONFIG_CFG80211_WEXT
|
||||||
/* wext data */
|
/* wext data */
|
||||||
struct {
|
struct {
|
||||||
|
|
|
@ -305,30 +305,14 @@ static void cfg80211_event_work(struct work_struct *work)
|
||||||
|
|
||||||
void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev)
|
void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev)
|
||||||
{
|
{
|
||||||
struct cfg80211_iface_destroy *item;
|
struct wireless_dev *wdev, *tmp;
|
||||||
|
|
||||||
ASSERT_RTNL();
|
ASSERT_RTNL();
|
||||||
|
|
||||||
spin_lock_irq(&rdev->destroy_list_lock);
|
list_for_each_entry_safe(wdev, tmp, &rdev->wiphy.wdev_list, list) {
|
||||||
while ((item = list_first_entry_or_null(&rdev->destroy_list,
|
if (wdev->nl_owner_dead)
|
||||||
struct cfg80211_iface_destroy,
|
rdev_del_virtual_intf(rdev, wdev);
|
||||||
list))) {
|
|
||||||
struct wireless_dev *wdev, *tmp;
|
|
||||||
u32 nlportid = item->nlportid;
|
|
||||||
|
|
||||||
list_del(&item->list);
|
|
||||||
kfree(item);
|
|
||||||
spin_unlock_irq(&rdev->destroy_list_lock);
|
|
||||||
|
|
||||||
list_for_each_entry_safe(wdev, tmp,
|
|
||||||
&rdev->wiphy.wdev_list, list) {
|
|
||||||
if (nlportid == wdev->owner_nlportid)
|
|
||||||
rdev_del_virtual_intf(rdev, wdev);
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_lock_irq(&rdev->destroy_list_lock);
|
|
||||||
}
|
}
|
||||||
spin_unlock_irq(&rdev->destroy_list_lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cfg80211_destroy_iface_wk(struct work_struct *work)
|
static void cfg80211_destroy_iface_wk(struct work_struct *work)
|
||||||
|
@ -484,8 +468,6 @@ use_default_name:
|
||||||
rdev->wiphy.dev.platform_data = rdev;
|
rdev->wiphy.dev.platform_data = rdev;
|
||||||
device_enable_async_suspend(&rdev->wiphy.dev);
|
device_enable_async_suspend(&rdev->wiphy.dev);
|
||||||
|
|
||||||
INIT_LIST_HEAD(&rdev->destroy_list);
|
|
||||||
spin_lock_init(&rdev->destroy_list_lock);
|
|
||||||
INIT_WORK(&rdev->destroy_work, cfg80211_destroy_iface_wk);
|
INIT_WORK(&rdev->destroy_work, cfg80211_destroy_iface_wk);
|
||||||
INIT_WORK(&rdev->sched_scan_stop_wk, cfg80211_sched_scan_stop_wk);
|
INIT_WORK(&rdev->sched_scan_stop_wk, cfg80211_sched_scan_stop_wk);
|
||||||
INIT_WORK(&rdev->propagate_radar_detect_wk,
|
INIT_WORK(&rdev->propagate_radar_detect_wk,
|
||||||
|
|
|
@ -91,10 +91,7 @@ struct cfg80211_registered_device {
|
||||||
|
|
||||||
struct cfg80211_coalesce *coalesce;
|
struct cfg80211_coalesce *coalesce;
|
||||||
|
|
||||||
spinlock_t destroy_list_lock;
|
|
||||||
struct list_head destroy_list;
|
|
||||||
struct work_struct destroy_work;
|
struct work_struct destroy_work;
|
||||||
|
|
||||||
struct work_struct sched_scan_stop_wk;
|
struct work_struct sched_scan_stop_wk;
|
||||||
|
|
||||||
struct cfg80211_chan_def radar_chandef;
|
struct cfg80211_chan_def radar_chandef;
|
||||||
|
@ -264,11 +261,6 @@ struct cfg80211_beacon_registration {
|
||||||
u32 nlportid;
|
u32 nlportid;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cfg80211_iface_destroy {
|
|
||||||
struct list_head list;
|
|
||||||
u32 nlportid;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct cfg80211_cqm_config {
|
struct cfg80211_cqm_config {
|
||||||
u32 rssi_hyst;
|
u32 rssi_hyst;
|
||||||
s32 last_rssi_event_value;
|
s32 last_rssi_event_value;
|
||||||
|
|
|
@ -14883,7 +14883,6 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
|
|
||||||
list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
|
list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
|
||||||
bool schedule_destroy_work = false;
|
|
||||||
struct cfg80211_sched_scan_request *sched_scan_req =
|
struct cfg80211_sched_scan_request *sched_scan_req =
|
||||||
rcu_dereference(rdev->sched_scan_req);
|
rcu_dereference(rdev->sched_scan_req);
|
||||||
|
|
||||||
|
@ -14899,10 +14898,12 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
|
||||||
list_for_each_entry_rcu(wdev, &rdev->wiphy.wdev_list, list) {
|
list_for_each_entry_rcu(wdev, &rdev->wiphy.wdev_list, list) {
|
||||||
cfg80211_mlme_unregister_socket(wdev, notify->portid);
|
cfg80211_mlme_unregister_socket(wdev, notify->portid);
|
||||||
|
|
||||||
if (wdev->owner_nlportid == notify->portid)
|
if (wdev->owner_nlportid == notify->portid) {
|
||||||
schedule_destroy_work = true;
|
wdev->nl_owner_dead = true;
|
||||||
else if (wdev->conn_owner_nlportid == notify->portid)
|
schedule_work(&rdev->destroy_work);
|
||||||
|
} else if (wdev->conn_owner_nlportid == notify->portid) {
|
||||||
schedule_work(&wdev->disconnect_wk);
|
schedule_work(&wdev->disconnect_wk);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock_bh(&rdev->beacon_registrations_lock);
|
spin_lock_bh(&rdev->beacon_registrations_lock);
|
||||||
|
@ -14915,19 +14916,6 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
spin_unlock_bh(&rdev->beacon_registrations_lock);
|
spin_unlock_bh(&rdev->beacon_registrations_lock);
|
||||||
|
|
||||||
if (schedule_destroy_work) {
|
|
||||||
struct cfg80211_iface_destroy *destroy;
|
|
||||||
|
|
||||||
destroy = kzalloc(sizeof(*destroy), GFP_ATOMIC);
|
|
||||||
if (destroy) {
|
|
||||||
destroy->nlportid = notify->portid;
|
|
||||||
spin_lock(&rdev->destroy_list_lock);
|
|
||||||
list_add(&destroy->list, &rdev->destroy_list);
|
|
||||||
spin_unlock(&rdev->destroy_list_lock);
|
|
||||||
schedule_work(&rdev->destroy_work);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
Loading…
Reference in New Issue