Permalink
Browse files

MFC r254008,254262: Improve the MSIX setup logic, making sure the req…

…uested

number of vectors are actually obtained, and if not cleaning up before falling
back to MSI. Also make the fallback decision as early as possible.

Approved by: re
  • Loading branch information...
1 parent 70e4841 commit 002b945b16737a4fa37e81439321e43ad4f89704 jfv committed Aug 20, 2013
Showing with 84 additions and 58 deletions.
  1. +21 −15 sys/dev/e1000/if_em.c
  2. +28 −15 sys/dev/e1000/if_igb.c
  3. +24 −17 sys/dev/ixgbe/ixgbe.c
  4. +11 −11 sys/dev/ixgbe/ixv.c
View
36 sys/dev/e1000/if_em.c
@@ -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;
@@ -2742,7 +2742,7 @@ static int
em_setup_msix(struct adapter *adapter)
{
device_t dev = adapter->dev;
- int val = 0;
+ int val;
/*
** Setup MSI/X for Hartwell: tests have shown
@@ -2756,37 +2756,43 @@ em_setup_msix(struct adapter *adapter)
int rid = PCIR_BAR(EM_MSIX_BAR);
adapter->msix_mem = bus_alloc_resource_any(dev,
SYS_RES_MEMORY, &rid, RF_ACTIVE);
- if (!adapter->msix_mem) {
+ if (adapter->msix_mem == NULL) {
/* May not be enabled */
device_printf(adapter->dev,
"Unable to map MSIX table \n");
goto msi;
}
val = pci_msix_count(dev);
- /* We only need 3 vectors */
- if (val > 3)
+ /* We only need/want 3 vectors */
+ if (val >= 3)
val = 3;
- if ((val != 3) && (val != 5)) {
- bus_release_resource(dev, SYS_RES_MEMORY,
- PCIR_BAR(EM_MSIX_BAR), adapter->msix_mem);
- adapter->msix_mem = NULL;
+ else {
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);
}
- return (val);
+ /*
+ ** If MSIX alloc failed or provided us with
+ ** less than needed, free and fall through to MSI
+ */
+ pci_release_msi(dev);
}
msi:
- val = pci_msi_count(dev);
- if (val == 1 && pci_alloc_msi(dev, &val) == 0) {
- adapter->msix = 1;
+ 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");
return (val);
}
View
43 sys/dev/e1000/if_igb.c
@@ -972,7 +972,13 @@ igb_mq_start(struct ifnet *ifp, struct mbuf *m)
que = &adapter->queues[i];
err = drbr_enqueue(ifp, txr->br, m);
- taskqueue_enqueue(que->tq, &txr->txq_task);
+ if (err)
+ return (err);
+ if (IGB_TX_TRYLOCK(txr)) {
+ err = igb_mq_start_locked(ifp, txr);
+ IGB_TX_UNLOCK(txr);
+ } else
+ taskqueue_enqueue(que->tq, &txr->txq_task);
return (err);
}
@@ -2834,24 +2840,19 @@ igb_setup_msix(struct adapter *adapter)
goto msi;
/* First try MSI/X */
+ msgs = pci_msix_count(dev);
+ if (msgs == 0)
+ goto msi;
rid = PCIR_BAR(IGB_MSIX_BAR);
adapter->msix_mem = bus_alloc_resource_any(dev,
SYS_RES_MEMORY, &rid, RF_ACTIVE);
- if (!adapter->msix_mem) {
+ if (adapter->msix_mem == NULL) {
/* May not be enabled */
device_printf(adapter->dev,
"Unable to map MSIX table \n");
goto msi;
}
- msgs = pci_msix_count(dev);
- if (msgs == 0) { /* system has msix disabled */
- bus_release_resource(dev, SYS_RES_MEMORY,
- PCIR_BAR(IGB_MSIX_BAR), adapter->msix_mem);
- adapter->msix_mem = NULL;
- goto msi;
- }
-
/* Figure out a reasonable auto config value */
queues = (mp_ncpus > (msgs-1)) ? (msgs-1) : mp_ncpus;
@@ -2894,20 +2895,32 @@ igb_setup_msix(struct adapter *adapter)
"MSIX Configuration Problem, "
"%d vectors configured, but %d queues wanted!\n",
msgs, want);
- return (0);
+ goto msi;
}
- if ((msgs) && 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:
- msgs = pci_msi_count(dev);
- if (msgs == 1 && pci_alloc_msi(dev, &msgs) == 0) {
- device_printf(adapter->dev," Using MSI interrupt\n");
+ if (adapter->msix_mem != NULL) {
+ bus_release_resource(dev, SYS_RES_MEMORY,
+ PCIR_BAR(IGB_MSIX_BAR), adapter->msix_mem);
+ adapter->msix_mem = NULL;
+ }
+ msgs = 1;
+ if (pci_alloc_msi(dev, &msgs) == 0) {
+ device_printf(adapter->dev," Using an MSI interrupt\n");
return (msgs);
}
+ device_printf(adapter->dev," Using a Legacy interrupt\n");
return (0);
}
View
41 sys/dev/ixgbe/ixgbe.c
@@ -2415,29 +2415,24 @@ ixgbe_setup_msix(struct adapter *adapter)
goto msi;
/* First try MSI/X */
+ msgs = pci_msix_count(dev);
+ if (msgs == 0)
+ goto msi;
rid = PCIR_BAR(MSIX_82598_BAR);
adapter->msix_mem = bus_alloc_resource_any(dev,
SYS_RES_MEMORY, &rid, RF_ACTIVE);
- if (!adapter->msix_mem) {
+ if (adapter->msix_mem == NULL) {
rid += 4; /* 82599 maps in higher BAR */
adapter->msix_mem = bus_alloc_resource_any(dev,
SYS_RES_MEMORY, &rid, RF_ACTIVE);
}
- if (!adapter->msix_mem) {
+ if (adapter->msix_mem == NULL) {
/* May not be enabled */
device_printf(adapter->dev,
"Unable to map MSIX table \n");
goto msi;
}
- msgs = pci_msix_count(dev);
- if (msgs == 0) { /* system has msix disabled */
- bus_release_resource(dev, SYS_RES_MEMORY,
- rid, adapter->msix_mem);
- adapter->msix_mem = NULL;
- goto msi;
- }
-
/* Figure out a reasonable auto config value */
queues = (mp_ncpus > (msgs-1)) ? (msgs-1) : mp_ncpus;
@@ -2459,21 +2454,33 @@ ixgbe_setup_msix(struct adapter *adapter)
"MSIX Configuration Problem, "
"%d vectors but %d queues wanted!\n",
msgs, want);
- return (0); /* Will go to Legacy setup */
+ goto msi;
}
- if ((msgs) && 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:
- msgs = pci_msi_count(dev);
- if (msgs == 1 && pci_alloc_msi(dev, &msgs) == 0)
+ if (adapter->msix_mem != NULL) {
+ bus_release_resource(dev, SYS_RES_MEMORY,
+ rid, adapter->msix_mem);
+ adapter->msix_mem = NULL;
+ }
+ msgs = 1;
+ if (pci_alloc_msi(dev, &msgs) == 0) {
device_printf(adapter->dev,"Using an MSI interrupt\n");
- else
- device_printf(adapter->dev,"Using a Legacy interrupt\n");
- return (msgs);
+ return (msgs);
+ }
+ device_printf(adapter->dev,"Using a Legacy interrupt\n");
+ return (0);
}
View
22 sys/dev/ixgbe/ixv.c
@@ -1680,37 +1680,37 @@ static int
ixv_setup_msix(struct adapter *adapter)
{
device_t dev = adapter->dev;
- int rid, vectors, want = 2;
+ int rid, want;
/* First try MSI/X */
rid = PCIR_BAR(3);
adapter->msix_mem = bus_alloc_resource_any(dev,
SYS_RES_MEMORY, &rid, RF_ACTIVE);
- if (!adapter->msix_mem) {
+ if (adapter->msix_mem == NULL) {
device_printf(adapter->dev,
"Unable to map MSIX table \n");
goto out;
}
- vectors = pci_msix_count(dev);
- if (vectors < 2) {
- bus_release_resource(dev, SYS_RES_MEMORY,
- rid, adapter->msix_mem);
- adapter->msix_mem = NULL;
- goto out;
- }
-
/*
** Want two vectors: one for a queue,
** plus an additional for mailbox.
*/
- if (pci_alloc_msix(dev, &want) == 0) {
+ want = 2;
+ 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,
+ rid, adapter->msix_mem);
+ adapter->msix_mem = NULL;
+ }
device_printf(adapter->dev,"MSIX config error\n");
return (ENXIO);
}

0 comments on commit 002b945

Please sign in to comment.