Author: jfv
Date: Tue Aug 20 17:50:30 2013
New Revision: 254573
URL: http://svnweb.freebsd.org/changeset/base/254573

Log:
  MFC r254008,254262:  Improve the MSIX setup logic, making sure the requested
  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

Modified:
  releng/9.2/sys/dev/e1000/if_em.c
  releng/9.2/sys/dev/e1000/if_igb.c
  releng/9.2/sys/dev/ixgbe/ixgbe.c
  releng/9.2/sys/dev/ixgbe/ixv.c
Directory Properties:
  releng/9.2/sys/   (props changed)
  releng/9.2/sys/dev/   (props changed)
  releng/9.2/sys/dev/e1000/   (props changed)
  releng/9.2/sys/dev/ixgbe/   (props changed)

Modified: releng/9.2/sys/dev/e1000/if_em.c
==============================================================================
--- releng/9.2/sys/dev/e1000/if_em.c    Tue Aug 20 16:21:05 2013        
(r254572)
+++ releng/9.2/sys/dev/e1000/if_em.c    Tue Aug 20 17:50:30 2013        
(r254573)
@@ -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);
        } 

Modified: releng/9.2/sys/dev/e1000/if_igb.c
==============================================================================
--- releng/9.2/sys/dev/e1000/if_igb.c   Tue Aug 20 16:21:05 2013        
(r254572)
+++ releng/9.2/sys/dev/e1000/if_igb.c   Tue Aug 20 17:50:30 2013        
(r254573)
@@ -972,7 +972,13 @@ igb_mq_start(struct ifnet *ifp, struct 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);
 }
 

Modified: releng/9.2/sys/dev/ixgbe/ixgbe.c
==============================================================================
--- releng/9.2/sys/dev/ixgbe/ixgbe.c    Tue Aug 20 16:21:05 2013        
(r254572)
+++ releng/9.2/sys/dev/ixgbe/ixgbe.c    Tue Aug 20 17:50:30 2013        
(r254573)
@@ -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);
 }
 
 

Modified: releng/9.2/sys/dev/ixgbe/ixv.c
==============================================================================
--- releng/9.2/sys/dev/ixgbe/ixv.c      Tue Aug 20 16:21:05 2013        
(r254572)
+++ releng/9.2/sys/dev/ixgbe/ixv.c      Tue Aug 20 17:50:30 2013        
(r254573)
@@ -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);
 }
_______________________________________________
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