Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ab81007a authored by Johannes Berg's avatar Johannes Berg
Browse files

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: default avatarJohannes Berg <johannes.berg@intel.com>
parent 127f60bf
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -3988,6 +3988,7 @@ struct cfg80211_cqm_config;
 * @event_list: (private) list for internal event processing
 * @event_lock: (private) lock for event list
 * @owner_nlportid: (private) owner socket port ID
 * @nl_owner_dead: (private) owner socket went away
 * @cqm_config: (private) nl80211 RSSI monitor state
 */
struct wireless_dev {
@@ -4037,12 +4038,13 @@ struct wireless_dev {

	u32 ap_unexpected_nlportid;

	u32 owner_nlportid;
	bool nl_owner_dead;

	bool cac_started;
	unsigned long cac_start_time;
	unsigned int cac_time_ms;

	u32 owner_nlportid;

#ifdef CONFIG_CFG80211_WEXT
	/* wext data */
	struct {
+4 −22
Original line number Diff line number Diff line
@@ -305,30 +305,14 @@ static void cfg80211_event_work(struct work_struct *work)

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;
		u32 nlportid = item->nlportid;

		list_del(&item->list);
		kfree(item);
		spin_unlock_irq(&rdev->destroy_list_lock);
	ASSERT_RTNL();

		list_for_each_entry_safe(wdev, tmp,
					 &rdev->wiphy.wdev_list, list) {
			if (nlportid == wdev->owner_nlportid)
	list_for_each_entry_safe(wdev, tmp, &rdev->wiphy.wdev_list, list) {
		if (wdev->nl_owner_dead)
			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)
@@ -484,8 +468,6 @@ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,
	rdev->wiphy.dev.platform_data = rdev;
	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->sched_scan_stop_wk, cfg80211_sched_scan_stop_wk);
	INIT_WORK(&rdev->propagate_radar_detect_wk,
+0 −8
Original line number Diff line number Diff line
@@ -91,10 +91,7 @@ struct cfg80211_registered_device {

	struct cfg80211_coalesce *coalesce;

	spinlock_t destroy_list_lock;
	struct list_head destroy_list;
	struct work_struct destroy_work;

	struct work_struct sched_scan_stop_wk;

	struct cfg80211_chan_def radar_chandef;
@@ -264,11 +261,6 @@ struct cfg80211_beacon_registration {
	u32 nlportid;
};

struct cfg80211_iface_destroy {
	struct list_head list;
	u32 nlportid;
};

struct cfg80211_cqm_config {
	u32 rssi_hyst;
	s32 last_rssi_event_value;
+5 −17
Original line number Diff line number Diff line
@@ -14883,7 +14883,6 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
	rcu_read_lock();

	list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
		bool schedule_destroy_work = false;
		struct cfg80211_sched_scan_request *sched_scan_req =
			rcu_dereference(rdev->sched_scan_req);

@@ -14899,11 +14898,13 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
		list_for_each_entry_rcu(wdev, &rdev->wiphy.wdev_list, list) {
			cfg80211_mlme_unregister_socket(wdev, notify->portid);

			if (wdev->owner_nlportid == notify->portid)
				schedule_destroy_work = true;
			else if (wdev->conn_owner_nlportid == notify->portid)
			if (wdev->owner_nlportid == notify->portid) {
				wdev->nl_owner_dead = true;
				schedule_work(&rdev->destroy_work);
			} else if (wdev->conn_owner_nlportid == notify->portid) {
				schedule_work(&wdev->disconnect_wk);
			}
		}

		spin_lock_bh(&rdev->beacon_registrations_lock);
		list_for_each_entry_safe(reg, tmp, &rdev->beacon_registrations,
@@ -14915,19 +14916,6 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
			}
		}
		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();