Skip to content

Commit b790432

Browse files
committed
Johannes Berg says: ==================== Couple of new fixes: - ath10k: revert a patch that had caused issues on some devices - cfg80211/mac80211: use hrtimers for some things where the precise timing matters - zd1211rw: fix a long-standing potential leak * tag 'wireless-2025-10-30' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless: wifi: zd1211rw: fix potential memory leak in __zd_usb_enable_rx() wifi: mac80211: use wiphy_hrtimer_work for csa.switch_work wifi: mac80211: use wiphy_hrtimer_work for ml_reconf_work wifi: mac80211: use wiphy_hrtimer_work for ttlm_work wifi: cfg80211: add an hrtimer based delayed work item Revert "wifi: ath10k: avoid unnecessary wait for service ready message" ==================== Link: https://patch.msgid.link/20251030104919.12871-3-johannes@sipsolutions.net Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents e576349 + 70e8335 commit b790432

File tree

9 files changed

+209
-52
lines changed

9 files changed

+209
-52
lines changed

drivers/net/wireless/ath/ath10k/wmi.c

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1764,32 +1764,33 @@ void ath10k_wmi_put_wmi_channel(struct ath10k *ar, struct wmi_channel *ch,
17641764

17651765
int ath10k_wmi_wait_for_service_ready(struct ath10k *ar)
17661766
{
1767-
unsigned long timeout = jiffies + WMI_SERVICE_READY_TIMEOUT_HZ;
17681767
unsigned long time_left, i;
17691768

1770-
/* Sometimes the PCI HIF doesn't receive interrupt
1771-
* for the service ready message even if the buffer
1772-
* was completed. PCIe sniffer shows that it's
1773-
* because the corresponding CE ring doesn't fires
1774-
* it. Workaround here by polling CE rings. Since
1775-
* the message could arrive at any time, continue
1776-
* polling until timeout.
1777-
*/
1778-
do {
1769+
time_left = wait_for_completion_timeout(&ar->wmi.service_ready,
1770+
WMI_SERVICE_READY_TIMEOUT_HZ);
1771+
if (!time_left) {
1772+
/* Sometimes the PCI HIF doesn't receive interrupt
1773+
* for the service ready message even if the buffer
1774+
* was completed. PCIe sniffer shows that it's
1775+
* because the corresponding CE ring doesn't fires
1776+
* it. Workaround here by polling CE rings once.
1777+
*/
1778+
ath10k_warn(ar, "failed to receive service ready completion, polling..\n");
1779+
17791780
for (i = 0; i < CE_COUNT; i++)
17801781
ath10k_hif_send_complete_check(ar, i, 1);
17811782

1782-
/* The 100 ms granularity is a tradeoff considering scheduler
1783-
* overhead and response latency
1784-
*/
17851783
time_left = wait_for_completion_timeout(&ar->wmi.service_ready,
1786-
msecs_to_jiffies(100));
1787-
if (time_left)
1788-
return 0;
1789-
} while (time_before(jiffies, timeout));
1784+
WMI_SERVICE_READY_TIMEOUT_HZ);
1785+
if (!time_left) {
1786+
ath10k_warn(ar, "polling timed out\n");
1787+
return -ETIMEDOUT;
1788+
}
1789+
1790+
ath10k_warn(ar, "service ready completion received, continuing normally\n");
1791+
}
17901792

1791-
ath10k_warn(ar, "failed to receive service ready completion\n");
1792-
return -ETIMEDOUT;
1793+
return 0;
17931794
}
17941795

17951796
int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar)

drivers/net/wireless/zydas/zd1211rw/zd_usb.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,7 @@ static int __zd_usb_enable_rx(struct zd_usb *usb)
791791
if (urbs) {
792792
for (i = 0; i < RX_URBS_COUNT; i++)
793793
free_rx_urb(urbs[i]);
794+
kfree(urbs);
794795
}
795796
return r;
796797
}

