提交 ab81007a 编写于 作者: J Johannes Berg

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: NJohannes Berg <johannes.berg@intel.com>
上级 127f60bf
...@@ -3988,6 +3988,7 @@ struct cfg80211_cqm_config; ...@@ -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 { ...@@ -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) ...@@ -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;
ASSERT_RTNL();
spin_lock_irq(&rdev->destroy_list_lock);
while ((item = list_first_entry_or_null(&rdev->destroy_list,
struct cfg80211_iface_destroy,
list))) {
struct wireless_dev *wdev, *tmp; struct wireless_dev *wdev, *tmp;
u32 nlportid = item->nlportid;
list_del(&item->list); ASSERT_RTNL();
kfree(item);
spin_unlock_irq(&rdev->destroy_list_lock);
list_for_each_entry_safe(wdev, tmp, list_for_each_entry_safe(wdev, tmp, &rdev->wiphy.wdev_list, list) {
&rdev->wiphy.wdev_list, list) { if (wdev->nl_owner_dead)
if (nlportid == wdev->owner_nlportid)
rdev_del_virtual_intf(rdev, wdev); 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 @@ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv, ...@@ -484,8 +468,6 @@ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,
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 { ...@@ -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 { ...@@ -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, ...@@ -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,11 +14898,13 @@ static int nl80211_netlink_notify(struct notifier_block * nb, ...@@ -14899,11 +14898,13 @@ 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);
list_for_each_entry_safe(reg, tmp, &rdev->beacon_registrations, list_for_each_entry_safe(reg, tmp, &rdev->beacon_registrations,
...@@ -14915,19 +14916,6 @@ static int nl80211_netlink_notify(struct notifier_block * nb, ...@@ -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();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册