Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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...
commit 002b945b16737a4fa37e81439321e43ad4f89704 1 parent 70e4841
authored August 20, 2013
36  sys/dev/e1000/if_em.c
@@ -2277,7 +2277,7 @@ em_local_timer(void *arg)
2277 2277
 
2278 2278
 	/* Mask to use in the irq trigger */
2279 2279
 	if (adapter->msix_mem)
2280  
-		trigger = rxr->ims; /* RX for 82574 */
  2280
+		trigger = rxr->ims;
2281 2281
 	else
2282 2282
 		trigger = E1000_ICS_RXDMT0;
2283 2283
 
@@ -2742,7 +2742,7 @@ static int
2742 2742
 em_setup_msix(struct adapter *adapter)
2743 2743
 {
2744 2744
 	device_t dev = adapter->dev;
2745  
-	int val = 0;
  2745
+	int val;
2746 2746
 
2747 2747
 	/*
2748 2748
 	** Setup MSI/X for Hartwell: tests have shown
@@ -2756,37 +2756,43 @@ em_setup_msix(struct adapter *adapter)
2756 2756
 		int rid = PCIR_BAR(EM_MSIX_BAR);
2757 2757
 		adapter->msix_mem = bus_alloc_resource_any(dev,
2758 2758
 		    SYS_RES_MEMORY, &rid, RF_ACTIVE);
2759  
-       		if (!adapter->msix_mem) {
  2759
+       		if (adapter->msix_mem == NULL) {
2760 2760
 			/* May not be enabled */
2761 2761
                		device_printf(adapter->dev,
2762 2762
 			    "Unable to map MSIX table \n");
2763 2763
 			goto msi;
2764 2764
        		}
2765 2765
 		val = pci_msix_count(dev); 
2766  
-		/* We only need 3 vectors */
2767  
-		if (val > 3)
  2766
+		/* We only need/want 3 vectors */
  2767
+		if (val >= 3)
2768 2768
 			val = 3;
2769  
-		if ((val != 3) && (val != 5)) {
2770  
-			bus_release_resource(dev, SYS_RES_MEMORY,
2771  
-			    PCIR_BAR(EM_MSIX_BAR), adapter->msix_mem);
2772  
-			adapter->msix_mem = NULL;
  2769
+		else {
2773 2770
                		device_printf(adapter->dev,
2774  
-			    "MSIX: incorrect vectors, using MSI\n");
  2771
+			    "MSIX: insufficient vectors, using MSI\n");
2775 2772
 			goto msi;
2776 2773
 		}
2777 2774
 
2778  
-		if (pci_alloc_msix(dev, &val) == 0) {
  2775
+		if ((pci_alloc_msix(dev, &val) == 0) && (val == 3)) {
2779 2776
 			device_printf(adapter->dev,
2780 2777
 			    "Using MSIX interrupts "
2781 2778
 			    "with %d vectors\n", val);
  2779
+			return (val);
2782 2780
 		}
2783 2781
 
2784  
-		return (val);
  2782
+		/*
  2783
+		** If MSIX alloc failed or provided us with
  2784
+		** less than needed, free and fall through to MSI
  2785
+		*/
  2786
+		pci_release_msi(dev);
2785 2787
 	}
2786 2788
 msi:
2787  
-       	val = pci_msi_count(dev);
2788  
-       	if (val == 1 && pci_alloc_msi(dev, &val) == 0) {
2789  
-               	adapter->msix = 1;
  2789
+	if (adapter->msix_mem != NULL) {
  2790
+		bus_release_resource(dev, SYS_RES_MEMORY,
  2791
+		    PCIR_BAR(EM_MSIX_BAR), adapter->msix_mem);
  2792
+		adapter->msix_mem = NULL;
  2793
+	}
  2794
+       	val = 1;
  2795
+       	if (pci_alloc_msi(dev, &val) == 0) {
2790 2796
                	device_printf(adapter->dev,"Using an MSI interrupt\n");
2791 2797
 		return (val);
2792 2798
 	} 
43  sys/dev/e1000/if_igb.c
@@ -972,7 +972,13 @@ igb_mq_start(struct ifnet *ifp, struct mbuf *m)
972 972
 	que = &adapter->queues[i];
973 973
 
974 974
 	err = drbr_enqueue(ifp, txr->br, m);
975  
-	taskqueue_enqueue(que->tq, &txr->txq_task);
  975
+	if (err)
  976
+		return (err);
  977
+	if (IGB_TX_TRYLOCK(txr)) {
  978
+		err = igb_mq_start_locked(ifp, txr);
  979
+		IGB_TX_UNLOCK(txr);
  980
+	} else
  981
+		taskqueue_enqueue(que->tq, &txr->txq_task);
976 982
 
977 983
 	return (err);
978 984
 }
@@ -2834,24 +2840,19 @@ igb_setup_msix(struct adapter *adapter)
2834 2840
 		goto msi;
2835 2841
 
2836 2842
 	/* First try MSI/X */
  2843
+	msgs = pci_msix_count(dev); 
  2844
+	if (msgs == 0)
  2845
+		goto msi;
2837 2846
 	rid = PCIR_BAR(IGB_MSIX_BAR);
2838 2847
 	adapter->msix_mem = bus_alloc_resource_any(dev,
2839 2848
 	    SYS_RES_MEMORY, &rid, RF_ACTIVE);
2840  
-       	if (!adapter->msix_mem) {
  2849
+       	if (adapter->msix_mem == NULL) {
2841 2850
 		/* May not be enabled */
2842 2851
 		device_printf(adapter->dev,
2843 2852
 		    "Unable to map MSIX table \n");
2844 2853
 		goto msi;
2845 2854
 	}
2846 2855
 
2847  
-	msgs = pci_msix_count(dev); 
2848  
-	if (msgs == 0) { /* system has msix disabled */
2849  
-		bus_release_resource(dev, SYS_RES_MEMORY,
2850  
-		    PCIR_BAR(IGB_MSIX_BAR), adapter->msix_mem);
2851  
-		adapter->msix_mem = NULL;
2852  
-		goto msi;
2853  
-	}
2854  
-
2855 2856
 	/* Figure out a reasonable auto config value */
2856 2857
 	queues = (mp_ncpus > (msgs-1)) ? (msgs-1) : mp_ncpus;
2857 2858
 
@@ -2894,20 +2895,32 @@ igb_setup_msix(struct adapter *adapter)
2894 2895
 		    "MSIX Configuration Problem, "
2895 2896
 		    "%d vectors configured, but %d queues wanted!\n",
2896 2897
 		    msgs, want);
2897  
-		return (0);
  2898
+		goto msi;
2898 2899
 	}
