Search Linux Wireless

[PATCH 6/6] wifi: iwlwifi: limit queue use independent of allocation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Johannes Berg <johannes.berg@xxxxxxxxx>

When using large queue sizes because of hardware workarounds, we
then shouldn't fill the queue according to the allocate size but
according to the desired size to avoid extra latency and lack of
A-MSDU aggregation.

This isn't pretty, but we can hopefully revert it once B-step is
there and we phase out A-step devices.

Fixes: bb16ffd561b6 ("iwlwifi: use 4k queue size for Bz A-step")
Signed-off-by: Johannes Berg <johannes.berg@xxxxxxxxx>
Signed-off-by: Gregory Greenman <gregory.greenman@xxxxxxxxx>
---
 .../net/wireless/intel/iwlwifi/iwl-trans.h    |  2 ++
 drivers/net/wireless/intel/iwlwifi/queue/tx.c | 23 ++++++++++++++++---
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
index 885581e636c7..7d0fa5eee4ea 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
@@ -894,6 +894,7 @@ struct iwl_pcie_first_tb_buf {
  * @read_ptr: last used entry (index) host_r
  * @dma_addr:  physical addr for BD's
  * @n_window: safe queue window
+ * @n_reduced_win: reduced @n_window in case of HW allocation workarounds
  * @id: queue id
  * @low_mark: low watermark, resume queue if free space more than this
  * @high_mark: high watermark, stop queue if free space less than this
@@ -936,6 +937,7 @@ struct iwl_txq {
 	int read_ptr;
 	dma_addr_t dma_addr;
 	int n_window;
+	int n_reduced_win;
 	u32 id;
 	int low_mark;
 	int high_mark;
diff --git a/drivers/net/wireless/intel/iwlwifi/queue/tx.c b/drivers/net/wireless/intel/iwlwifi/queue/tx.c
index d1c39c214f95..a2d83c1201d5 100644
--- a/drivers/net/wireless/intel/iwlwifi/queue/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/queue/tx.c
@@ -685,8 +685,8 @@ int iwl_txq_space(struct iwl_trans *trans, const struct iwl_txq *q)
 	 * If q->n_window is smaller than max_tfd_queue_size, there is no need
 	 * to reserve any queue entries for this purpose.
 	 */
-	if (q->n_window < trans->trans_cfg->base_params->max_tfd_queue_size)
-		max = q->n_window;
+	if (q->n_reduced_win < trans->trans_cfg->base_params->max_tfd_queue_size)
+		max = q->n_reduced_win;
 	else
 		max = trans->trans_cfg->base_params->max_tfd_queue_size - 1;
 
@@ -899,6 +899,7 @@ static void iwl_txq_gen2_free(struct iwl_trans *trans, int txq_id)
 static int iwl_queue_init(struct iwl_txq *q, int slots_num)
 {
 	q->n_window = slots_num;
+	q->n_reduced_win = slots_num;
 
 	/* slots_num must be power-of-two size, otherwise
 	 * iwl_txq_get_cmd_index is broken. */
@@ -1037,6 +1038,7 @@ int iwl_txq_alloc(struct iwl_trans *trans, struct iwl_txq *txq, int slots_num,
 	txq->trans = trans;
 
 	txq->n_window = slots_num;
+	txq->n_reduced_win = slots_num;
 
 	txq->entries = kcalloc(slots_num,
 			       sizeof(struct iwl_pcie_txq_entry),
@@ -1197,16 +1199,31 @@ int iwl_txq_dyn_alloc(struct iwl_trans *trans, u32 flags, u32 sta_mask,
 	struct iwl_host_cmd hcmd = {
 		.flags = CMD_WANT_SKB,
 	};
+	int org_size = 0;
 	int ret;
 
 	if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_BZ &&
-	    trans->hw_rev_step == SILICON_A_STEP)
+	    trans->hw_rev_step == SILICON_A_STEP) {
+		org_size = size;
 		size = 4096;
+	}
 
 	txq = iwl_txq_dyn_alloc_dma(trans, size, timeout);
 	if (IS_ERR(txq))
 		return PTR_ERR(txq);
 
+	if (org_size) {
+		txq->n_reduced_win = org_size;
+
+		txq->low_mark = org_size / 4;
+		if (txq->low_mark < 4)
+			txq->low_mark = 4;
+
+		txq->high_mark = org_size / 8;
+		if (txq->high_mark < 2)
+			txq->high_mark = 2;
+	}
+
 	if (trans->txqs.queue_alloc_cmd_ver == 0) {
 		memset(&cmd.old, 0, sizeof(cmd.old));
 		cmd.old.tfdq_addr = cpu_to_le64(txq->dma_addr);
-- 
2.38.1




[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux