Commit 77dcc623 authored by Thomas Gleixner's avatar Thomas Gleixner
Browse files

mac80211_hwsim: Replace hrtimer tasklet with softirq hrtimer



Switch the timer to HRTIMER_MODE_REL_SOFT, which executed the timer callback in
softirq context and remove the hrtimer_tasklet.

Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarAnna-Maria Gleixner <anna-maria@linutronix.de>
Signed-off-by: default avatarSebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Reviewed-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Acked-by: default avatarDavid S. Miller <davem@davemloft.net>
Cc: netdev@vger.kernel.org
Cc: linux-wireless@vger.kernel.org
Cc: Kalle Valo <kvalo@codeaurora.org>
Link: https://lkml.kernel.org/r/20190301224821.29843-2-bigeasy@linutronix.de
parent 9e98c678
Loading
Loading
Loading
Loading
+21 −25
Original line number Diff line number Diff line
@@ -521,7 +521,7 @@ struct mac80211_hwsim_data {
	unsigned int rx_filter;
	bool started, idle, scanning;
	struct mutex mutex;
	struct tasklet_hrtimer beacon_timer;
	struct hrtimer beacon_timer;
	enum ps_mode {
		PS_DISABLED, PS_ENABLED, PS_AUTO_POLL, PS_MANUAL_POLL
	} ps;
@@ -1460,7 +1460,7 @@ static void mac80211_hwsim_stop(struct ieee80211_hw *hw)
{
	struct mac80211_hwsim_data *data = hw->priv;
	data->started = false;
	tasklet_hrtimer_cancel(&data->beacon_timer);
	hrtimer_cancel(&data->beacon_timer);
	wiphy_dbg(hw->wiphy, "%s\n", __func__);
}

@@ -1583,14 +1583,12 @@ static enum hrtimer_restart
mac80211_hwsim_beacon(struct hrtimer *timer)
{
	struct mac80211_hwsim_data *data =
		container_of(timer, struct mac80211_hwsim_data,
			     beacon_timer.timer);
		container_of(timer, struct mac80211_hwsim_data, beacon_timer);
	struct ieee80211_hw *hw = data->hw;
	u64 bcn_int = data->beacon_int;
	ktime_t next_bcn;

	if (!data->started)
		goto out;
		return HRTIMER_NORESTART;

	ieee80211_iterate_active_interfaces_atomic(
		hw, IEEE80211_IFACE_ITER_NORMAL,
@@ -1601,12 +1599,9 @@ mac80211_hwsim_beacon(struct hrtimer *timer)
		bcn_int -= data->bcn_delta;
		data->bcn_delta = 0;
	}

	next_bcn = ktime_add(hrtimer_get_expires(timer),
			     ns_to_ktime(bcn_int * 1000));
	tasklet_hrtimer_start(&data->beacon_timer, next_bcn, HRTIMER_MODE_ABS);
out:
	return HRTIMER_NORESTART;
	hrtimer_forward(&data->beacon_timer, hrtimer_get_expires(timer),
			ns_to_ktime(bcn_int * NSEC_PER_USEC));
	return HRTIMER_RESTART;
}

static const char * const hwsim_chanwidths[] = {
@@ -1680,15 +1675,15 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
	mutex_unlock(&data->mutex);

	if (!data->started || !data->beacon_int)
		tasklet_hrtimer_cancel(&data->beacon_timer);
	else if (!hrtimer_is_queued(&data->beacon_timer.timer)) {
		hrtimer_cancel(&data->beacon_timer);
	else if (!hrtimer_is_queued(&data->beacon_timer)) {
		u64 tsf = mac80211_hwsim_get_tsf(hw, NULL);
		u32 bcn_int = data->beacon_int;
		u64 until_tbtt = bcn_int - do_div(tsf, bcn_int);

		tasklet_hrtimer_start(&data->beacon_timer,
				      ns_to_ktime(until_tbtt * 1000),
				      HRTIMER_MODE_REL);
		hrtimer_start(&data->beacon_timer,
			      ns_to_ktime(until_tbtt * NSEC_PER_USEC),
			      HRTIMER_MODE_REL_SOFT);
	}

	return 0;
@@ -1751,7 +1746,7 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
			  info->enable_beacon, info->beacon_int);
		vp->bcn_en = info->enable_beacon;
		if (data->started &&
		    !hrtimer_is_queued(&data->beacon_timer.timer) &&
		    !hrtimer_is_queued(&data->beacon_timer) &&
		    info->enable_beacon) {
			u64 tsf, until_tbtt;
			u32 bcn_int;
@@ -1759,9 +1754,10 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
			tsf = mac80211_hwsim_get_tsf(hw, vif);
			bcn_int = data->beacon_int;
			until_tbtt = bcn_int - do_div(tsf, bcn_int);
			tasklet_hrtimer_start(&data->beacon_timer,
					      ns_to_ktime(until_tbtt * 1000),
					      HRTIMER_MODE_REL);

			hrtimer_start(&data->beacon_timer,
				      ns_to_ktime(until_tbtt * NSEC_PER_USEC),
				      HRTIMER_MODE_REL_SOFT);
		} else if (!info->enable_beacon) {
			unsigned int count = 0;
			ieee80211_iterate_active_interfaces_atomic(
@@ -1770,7 +1766,7 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
			wiphy_dbg(hw->wiphy, "  beaconing vifs remaining: %u",
				  count);
			if (count == 0) {
				tasklet_hrtimer_cancel(&data->beacon_timer);
				hrtimer_cancel(&data->beacon_timer);
				data->beacon_int = 0;
			}
		}
@@ -2922,9 +2918,9 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,

	wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);

	tasklet_hrtimer_init(&data->beacon_timer,
			     mac80211_hwsim_beacon,
			     CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
	hrtimer_init(&data->beacon_timer, CLOCK_MONOTONIC,
		     HRTIMER_MODE_ABS_SOFT);
	data->beacon_timer.function = mac80211_hwsim_beacon;

	err = ieee80211_register_hw(hw);
	if (err < 0) {