2899  
-	if ((msgs) && pci_alloc_msix(dev, &msgs) == 0) {
  2900
+	if ((pci_alloc_msix(dev, &msgs) == 0) && (msgs == want)) {
2900 2901
                	device_printf(adapter->dev,
2901 2902
 		    "Using MSIX interrupts with %d vectors\n", msgs);
2902 2903
 		adapter->num_queues = queues;
2903 2904
 		return (msgs);
2904 2905
 	}
  2906
+	/*
  2907
+	** If MSIX alloc failed or provided us with
  2908
+	** less than needed, free and fall through to MSI
  2909
+	*/
  2910
+	pci_release_msi(dev);
  2911
+
2905 2912
 msi:
2906  
-       	msgs = pci_msi_count(dev);
2907  
-	if (msgs == 1 && pci_alloc_msi(dev, &msgs) == 0) {
2908  
-		device_printf(adapter->dev," Using MSI interrupt\n");
  2913
+       	if (adapter->msix_mem != NULL) {
  2914
+		bus_release_resource(dev, SYS_RES_MEMORY,
  2915
+		    PCIR_BAR(IGB_MSIX_BAR), adapter->msix_mem);
  2916
+		adapter->msix_mem = NULL;
  2917
+	}
  2918
+       	msgs = 1;
  2919
+	if (pci_alloc_msi(dev, &msgs) == 0) {
  2920
+		device_printf(adapter->dev," Using an MSI interrupt\n");
2909 2921
 		return (msgs);
2910 2922
 	}
  2923
+	device_printf(adapter->dev," Using a Legacy interrupt\n");
2911 2924
 	return (0);
2912 2925
 }
2913 2926
 
41  sys/dev/ixgbe/ixgbe.c
@@ -2415,29 +2415,24 @@ ixgbe_setup_msix(struct adapter *adapter)
2415 2415
 		goto msi;
2416 2416
 
2417 2417
 	/* First try MSI/X */
  2418
+	msgs = pci_msix_count(dev); 
  2419
+	if (msgs == 0)
  2420
+		goto msi;
2418 2421
 	rid = PCIR_BAR(MSIX_82598_BAR);
2419 2422
 	adapter->msix_mem = bus_alloc_resource_any(dev,
2420 2423
 	    SYS_RES_MEMORY, &rid, RF_ACTIVE);
2421  
-       	if (!adapter->msix_mem) {
  2424
+       	if (adapter->msix_mem == NULL) {
2422 2425
 		rid += 4;	/* 82599 maps in higher BAR */
2423 2426
 		adapter->msix_mem = bus_alloc_resource_any(dev,
2424 2427
 		    SYS_RES_MEMORY, &rid, RF_ACTIVE);
2425 2428
 	}
2426  
-       	if (!adapter->msix_mem) {
  2429
+       	if (adapter->msix_mem == NULL) {
2427 2430
 		/* May not be enabled */
2428 2431
 		device_printf(adapter->dev,
2429 2432
 		    "Unable to map MSIX table \n");
2430 2433
 		goto msi;
2431 2434
 	}
2432 2435
 
2433  
-	msgs = pci_msix_count(dev); 
2434  
-	if (msgs == 0) { /* system has msix disabled */
2435  
-		bus_release_resource(dev, SYS_RES_MEMORY,
2436  
-		    rid, adapter->msix_mem);
2437  
-		adapter->msix_mem = NULL;
2438  
-		goto msi;
2439  
-	}
2440  
-
2441 2436
 	/* Figure out a reasonable auto config value */
2442 2437
 	queues = (mp_ncpus > (msgs-1)) ? (msgs-1) : mp_ncpus;
2443 2438
 
@@ -2459,21 +2454,33 @@ ixgbe_setup_msix(struct adapter *adapter)
2459 2454
 		    "MSIX Configuration Problem, "
2460 2455
 		    "%d vectors but %d queues wanted!\n",
2461 2456
 		    msgs, want);
2462  
-		return (0); /* Will go to Legacy setup */
  2457
+		goto msi;
2463 2458
 	}
2464  
-	if ((msgs) && pci_alloc_msix(dev, &msgs) == 0) {
  2459
+	if ((pci_alloc_msix(dev, &msgs) == 0) && (msgs == want)) {
2465 2460
                	device_printf(adapter->dev,
2466 2461
 		    "Using MSIX interrupts with %d vectors\n", msgs);
2467 2462
 		adapter->num_queues = queues;
2468 2463
 		return (msgs);
2469 2464
 	}
  2465
+	/*
  2466
+	** If MSIX alloc failed or provided us with
  2467
+	** less than needed, free and fall through to MSI
  2468
+	*/
  2469
+	pci_release_msi(dev);
  2470
+
2470 2471
 msi:
2471  
-       	msgs = pci_msi_count(dev);
2472  
-       	if (msgs == 1 && pci_alloc_msi(dev, &msgs) == 0)
  2472
+       	if (adapter->msix_mem != NULL) {
  2473
+		bus_release_resource(dev, SYS_RES_MEMORY,
  2474
+		    rid, adapter->msix_mem);
  2475
+		adapter->msix_mem = NULL;
  2476
+	}
  2477
+       	msgs = 1;
  2478
+       	if (pci_alloc_msi(dev, &msgs) == 0) {
2473 2479
                	device_printf(adapter->dev,"Using an MSI interrupt\n");
2474  
-	else
2475  
-               	device_printf(adapter->dev,"Using a Legacy interrupt\n");
2476  
-	return (msgs);
  2480
+		return (msgs);
  2481
+	}
  2482
+	device_printf(adapter->dev,"Using a Legacy interrupt\n");
  2483
+	return (0);
2477 2484
 }
2478 2485
 
2479 2486
 
22  sys/dev/ixgbe/ixv.c
@@ -1680,37 +1680,37 @@ static int
1680 1680
 ixv_setup_msix(struct adapter *adapter)
1681 1681
 {
1682 1682
 	device_t dev = adapter->dev;
1683  
-	int rid, vectors, want = 2;
  1683
+	int rid, want;
1684 1684
 
1685 1685
 
1686 1686
 	/* First try MSI/X */
1687 1687
 	rid = PCIR_BAR(3);
1688 1688
 	adapter->msix_mem = bus_alloc_resource_any(dev,
1689 1689
 	    SYS_RES_MEMORY, &rid, RF_ACTIVE);
1690  
-       	if (!adapter->msix_mem) {
  1690
+       	if (adapter->msix_mem == NULL) {
1691 1691
 		device_printf(adapter->dev,
1692 1692
 		    "Unable to map MSIX table \n");
1693 1693
 		goto out;
1694 1694
 	}
1695 1695
 
1696  
-	vectors = pci_msix_count(dev); 
1697  
-	if (vectors < 2) {
1698  
-		bus_release_resource(dev, SYS_RES_MEMORY,
1699  
-		    rid, adapter->msix_mem);
1700  
-		adapter->msix_mem = NULL;
1701  
-		goto out;
1702  
-	}
1703  
-
1704 1696
 	/*
1705 1697
 	** Want two vectors: one for a queue,
1706 1698
 	** plus an additional for mailbox.
1707 1699
 	*/
1708  
-	if (pci_alloc_msix(dev, &want) == 0) {
  1700
+	want = 2;
  1701
+	if ((pci_alloc_msix(dev, &want) == 0) && (want == 2)) {
1709 1702
                	device_printf(adapter->dev,
1710 1703
 		    "Using MSIX interrupts with %d vectors\n", want);
1711 1704
 		return (want);
1712 1705
 	}
  1706
+	/* Release in case alloc was insufficient */
  1707
+	pci_release_msi(dev);
1713 1708
 out:
  1709
+       	if (adapter->msix_mem != NULL) {
  1710
+		bus_release_resource(dev, SYS_RES_MEMORY,
  1711
+		    rid, adapter->msix_mem);
  1712
+		adapter->msix_mem = NULL;
  1713
+	}
1714 1714
 	device_printf(adapter->dev,"MSIX config error\n");
1715 1715
 	return (ENXIO);
1716 1716
 }

0 notes on commit 002b945

Please sign in to comment.
Something went wrong with that request. Please try again.