forked from Minki/linux
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: Alexander 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: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
9e7df17e2e
commit
b60b869d5f
@ -2729,47 +2729,44 @@ vmxnet3_read_mac_addr(struct vmxnet3_adapter *adapter, u8 *mac)
|
||||
/*
|
||||
* Enable MSIx vectors.
|
||||
* Returns :
|
||||
* 0 on successful enabling of required vectors,
|
||||
* VMXNET3_LINUX_MIN_MSIX_VECT when only minimum number of vectors required
|
||||
* could be enabled.
|
||||
* number of vectors which can be enabled otherwise (this number is smaller
|
||||
* were enabled.
|
||||
* number of vectors which were enabled otherwise (this number is greater
|
||||
* than VMXNET3_LINUX_MIN_MSIX_VECT)
|
||||
*/
|
||||
|
||||
static int
|
||||
vmxnet3_acquire_msix_vectors(struct vmxnet3_adapter *adapter,
|
||||
int vectors)
|
||||
vmxnet3_acquire_msix_vectors(struct vmxnet3_adapter *adapter, int nvec)
|
||||
{
|
||||
int err = 0, vector_threshold;
|
||||
vector_threshold = VMXNET3_LINUX_MIN_MSIX_VECT;
|
||||
|
||||
while (vectors >= vector_threshold) {
|
||||
err = pci_enable_msix(adapter->pdev, adapter->intr.msix_entries,
|
||||
vectors);
|
||||
do {
|
||||
int err = pci_enable_msix(adapter->pdev,
|
||||
adapter->intr.msix_entries, nvec);
|
||||
if (!err) {
|
||||
adapter->intr.num_intrs = vectors;
|
||||
return 0;
|
||||
return nvec;
|
||||
} else if (err < 0) {
|
||||
dev_err(&adapter->netdev->dev,
|
||||
"Failed to enable MSI-X, error: %d\n", err);
|
||||
vectors = 0;
|
||||
} else if (err < vector_threshold) {
|
||||
break;
|
||||
"Failed to enable MSI-X, error: %d\n", err);
|
||||
return err;
|
||||
} else if (err < VMXNET3_LINUX_MIN_MSIX_VECT) {
|
||||
dev_info(&adapter->pdev->dev,
|
||||
"Number of MSI-X which can be allocated "
|
||||
"is lower than min threshold required.\n");
|
||||
return -ENOSPC;
|
||||
} else {
|
||||
/* If fails to enable required number of MSI-x vectors
|
||||
* try enabling minimum number of vectors required.
|
||||
*/
|
||||
dev_err(&adapter->netdev->dev,
|
||||
"Failed to enable %d MSI-X, trying %d instead\n",
|
||||
vectors, vector_threshold);
|
||||
vectors = vector_threshold;
|
||||
"Failed to enable %d MSI-X, trying %d\n",
|
||||
nvec, VMXNET3_LINUX_MIN_MSIX_VECT);
|
||||
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 "
|
||||
"is lower than min threshold required.\n");
|
||||
return err;
|
||||
/*
|
||||
* Should never get here
|
||||
*/
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
|
||||
@ -2796,56 +2793,50 @@ vmxnet3_alloc_intr_resources(struct vmxnet3_adapter *adapter)
|
||||
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
if (adapter->intr.type == VMXNET3_IT_MSIX) {
|
||||
int vector, err = 0;
|
||||
int i, nvec;
|
||||
|
||||
adapter->intr.num_intrs = (adapter->share_intr ==
|
||||
VMXNET3_INTR_TXSHARE) ? 1 :
|
||||
adapter->num_tx_queues;
|
||||
adapter->intr.num_intrs += (adapter->share_intr ==
|
||||
VMXNET3_INTR_BUDDYSHARE) ? 0 :
|
||||
adapter->num_rx_queues;
|
||||
adapter->intr.num_intrs += 1; /* for link event */
|
||||
nvec = adapter->share_intr == VMXNET3_INTR_TXSHARE ?
|
||||
1 : adapter->num_tx_queues;
|
||||
nvec += adapter->share_intr == VMXNET3_INTR_BUDDYSHARE ?
|
||||
0 : adapter->num_rx_queues;
|
||||
nvec += 1; /* for link event */
|
||||
nvec = nvec > VMXNET3_LINUX_MIN_MSIX_VECT ?
|
||||
nvec : VMXNET3_LINUX_MIN_MSIX_VECT;
|
||||
|
||||
adapter->intr.num_intrs = (adapter->intr.num_intrs >
|
||||
VMXNET3_LINUX_MIN_MSIX_VECT
|
||||
? adapter->intr.num_intrs :
|
||||
VMXNET3_LINUX_MIN_MSIX_VECT);
|
||||
for (i = 0; i < nvec; i++)
|
||||
adapter->intr.msix_entries[i].entry = i;
|
||||
|
||||
for (vector = 0; vector < adapter->intr.num_intrs; vector++)
|
||||
adapter->intr.msix_entries[vector].entry = vector;
|
||||
nvec = vmxnet3_acquire_msix_vectors(adapter, nvec);
|
||||
if (nvec < 0)
|
||||
goto msix_err;
|
||||
|
||||
err = vmxnet3_acquire_msix_vectors(adapter,
|
||||
adapter->intr.num_intrs);
|
||||
/* If we cannot allocate one MSIx vector per queue
|
||||
* 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
|
||||
|| adapter->num_rx_queues != 1) {
|
||||
adapter->share_intr = VMXNET3_INTR_TXSHARE;
|
||||
netdev_err(adapter->netdev,
|
||||
"Number of rx queues : 1\n");
|
||||
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 */
|
||||
dev_info(&adapter->pdev->dev,
|
||||
"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;
|
||||
}
|
||||
|
||||
if (adapter->intr.type == VMXNET3_IT_MSI) {
|
||||
int err;
|
||||
err = pci_enable_msi(adapter->pdev);
|
||||
if (!err) {
|
||||
if (!pci_enable_msi(adapter->pdev)) {
|
||||
adapter->num_rx_queues = 1;
|
||||
adapter->intr.num_intrs = 1;
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user