Improve the MSIX setup code in the drivers, thanks to Marius for

the changes. Make sure that pci_alloc_msix() does give us the vectors
we need and fall back to MSI when it doesn't, also release any that
were allocated when insufficient.

MFC after: 3 days
This commit is contained in:
Jack F Vogel 2013-08-12 22:54:38 +00:00
parent 57b5fc5f3d
commit 4dc63104ae
4 changed files with 33 additions and 13 deletions

@ -2277,7 +2277,7 @@ em_local_timer(void *arg)
/* Mask to use in the irq trigger */
if (adapter->msix_mem)
trigger = rxr->ims; /* RX for 82574 */
trigger = rxr->ims;
else
trigger = E1000_ICS_RXDMT0;
@ -2775,23 +2775,30 @@ em_setup_msix(struct adapter *adapter)
if (val >= 3)
val = 3;
else {
bus_release_resource(dev, SYS_RES_MEMORY,
PCIR_BAR(EM_MSIX_BAR), adapter->msix_mem);
adapter->msix_mem = NULL;
device_printf(adapter->dev,
"MSIX: incorrect vectors, using MSI\n");
"MSIX: insufficient vectors, using MSI\n");
goto msi;
}
if (pci_alloc_msix(dev, &val) == 0) {
if ((pci_alloc_msix(dev, &val) == 0) && (val == 3)) {
device_printf(adapter->dev,
"Using MSIX interrupts "
"with %d vectors\n", val);
return (val);
}
/* Fall through to MSI */
/*
** If MSIX alloc failed or provided us with
** less than needed, free and fall through to MSI
*/
pci_release_msi(dev);
}
msi:
if (adapter->msix_mem != NULL) {
bus_release_resource(dev, SYS_RES_MEMORY,
PCIR_BAR(EM_MSIX_BAR), adapter->msix_mem);
adapter->msix_mem = NULL;
}
val = 1;
if (pci_alloc_msi(dev, &val) == 0) {
device_printf(adapter->dev,"Using an MSI interrupt\n");

@ -2899,13 +2899,18 @@ igb_setup_msix(struct adapter *adapter)
msgs, want);
goto msi;
}
if (pci_alloc_msix(dev, &msgs) == 0) {
if ((pci_alloc_msix(dev, &msgs) == 0) && (msgs == want)) {
device_printf(adapter->dev,
"Using MSIX interrupts with %d vectors\n", msgs);
adapter->num_queues = queues;
return (msgs);
}
/* Fallback to MSI configuration */
/*
** If MSIX alloc failed or provided us with
** less than needed, free and fall through to MSI
*/
pci_release_msi(dev);
msi:
if (adapter->msix_mem != NULL) {
bus_release_resource(dev, SYS_RES_MEMORY,
@ -2914,10 +2919,10 @@ msi:
}
msgs = 1;
if (pci_alloc_msi(dev, &msgs) == 0) {
device_printf(adapter->dev," Using MSI interrupt\n");
device_printf(adapter->dev," Using an MSI interrupt\n");
return (msgs);
}
/* Default to a legacy interrupt */
device_printf(adapter->dev," Using a Legacy interrupt\n");
return (0);
}

@ -2456,12 +2456,18 @@ ixgbe_setup_msix(struct adapter *adapter)
msgs, want);
goto msi;
}
if (pci_alloc_msix(dev, &msgs) == 0) {
if ((pci_alloc_msix(dev, &msgs) == 0) && (msgs == want)) {
device_printf(adapter->dev,
"Using MSIX interrupts with %d vectors\n", msgs);
adapter->num_queues = queues;
return (msgs);
}
/*
** If MSIX alloc failed or provided us with
** less than needed, free and fall through to MSI
*/
pci_release_msi(dev);
msi:
if (adapter->msix_mem != NULL) {
bus_release_resource(dev, SYS_RES_MEMORY,

@ -1704,11 +1704,13 @@ ixv_setup_msix(struct adapter *adapter)
** plus an additional for mailbox.
*/
want = 2;
if (pci_alloc_msix(dev, &want) == 0) {
if ((pci_alloc_msix(dev, &want) == 0) && (want == 2)) {
device_printf(adapter->dev,
"Using MSIX interrupts with %d vectors\n", want);
return (want);
}
/* Release in case alloc was insufficient */
pci_release_msi(dev);
out:
if (adapter->msix_mem != NULL) {
bus_release_resource(dev, SYS_RES_MEMORY,