Author: jfv
Date: Mon Aug 12 22:54:38 2013
New Revision: 254262
URL: http://svnweb.freebsd.org/changeset/base/254262

Log:
  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

Modified:
  head/sys/dev/e1000/if_em.c
  head/sys/dev/e1000/if_igb.c
  head/sys/dev/ixgbe/ixgbe.c
  head/sys/dev/ixgbe/ixv.c

Modified: head/sys/dev/e1000/if_em.c
==============================================================================
--- head/sys/dev/e1000/if_em.c  Mon Aug 12 22:27:53 2013        (r254261)
+++ head/sys/dev/e1000/if_em.c  Mon Aug 12 22:54:38 2013        (r254262)
@@ -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");

Modified: head/sys/dev/e1000/if_igb.c
==============================================================================
--- head/sys/dev/e1000/if_igb.c Mon Aug 12 22:27:53 2013        (r254261)
+++ head/sys/dev/e1000/if_igb.c Mon Aug 12 22:54:38 2013        (r254262)
@@ -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);
 }
 

Modified: head/sys/dev/ixgbe/ixgbe.c
==============================================================================
--- head/sys/dev/ixgbe/ixgbe.c  Mon Aug 12 22:27:53 2013        (r254261)
+++ head/sys/dev/ixgbe/ixgbe.c  Mon Aug 12 22:54:38 2013        (r254262)
@@ -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,

Modified: head/sys/dev/ixgbe/ixv.c
==============================================================================
--- head/sys/dev/ixgbe/ixv.c    Mon Aug 12 22:27:53 2013        (r254261)
+++ head/sys/dev/ixgbe/ixv.c    Mon Aug 12 22:54:38 2013        (r254262)
@@ -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,
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to