From c8a53736fe9139a202d17ed7f95389d33326cb61 Mon Sep 17 00:00:00 2001 From: jfv Date: Mon, 12 Aug 2013 22:54:38 +0000 Subject: 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 --- sys/dev/e1000/if_em.c | 21 ++++++++++++++------- sys/dev/e1000/if_igb.c | 13 +++++++++---- sys/dev/ixgbe/ixgbe.c | 8 +++++++- sys/dev/ixgbe/ixv.c | 4 +++- 4 files changed, 33 insertions(+), 13 deletions(-) (limited to 'sys/dev') diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index 9499953..b3327e8 100644 --- a/sys/dev/e1000/if_em.c +++ b/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; @@ -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"); diff --git a/sys/dev/e1000/if_igb.c b/sys/dev/e1000/if_igb.c index d524832..cb079fa 100644 --- a/sys/dev/e1000/if_igb.c +++ b/sys/dev/e1000/if_igb.c @@ -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); } diff --git a/sys/dev/ixgbe/ixgbe.c b/sys/dev/ixgbe/ixgbe.c index ca4aa66..e6dc239 100644 --- a/sys/dev/ixgbe/ixgbe.c +++ b/sys/dev/ixgbe/ixgbe.c @@ -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, diff --git a/sys/dev/ixgbe/ixv.c b/sys/dev/ixgbe/ixv.c index 20131aa..c0cd7ae 100644 --- a/sys/dev/ixgbe/ixv.c +++ b/sys/dev/ixgbe/ixv.c @@ -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, -- cgit v1.1