Commit b60b869d authored by Alexander Gordeev's avatar Alexander Gordeev Committed by David S. Miller

vmxnet3: Fix MSI-X/MSI enablement code

This update cleans up the MSI-X/MSI enablement code, fixes
vmxnet3_acquire_msix_vectors() invalid return values and
enables a dead code in case VMXNET3_LINUX_MIN_MSIX_VECT
MSI-X vectors were allocated.
Signed-off-by: default avatarAlexander Gordeev <agordeev@redhat.com>
Cc: Shreyas Bhatewara <sbhatewara@vmware.com>
Cc: pv-drivers@vmware.com
Cc: netdev@vger.kernel.org
Cc: linux-pci@vger.kernel.org
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9e7df17e
...@@ -2729,47 +2729,44 @@ vmxnet3_read_mac_addr(struct vmxnet3_adapter *adapter, u8 *mac) ...@@ -2729,47 +2729,44 @@ vmxnet3_read_mac_addr(struct vmxnet3_adapter *adapter, u8 *mac)
/* /*
* Enable MSIx vectors. * Enable MSIx vectors.
* Returns : * Returns :
* 0 on successful enabling of required vectors,
* VMXNET3_LINUX_MIN_MSIX_VECT when only minimum number of vectors required * VMXNET3_LINUX_MIN_MSIX_VECT when only minimum number of vectors required
* could be enabled. * were enabled.
* number of vectors which can be enabled otherwise (this number is smaller * number of vectors which were enabled otherwise (this number is greater
* than VMXNET3_LINUX_MIN_MSIX_VECT) * than VMXNET3_LINUX_MIN_MSIX_VECT)
*/ */
static int static int
vmxnet3_acquire_msix_vectors(struct vmxnet3_adapter *adapter, vmxnet3_acquire_msix_vectors(struct vmxnet3_adapter *adapter, int nvec)
int vectors)
{ {
int err = 0, vector_threshold; do {
vector_threshold = VMXNET3_LINUX_MIN_MSIX_VECT; int err = pci_enable_msix(adapter->pdev,
adapter->intr.msix_entries, nvec);
while (vectors >= vector_threshold) {
err = pci_enable_msix(adapter->pdev, adapter->intr.msix_entries,
vectors);
if (!err) { if (!err) {
adapter->intr.num_intrs = vectors; return nvec;
return 0;
} else if (err < 0) { } else if (err < 0) {
dev_err(&adapter->netdev->dev, dev_err(&adapter->netdev->dev,
"Failed to enable MSI-X, error: %d\n", err); "Failed to enable MSI-X, error: %d\n", err);
vectors = 0; return err;
} else if (err < vector_threshold) { } else if (err < VMXNET3_LINUX_MIN_MSIX_VECT) {
break; dev_info(&adapter->pdev->dev,
"Number of MSI-X which can be allocated "
"is lower than min threshold required.\n");
return -ENOSPC;
} else { } else {
/* If fails to enable required number of MSI-x vectors /* If fails to enable required number of MSI-x vectors
* try enabling minimum number of vectors required. * try enabling minimum number of vectors required.
*/ */
dev_err(&adapter->netdev->dev, dev_err(&adapter->netdev->dev,
"Failed to enable %d MSI-X, trying %d instead\n", "Failed to enable %d MSI-X, trying %d\n",
vectors, vector_threshold); nvec, VMXNET3_LINUX_MIN_MSIX_VECT);
vectors = vector_threshold; nvec = VMXNET3_LINUX_MIN_MSIX_VECT;
} }
} } while (nvec >= VMXNET3_LINUX_MIN_MSIX_VECT);
dev_info(&adapter->pdev->dev, /*
"Number of MSI-X interrupts which can be allocated " * Should never get here
"is lower than min threshold required.\n"); */
return err; return -ENOSPC;
} }
...@@ -2796,56 +2793,50 @@ vmxnet3_alloc_intr_resources(struct vmxnet3_adapter *adapter) ...@@ -2796,56 +2793,50 @@ vmxnet3_alloc_intr_resources(struct vmxnet3_adapter *adapter)
#ifdef CONFIG_PCI_MSI #ifdef CONFIG_PCI_MSI
if (adapter->intr.type == VMXNET3_IT_MSIX) { if (adapter->intr.type == VMXNET3_IT_MSIX) {
int vector, err = 0; int i, nvec;
adapter->intr.num_intrs = (adapter->share_intr == nvec = adapter->share_intr == VMXNET3_INTR_TXSHARE ?
VMXNET3_INTR_TXSHARE) ? 1 : 1 : adapter->num_tx_queues;
adapter->num_tx_queues; nvec += adapter->share_intr == VMXNET3_INTR_BUDDYSHARE ?
adapter->intr.num_intrs += (adapter->share_intr == 0 : adapter->num_rx_queues;
VMXNET3_INTR_BUDDYSHARE) ? 0 : nvec += 1; /* for link event */
adapter->num_rx_queues; nvec = nvec > VMXNET3_LINUX_MIN_MSIX_VECT ?
adapter->intr.num_intrs += 1; /* for link event */ nvec : VMXNET3_LINUX_MIN_MSIX_VECT;
adapter->intr.num_intrs = (adapter->intr.num_intrs > for (i = 0; i < nvec; i++)
VMXNET3_LINUX_MIN_MSIX_VECT adapter->intr.msix_entries[i].entry = i;
? adapter->intr.num_intrs :
VMXNET3_LINUX_MIN_MSIX_VECT); nvec = vmxnet3_acquire_msix_vectors(adapter, nvec);
if (nvec < 0)
for (vector = 0; vector < adapter->intr.num_intrs; vector++) goto msix_err;
adapter->intr.msix_entries[vector].entry = vector;
err = vmxnet3_acquire_msix_vectors(adapter,
adapter->intr.num_intrs);
/* If we cannot allocate one MSIx vector per queue /* If we cannot allocate one MSIx vector per queue
* then limit the number of rx queues to 1 * then limit the number of rx queues to 1
*/ */
if (err == VMXNET3_LINUX_MIN_MSIX_VECT) { if (nvec == VMXNET3_LINUX_MIN_MSIX_VECT) {
if (adapter->share_intr != VMXNET3_INTR_BUDDYSHARE if (adapter->share_intr != VMXNET3_INTR_BUDDYSHARE
|| adapter->num_rx_queues != 1) { || adapter->num_rx_queues != 1) {
adapter->share_intr = VMXNET3_INTR_TXSHARE; adapter->share_intr = VMXNET3_INTR_TXSHARE;
netdev_err(adapter->netdev, netdev_err(adapter->netdev,
"Number of rx queues : 1\n"); "Number of rx queues : 1\n");
adapter->num_rx_queues = 1; adapter->num_rx_queues = 1;
adapter->intr.num_intrs =
VMXNET3_LINUX_MIN_MSIX_VECT;
} }
return;
} }
if (!err)
return;
adapter->intr.num_intrs = nvec;
return;
msix_err:
/* If we cannot allocate MSIx vectors use only one rx queue */ /* If we cannot allocate MSIx vectors use only one rx queue */
dev_info(&adapter->pdev->dev, dev_info(&adapter->pdev->dev,
"Failed to enable MSI-X, error %d. " "Failed to enable MSI-X, error %d. "
"Limiting #rx queues to 1, try MSI.\n", err); "Limiting #rx queues to 1, try MSI.\n", nvec);
adapter->intr.type = VMXNET3_IT_MSI; adapter->intr.type = VMXNET3_IT_MSI;
} }
if (adapter->intr.type == VMXNET3_IT_MSI) { if (adapter->intr.type == VMXNET3_IT_MSI) {
int err; if (!pci_enable_msi(adapter->pdev)) {
err = pci_enable_msi(adapter->pdev);
if (!err) {
adapter->num_rx_queues = 1; adapter->num_rx_queues = 1;
adapter->intr.num_intrs = 1; adapter->intr.num_intrs = 1;
return; return;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment