]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 24 Jan 2019 18:03:30 +0000 (19:03 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 24 Jan 2019 18:03:30 +0000 (19:03 +0100)
added patches:
iwlwifi-mvm-send-lq-command-as-async-when-necessary.patch

queue-4.19/iwlwifi-mvm-send-lq-command-as-async-when-necessary.patch [new file with mode: 0644]
queue-4.19/series

diff --git a/queue-4.19/iwlwifi-mvm-send-lq-command-as-async-when-necessary.patch b/queue-4.19/iwlwifi-mvm-send-lq-command-as-async-when-necessary.patch
new file mode 100644 (file)
index 0000000..e1dfa07
--- /dev/null
@@ -0,0 +1,176 @@
+From 3baf7528d6f832b28622d1ddadd2e47f6c2b5e08 Mon Sep 17 00:00:00 2001
+From: Avraham Stern <avraham.stern@intel.com>
+Date: Thu, 3 May 2018 15:02:16 +0300
+Subject: iwlwifi: mvm: Send LQ command as async when necessary
+
+From: Avraham Stern <avraham.stern@intel.com>
+
+commit 3baf7528d6f832b28622d1ddadd2e47f6c2b5e08 upstream.
+
+The parameter that indicated whether the LQ command should be sent
+as sync or async was removed, causing the LQ command to be sent as
+sync from interrupt context (e.g. from the RX path). This resulted
+in a kernel warning: "scheduling while atomic" and failing to send
+the LQ command, which ultimately leads to a queue hang.
+
+Fix it by adding back the required parameter to send the command as
+sync only when it is allowed.
+
+Fixes: d94c5a820d10 ("iwlwifi: mvm: open BA session only when sta is authorized")
+Signed-off-by: Avraham Stern <avraham.stern@intel.com>
+Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
+Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c |    6 ++++--
+ drivers/net/wireless/intel/iwlwifi/mvm/mvm.h      |    2 +-
+ drivers/net/wireless/intel/iwlwifi/mvm/rs.c       |   18 ++++++++----------
+ drivers/net/wireless/intel/iwlwifi/mvm/rs.h       |    2 +-
+ drivers/net/wireless/intel/iwlwifi/mvm/utils.c    |    7 +++----
+ 5 files changed, 17 insertions(+), 18 deletions(-)
+
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+@@ -2938,7 +2938,8 @@ static int iwl_mvm_mac_sta_state(struct
+                       iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
+               }
+-              iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band);
++              iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band,
++                                   false);
+               ret = iwl_mvm_update_sta(mvm, vif, sta);
+       } else if (old_state == IEEE80211_STA_ASSOC &&
+                  new_state == IEEE80211_STA_AUTHORIZED) {
+@@ -2954,7 +2955,8 @@ static int iwl_mvm_mac_sta_state(struct
+               /* enable beacon filtering */
+               WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0));
+-              iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band);
++              iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band,
++                                   true);
+               ret = 0;
+       } else if (old_state == IEEE80211_STA_AUTHORIZED &&
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+@@ -1685,7 +1685,7 @@ iwl_mvm_vif_dbgfs_clean(struct iwl_mvm *
+ #endif /* CONFIG_IWLWIFI_DEBUGFS */
+ /* rate scaling */
+-int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init);
++int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool sync);
+ void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg);
+ int rs_pretty_print_rate(char *buf, int bufsz, const u32 rate);
+ void rs_update_last_rssi(struct iwl_mvm *mvm,
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c
+@@ -1280,7 +1280,7 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm
+                      (unsigned long)(lq_sta->last_tx +
+                                      (IWL_MVM_RS_IDLE_TIMEOUT * HZ)))) {
+               IWL_DEBUG_RATE(mvm, "Tx idle for too long. reinit rs\n");
+-              iwl_mvm_rs_rate_init(mvm, sta, info->band);
++              iwl_mvm_rs_rate_init(mvm, sta, info->band, true);
+               return;
+       }
+       lq_sta->last_tx = jiffies;
+@@ -2870,9 +2870,8 @@ void rs_update_last_rssi(struct iwl_mvm
+ static void rs_initialize_lq(struct iwl_mvm *mvm,
+                            struct ieee80211_sta *sta,
+                            struct iwl_lq_sta *lq_sta,
+-                           enum nl80211_band band)
++                           enum nl80211_band band, bool update)
+ {
+-      struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
+       struct iwl_scale_tbl_info *tbl;
+       struct rs_rate *rate;
+       u8 active_tbl = 0;
+@@ -2901,8 +2900,7 @@ static void rs_initialize_lq(struct iwl_
+       rs_set_expected_tpt_table(lq_sta, tbl);
+       rs_fill_lq_cmd(mvm, sta, lq_sta, rate);
+       /* TODO restore station should remember the lq cmd */
+-      iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq,
+-                          mvmsta->sta_state < IEEE80211_STA_AUTHORIZED);
++      iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, !update);
+ }
+ static void rs_drv_get_rate(void *mvm_r, struct ieee80211_sta *sta,
+@@ -3155,7 +3153,7 @@ void iwl_mvm_update_frame_stats(struct i
+  * Called after adding a new station to initialize rate scaling
+  */
+ static void rs_drv_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
+-                           enum nl80211_band band)
++                           enum nl80211_band band, bool update)
+ {
+       int i, j;
+       struct ieee80211_hw *hw = mvm->hw;
+@@ -3235,7 +3233,7 @@ static void rs_drv_rate_init(struct iwl_
+ #ifdef CONFIG_IWLWIFI_DEBUGFS
+       iwl_mvm_reset_frame_stats(mvm);
+ #endif
+-      rs_initialize_lq(mvm, sta, lq_sta, band);
++      rs_initialize_lq(mvm, sta, lq_sta, band, update);
+ }
+ static void rs_drv_rate_update(void *mvm_r,
+@@ -3255,7 +3253,7 @@ static void rs_drv_rate_update(void *mvm
+       for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++)
+               ieee80211_stop_tx_ba_session(sta, tid);
+-      iwl_mvm_rs_rate_init(mvm, sta, sband->band);
++      iwl_mvm_rs_rate_init(mvm, sta, sband->band, true);
+ }
+ #ifdef CONFIG_MAC80211_DEBUGFS
+@@ -4112,12 +4110,12 @@ static const struct rate_control_ops rs_
+ };
+ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
+-                        enum nl80211_band band)
++                        enum nl80211_band band, bool update)
+ {
+       if (iwl_mvm_has_tlc_offload(mvm))
+               rs_fw_rate_init(mvm, sta, band);
+       else
+-              rs_drv_rate_init(mvm, sta, band);
++              rs_drv_rate_init(mvm, sta, band, update);
+ }
+ int iwl_mvm_rate_control_register(void)
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.h
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.h
+@@ -420,7 +420,7 @@ struct iwl_lq_sta {
+ /* Initialize station's rate scaling information after adding station */
+ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
+-                        enum nl80211_band band);
++                        enum nl80211_band band, bool init);
+ /* Notify RS about Tx status */
+ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c
+@@ -900,20 +900,19 @@ int iwl_mvm_disable_txq(struct iwl_mvm *
+ /**
+  * iwl_mvm_send_lq_cmd() - Send link quality command
+- * @init: This command is sent as part of station initialization right
+- *        after station has been added.
++ * @sync: This command can be sent synchronously.
+  *
+  * The link quality command is sent as the last step of station creation.
+  * This is the special case in which init is set and we call a callback in
+  * this case to clear the state indicating that station creation is in
+  * progress.
+  */
+-int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool init)
++int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq, bool sync)
+ {
+       struct iwl_host_cmd cmd = {
+               .id = LQ_CMD,
+               .len = { sizeof(struct iwl_lq_cmd), },
+-              .flags = init ? 0 : CMD_ASYNC,
++              .flags = sync ? 0 : CMD_ASYNC,
+               .data = { lq, },
+       };
index 5b4181207eae45471192f01d76ca726e27b9ebf0..1083c50a6c42d0e74b67f4b005494f34ae983ca3 100644 (file)
@@ -97,3 +97,4 @@ mm-page-writeback.c-don-t-break-integrity-writeback-.patch
 mm-swap-use-nr_node_ids-for-avail_lists-in-swap_info.patch
 userfaultfd-clear-flag-if-remap-event-not-enabled.patch
 mm-proc-be-more-verbose-about-unstable-vma-flags-in-.patch
+iwlwifi-mvm-send-lq-command-as-async-when-necessary.patch