include/net/cfg80211.h

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6435,6 +6435,11 @@ static inline void wiphy_delayed_work_init(struct wiphy_delayed_work *dwork,
64356435
* after wiphy_lock() was called. Therefore, wiphy_cancel_work() can
64366436
* use just cancel_work() instead of cancel_work_sync(), it requires
64376437
* being in a section protected by wiphy_lock().
6438+
*
6439+
* Note that these are scheduled with a timer where the accuracy
6440+
* becomes less the longer in the future the scheduled timer is. Use
6441+
* wiphy_hrtimer_work_queue() if the timer must be not be late by more
6442+
* than approximately 10 percent.
64386443
*/
64396444
void wiphy_delayed_work_queue(struct wiphy *wiphy,
64406445
struct wiphy_delayed_work *dwork,
@@ -6506,6 +6511,79 @@ void wiphy_delayed_work_flush(struct wiphy *wiphy,
65066511
bool wiphy_delayed_work_pending(struct wiphy *wiphy,
65076512
struct wiphy_delayed_work *dwork);
65086513

6514+
struct wiphy_hrtimer_work {
6515+
struct wiphy_work work;
6516+
struct wiphy *wiphy;
6517+
struct hrtimer timer;
6518+
};
6519+
6520+
enum hrtimer_restart wiphy_hrtimer_work_timer(struct hrtimer *t);
6521+
6522+
static inline void wiphy_hrtimer_work_init(struct wiphy_hrtimer_work *hrwork,
6523+
wiphy_work_func_t func)
6524+
{
6525+
hrtimer_setup(&hrwork->timer, wiphy_hrtimer_work_timer,
6526+
CLOCK_BOOTTIME, HRTIMER_MODE_REL);
6527+
wiphy_work_init(&hrwork->work, func);
6528+
}
6529+
6530+
/**
6531+
* wiphy_hrtimer_work_queue - queue hrtimer work for the wiphy
6532+
* @wiphy: the wiphy to queue for
6533+
* @hrwork: the high resolution timer worker
6534+
* @delay: the delay given as a ktime_t
6535+
*
6536+
* Please refer to wiphy_delayed_work_queue(). The difference is that
6537+
* the hrtimer work uses a high resolution timer for scheduling. This
6538+
* may be needed if timeouts might be scheduled further in the future
6539+
* and the accuracy of the normal timer is not sufficient.
6540+
*
6541+
* Expect a delay of a few milliseconds as the timer is scheduled
6542+
* with some slack and some more time may pass between queueing the
6543+
* work and its start.
6544+
*/
6545+
void wiphy_hrtimer_work_queue(struct wiphy *wiphy,
6546+
struct wiphy_hrtimer_work *hrwork,
6547+
ktime_t delay);
6548+
6549+
/**
6550+
* wiphy_hrtimer_work_cancel - cancel previously queued hrtimer work
6551+
* @wiphy: the wiphy, for debug purposes
6552+
* @hrtimer: the hrtimer work to cancel
6553+
*
6554+
* Cancel the work *without* waiting for it, this assumes being
6555+
* called under the wiphy mutex acquired by wiphy_lock().
6556+
*/
6557+
void wiphy_hrtimer_work_cancel(struct wiphy *wiphy,
6558+
struct wiphy_hrtimer_work *hrtimer);
6559+
6560+
/**
6561+
* wiphy_hrtimer_work_flush - flush previously queued hrtimer work
6562+
* @wiphy: the wiphy, for debug purposes
6563+
* @hrwork: the hrtimer work to flush
6564+
*
6565+
* Flush the work (i.e. run it if pending). This must be called
6566+
* under the wiphy mutex acquired by wiphy_lock().
6567+
*/
6568+
void wiphy_hrtimer_work_flush(struct wiphy *wiphy,
6569+
struct wiphy_hrtimer_work *hrwork);
6570+
6571+
/**
6572+
* wiphy_hrtimer_work_pending - Find out whether a wiphy hrtimer
6573+
* work item is currently pending.
6574+
*
6575+
* @wiphy: the wiphy, for debug purposes
6576+
* @hrwork: the hrtimer work in question
6577+
*
6578+
* Return: true if timer is pending, false otherwise
6579+
*
6580+
* Please refer to the wiphy_delayed_work_pending() documentation as
6581+
* this is the equivalent function for hrtimer based delayed work
6582+
* items.
6583+
*/
6584+
bool wiphy_hrtimer_work_pending(struct wiphy *wiphy,
6585+
struct wiphy_hrtimer_work *hrwork);
6586+
65096587
/**
65106588
* enum ieee80211_ap_reg_power - regulatory power for an Access Point
65116589
*

net/mac80211/chan.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1290,7 +1290,7 @@ ieee80211_link_chanctx_reservation_complete(struct ieee80211_link_data *link)
12901290
&link->csa.finalize_work);
12911291
break;
12921292
case NL80211_IFTYPE_STATION:
1293-
wiphy_delayed_work_queue(sdata->local->hw.wiphy,
1293+
wiphy_hrtimer_work_queue(sdata->local->hw.wiphy,
12941294
&link->u.mgd.csa.switch_work, 0);
12951295
break;
12961296
case NL80211_IFTYPE_UNSPECIFIED:

net/mac80211/ieee80211_i.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -612,11 +612,11 @@ struct ieee80211_if_managed {
612612
u8 *assoc_req_ies;
613613
size_t assoc_req_ies_len;
614614

615-
struct wiphy_delayed_work ml_reconf_work;
615+
struct wiphy_hrtimer_work ml_reconf_work;
616616
u16 removed_links;
617617

618618
/* TID-to-link mapping support */
619-
struct wiphy_delayed_work ttlm_work;
619+
struct wiphy_hrtimer_work ttlm_work;
620620
struct ieee80211_adv_ttlm_info ttlm_info;
621621
struct wiphy_work teardown_ttlm_work;
622622

@@ -1017,10 +1017,10 @@ struct ieee80211_link_data_managed {
10171017
bool operating_11g_mode;
10181018

10191019
struct {
1020-
struct wiphy_delayed_work switch_work;
1020+
struct wiphy_hrtimer_work switch_work;
10211021
struct cfg80211_chan_def ap_chandef;
10221022
struct ieee80211_parsed_tpe tpe;
1023-
unsigned long time;
1023+
ktime_t time;
10241024
bool waiting_bcn;
10251025
bool ignored_same_chan;
10261026
bool blocked_tx;

net/mac80211/link.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -472,10 +472,10 @@ static int _ieee80211_set_active_links(struct ieee80211_sub_if_data *sdata,
472472
* from there.
473473
*/
474474
if (link->conf->csa_active)
475-
wiphy_delayed_work_queue(local->hw.wiphy,
475+
wiphy_hrtimer_work_queue(local->hw.wiphy,
476476
&link->u.mgd.csa.switch_work,
477477
link->u.mgd.csa.time -
478-
jiffies);
478+
ktime_get_boottime());
479479
}
480480

481481
for_each_set_bit(link_id, &add, IEEE80211_MLD_MAX_NUM_LINKS) {

net/mac80211/mlme.c

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
#define IEEE80211_ASSOC_TIMEOUT_SHORT (HZ / 10)
4646
#define IEEE80211_ASSOC_MAX_TRIES 3
4747

48-
#define IEEE80211_ADV_TTLM_SAFETY_BUFFER_MS msecs_to_jiffies(100)
48+
#define IEEE80211_ADV_TTLM_SAFETY_BUFFER_MS (100 * USEC_PER_MSEC)
4949
#define IEEE80211_ADV_TTLM_ST_UNDERFLOW 0xff00
5050

5151
#define IEEE80211_NEG_TTLM_REQ_TIMEOUT (HZ / 5)
@@ -2594,7 +2594,7 @@ void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success,
25942594
return;
25952595
}
25962596

2597-
wiphy_delayed_work_queue(sdata->local->hw.wiphy,
2597+
wiphy_hrtimer_work_queue(sdata->local->hw.wiphy,
25982598
&link->u.mgd.csa.switch_work, 0);
25992599
}
26002600

@@ -2753,7 +2753,8 @@ ieee80211_sta_process_chanswitch(struct ieee80211_link_data *link,
27532753
.timestamp = timestamp,
27542754
.device_timestamp = device_timestamp,
27552755
};
2756-
unsigned long now;
2756+
u32 csa_time_tu;
2757+
ktime_t now;
27572758
int res;
27582759

27592760
lockdep_assert_wiphy(local->hw.wiphy);
@@ -2983,10 +2984,9 @@ ieee80211_sta_process_chanswitch(struct ieee80211_link_data *link,
29832984
csa_ie.mode);
29842985

29852986
/* we may have to handle timeout for deactivated link in software */
2986-
now = jiffies;
2987-
link->u.mgd.csa.time = now +
2988-
TU_TO_JIFFIES((max_t(int, csa_ie.count, 1) - 1) *
2989-
link->conf->beacon_int);
2987+
now = ktime_get_boottime();
2988+
csa_time_tu = (max_t(int, csa_ie.count, 1) - 1) * link->conf->beacon_int;
2989+
link->u.mgd.csa.time = now + us_to_ktime(ieee80211_tu_to_usec(csa_time_tu));
29902990

29912991
if (ieee80211_vif_link_active(&sdata->vif, link->link_id) &&
29922992
local->ops->channel_switch) {
@@ -3001,7 +3001,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_link_data *link,
30013001
}
30023002

30033003
/* channel switch handled in software */
3004-
wiphy_delayed_work_queue(local->hw.wiphy,
3004+
wiphy_hrtimer_work_queue(local->hw.wiphy,
30053005
&link->u.mgd.csa.switch_work,
30063006
link->u.mgd.csa.time - now);
30073007
return;
@@ -4242,14 +4242,14 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
42424242

42434243
memset(&sdata->u.mgd.ttlm_info, 0,
42444244
sizeof(sdata->u.mgd.ttlm_info));
4245-
wiphy_delayed_work_cancel(sdata->local->hw.wiphy, &ifmgd->ttlm_work);
4245+
wiphy_hrtimer_work_cancel(sdata->local->hw.wiphy, &ifmgd->ttlm_work);
42464246

42474247
memset(&sdata->vif.neg_ttlm, 0, sizeof(sdata->vif.neg_ttlm));
42484248
wiphy_delayed_work_cancel(sdata->local->hw.wiphy,
42494249
&ifmgd->neg_ttlm_timeout_work);
42504250

42514251
sdata->u.mgd.removed_links = 0;
4252-
wiphy_delayed_work_cancel(sdata->local->hw.wiphy,
4252+
wiphy_hrtimer_work_cancel(sdata->local->hw.wiphy,
42534253
&sdata->u.mgd.ml_reconf_work);
42544254

42554255
wiphy_work_cancel(sdata->local->hw.wiphy,
@@ -6876,7 +6876,7 @@ static void ieee80211_ml_reconfiguration(struct ieee80211_sub_if_data *sdata,
68766876
/* In case the removal was cancelled, abort it */
68776877
if (sdata->u.mgd.removed_links) {
68786878
sdata->u.mgd.removed_links = 0;
6879-
wiphy_delayed_work_cancel(sdata->local->hw.wiphy,
6879+
wiphy_hrtimer_work_cancel(sdata->local->hw.wiphy,
68806880
&sdata->u.mgd.ml_reconf_work);
68816881
}
68826882
return;
@@ -6906,9 +6906,9 @@ static void ieee80211_ml_reconfiguration(struct ieee80211_sub_if_data *sdata,
69066906
}
69076907

69086908
sdata->u.mgd.removed_links = removed_links;
6909-
wiphy_delayed_work_queue(sdata->local->hw.wiphy,
6909+
wiphy_hrtimer_work_queue(sdata->local->hw.wiphy,
69106910
&sdata->u.mgd.ml_reconf_work,
6911-
TU_TO_JIFFIES(delay));
6911+
us_to_ktime(ieee80211_tu_to_usec(delay)));
69126912
}
69136913

69146914
static int ieee80211_ttlm_set_links(struct ieee80211_sub_if_data *sdata,
@@ -7095,7 +7095,7 @@ static void ieee80211_process_adv_ttlm(struct ieee80211_sub_if_data *sdata,
70957095
/* if a planned TID-to-link mapping was cancelled -
70967096
* abort it
70977097
*/
7098-
wiphy_delayed_work_cancel(sdata->local->hw.wiphy,
7098+
wiphy_hrtimer_work_cancel(sdata->local->hw.wiphy,
70997099
&sdata->u.mgd.ttlm_work);
71007100
} else if (sdata->u.mgd.ttlm_info.active) {
71017101
/* if no TID-to-link element, set to default mapping in
@@ -7130,7 +7130,7 @@ static void ieee80211_process_adv_ttlm(struct ieee80211_sub_if_data *sdata,
71307130

71317131
if (ttlm_info.switch_time) {
71327132
u16 beacon_ts_tu, st_tu, delay;
7133-
u32 delay_jiffies;
7133+
u64 delay_usec;
71347134
u64 mask;
71357135

71367136
/* The t2l map switch time is indicated with a partial
@@ -7152,23 +7152,23 @@ static void ieee80211_process_adv_ttlm(struct ieee80211_sub_if_data *sdata,
71527152
if (delay > IEEE80211_ADV_TTLM_ST_UNDERFLOW)
71537153
return;
71547154

7155-
delay_jiffies = TU_TO_JIFFIES(delay);
7155+
delay_usec = ieee80211_tu_to_usec(delay);
71567156

71577157
/* Link switching can take time, so schedule it
71587158
* 100ms before to be ready on time
71597159
*/
7160-
if (delay_jiffies > IEEE80211_ADV_TTLM_SAFETY_BUFFER_MS)
7161-
delay_jiffies -=
7160+
if (delay_usec > IEEE80211_ADV_TTLM_SAFETY_BUFFER_MS)
7161+
delay_usec -=
71627162
IEEE80211_ADV_TTLM_SAFETY_BUFFER_MS;
71637163
else
7164-
delay_jiffies = 0;
7164+
delay_usec = 0;
71657165

71667166
sdata->u.mgd.ttlm_info = ttlm_info;
7167-
wiphy_delayed_work_cancel(sdata->local->hw.wiphy,
7167+
wiphy_hrtimer_work_cancel(sdata->local->hw.wiphy,
71687168
&sdata->u.mgd.ttlm_work);
7169-
wiphy_delayed_work_queue(sdata->local->hw.wiphy,
7169+
wiphy_hrtimer_work_queue(sdata->local->hw.wiphy,
71707170
&sdata->u.mgd.ttlm_work,
7171-
delay_jiffies);
7171+
us_to_ktime(delay_usec));
71727172
return;
71737173
}
71747174
}
@@ -8793,7 +8793,7 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
87938793
ieee80211_csa_connection_drop_work);
87948794
wiphy_delayed_work_init(&ifmgd->tdls_peer_del_work,
87958795
ieee80211_tdls_peer_del_work);
8796-
wiphy_delayed_work_init(&ifmgd->ml_reconf_work,
8796+
wiphy_hrtimer_work_init(&ifmgd->ml_reconf_work,
87978797
ieee80211_ml_reconf_work);
87988798
wiphy_delayed_work_init(&ifmgd->reconf.wk,
87998799
ieee80211_ml_sta_reconf_timeout);
@@ -8802,7 +8802,7 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
88028802
timer_setup(&ifmgd->conn_mon_timer, ieee80211_sta_conn_mon_timer, 0);
88038803
wiphy_delayed_work_init(&ifmgd->tx_tspec_wk,
88048804
ieee80211_sta_handle_tspec_ac_params_wk);
8805-
wiphy_delayed_work_init(&ifmgd->ttlm_work,
8805+
wiphy_hrtimer_work_init(&ifmgd->ttlm_work,
88068806
ieee80211_tid_to_link_map_work);
88078807
wiphy_delayed_work_init(&ifmgd->neg_ttlm_timeout_work,
88088808
ieee80211_neg_ttlm_timeout_work);
@@ -8849,7 +8849,7 @@ void ieee80211_mgd_setup_link(struct ieee80211_link_data *link)
88498849
else
88508850
link->u.mgd.req_smps = IEEE80211_SMPS_OFF;
88518851

8852-
wiphy_delayed_work_init(&link->u.mgd.csa.switch_work,
8852+
wiphy_hrtimer_work_init(&link->u.mgd.csa.switch_work,
88538853
ieee80211_csa_switch_work);
88548854

88558855
ieee80211_clear_tpe(&link->conf->tpe);
@@ -10064,7 +10064,7 @@ void ieee80211_mgd_stop_link(struct ieee80211_link_data *link)
1006410064
&link->u.mgd.request_smps_work);
1006510065
wiphy_work_cancel(link->sdata->local->hw.wiphy,
1006610066
&link->u.mgd.recalc_smps);
10067-
wiphy_delayed_work_cancel(link->sdata->local->hw.wiphy,
10067+
wiphy_hrtimer_work_cancel(link->sdata->local->hw.wiphy,
1006810068
&link->u.mgd.csa.switch_work);
1006910069
}
1007010070

0 commit comments

Comments
 (0)