All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] iwlwifi: limit MSI-X IRQs to IWL_MAX_RX_HW_QUEUES - 1 to avoid num_rx_queues > IWL_MAX_RX_HW_QUEUES
@ 2018-05-05 15:10 Hao Wei Tee
  2018-05-05 15:18 ` [PATCH v2] " Hao Wei Tee
  0 siblings, 1 reply; 3+ messages in thread
From: Hao Wei Tee @ 2018-05-05 15:10 UTC (permalink / raw)
  To: johannes.berg, emmanuel.grumbach, luciano.coelho, linuxwifi,
	linux-wireless

When there are 16 or more logical CPUs, we request for `IWL_MAX_RX_HW_QUEUES` (16)
IRQs only, but later on create `num_irqs+1` RX queues, which could end up more
than `IWL_MAX_RX_HW_QUEUES` if the OS does return us 16 IRQs. This wreaks lots
of havoc elsewhere later on due to code that uses `num_rx_queues` to calculate
array sizes.

Limit to IWL_MAX_RX_HW_QUEUES - 1 IRQs so num_rx_queues is never more than
IWL_MAX_RX_HW_QUEUES.
---
 drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 6e9a9ecfb11c..f5c12924c836 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -1607,7 +1607,7 @@ static void iwl_pcie_set_interrupt_capa(struct pci_dev *pdev,
 		goto enable_msi;
 
 	nr_online_cpus = num_online_cpus();
-	max_irqs = min_t(u32, nr_online_cpus + 2, IWL_MAX_RX_HW_QUEUES);
+	max_irqs = min_t(u32, nr_online_cpus + 2, IWL_MAX_RX_HW_QUEUES - 1);
 	for (i = 0; i < max_irqs; i++)
 		trans_pcie->msix_entries[i].entry = i;
 
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH v2] iwlwifi: limit MSI-X IRQs to IWL_MAX_RX_HW_QUEUES - 1 to avoid num_rx_queues > IWL_MAX_RX_HW_QUEUES
  2018-05-05 15:10 [PATCH] iwlwifi: limit MSI-X IRQs to IWL_MAX_RX_HW_QUEUES - 1 to avoid num_rx_queues > IWL_MAX_RX_HW_QUEUES Hao Wei Tee
@ 2018-05-05 15:18 ` Hao Wei Tee
  2018-05-06  9:33   ` [PATCH v3] iwlwifi: compare with actual number of IRQs requested for, not number of CPUs Hao Wei Tee
  0 siblings, 1 reply; 3+ messages in thread
From: Hao Wei Tee @ 2018-05-05 15:18 UTC (permalink / raw)
  To: johannes.berg, emmanuel.grumbach, luciano.coelho, linuxwifi,
	linux-wireless

When there are 16 or more logical CPUs, we request for `IWL_MAX_RX_HW_QUEUES` (16)
IRQs only, but later on create `num_irqs+1` RX queues, which could end up more
than `IWL_MAX_RX_HW_QUEUES` if the OS does return us 16 IRQs. This wreaks lots
of havoc elsewhere later on due to code that uses `num_rx_queues` to calculate
array sizes.

Limit to IWL_MAX_RX_HW_QUEUES - 1 IRQs so num_rx_queues is never more than
IWL_MAX_RX_HW_QUEUES.

Signed-off-by: Hao Wei Tee <angelsl@in04.sg>
---
My bad. Forgot to sign off.

 drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 6e9a9ecfb11c..f5c12924c836 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -1607,7 +1607,7 @@ static void iwl_pcie_set_interrupt_capa(struct pci_dev *pdev,
 		goto enable_msi;
 
 	nr_online_cpus = num_online_cpus();
-	max_irqs = min_t(u32, nr_online_cpus + 2, IWL_MAX_RX_HW_QUEUES);
+	max_irqs = min_t(u32, nr_online_cpus + 2, IWL_MAX_RX_HW_QUEUES - 1);
 	for (i = 0; i < max_irqs; i++)
 		trans_pcie->msix_entries[i].entry = i;
 
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH v3] iwlwifi: compare with actual number of IRQs requested for, not number of CPUs
  2018-05-05 15:18 ` [PATCH v2] " Hao Wei Tee
@ 2018-05-06  9:33   ` Hao Wei Tee
  0 siblings, 0 replies; 3+ messages in thread
From: Hao Wei Tee @ 2018-05-06  9:33 UTC (permalink / raw)
  To: johannes.berg, emmanuel.grumbach, luciano.coelho, linuxwifi,
	linux-wireless

When there are 16 or more logical CPUs, we request for `IWL_MAX_RX_HW_QUEUES` (16)
IRQs only as we limit to that number of IRQs, but later on we compare the
number of IRQs returned to nr_online_cpus+2 instead of max_irqs, the latter
being what we actually asked for. This ends up setting num_rx_queues to 17
which causes lots of out-of-bounds array accesses later on.

Compare to max_irqs instead, and also add an assertion in case num_rx_queues
> IWM_MAX_RX_HW_QUEUES.

Signed-off-by: Hao Wei Tee <angelsl@in04.sg>
---
I think this is a better fix than what I sent previously.

But you guys are probably looking into it now, so please disregard my
probably-incorrect fix.

Thanks.

 drivers/net/wireless/intel/iwlwifi/pcie/trans.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
index 6e9a9ecfb11c..aa469046f86c 100644
--- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c
@@ -1633,16 +1633,17 @@ static void iwl_pcie_set_interrupt_capa(struct pci_dev *pdev,
 	 * Two interrupts less: non rx causes shared with FBQ and RSS.
 	 * More than two interrupts: we will use fewer RSS queues.
 	 */
-	if (num_irqs <= nr_online_cpus) {
+	if (num_irqs <= max_irqs - 2) {
 		trans_pcie->trans->num_rx_queues = num_irqs + 1;
 		trans_pcie->shared_vec_mask = IWL_SHARED_IRQ_NON_RX |
 			IWL_SHARED_IRQ_FIRST_RSS;
-	} else if (num_irqs == nr_online_cpus + 1) {
+	} else if (num_irqs == max_irqs - 1) {
 		trans_pcie->trans->num_rx_queues = num_irqs;
 		trans_pcie->shared_vec_mask = IWL_SHARED_IRQ_NON_RX;
 	} else {
 		trans_pcie->trans->num_rx_queues = num_irqs - 1;
 	}
+	WARN_ON(trans_pcie->trans->num_rx_queues > IWL_MAX_RX_HW_QUEUES);
 
 	trans_pcie->alloc_vecs = num_irqs;
 	trans_pcie->msix_enabled = true;
-- 
2.17.0

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2018-05-06  9:33 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-05 15:10 [PATCH] iwlwifi: limit MSI-X IRQs to IWL_MAX_RX_HW_QUEUES - 1 to avoid num_rx_queues > IWL_MAX_RX_HW_QUEUES Hao Wei Tee
2018-05-05 15:18 ` [PATCH v2] " Hao Wei Tee
2018-05-06  9:33   ` [PATCH v3] iwlwifi: compare with actual number of IRQs requested for, not number of CPUs Hao Wei Tee

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.