@@ -957,6 +957,28 @@ static void enable_rx(struct adapter *adap)
957
957
}
958
958
}
959
959
960
+ static int alloc_ofld_rxqs (struct adapter * adap , struct sge_ofld_rxq * q ,
961
+ unsigned int nq , unsigned int per_chan , int msi_idx ,
962
+ u16 * ids )
963
+ {
964
+ int i , err ;
965
+
966
+ for (i = 0 ; i < nq ; i ++ , q ++ ) {
967
+ if (msi_idx > 0 )
968
+ msi_idx ++ ;
969
+ err = t4_sge_alloc_rxq (adap , & q -> rspq , false,
970
+ adap -> port [i / per_chan ],
971
+ msi_idx , q -> fl .size ? & q -> fl : NULL ,
972
+ uldrx_handler );
973
+ if (err )
974
+ return err ;
975
+ memset (& q -> stats , 0 , sizeof (q -> stats ));
976
+ if (ids )
977
+ ids [i ] = q -> rspq .abs_id ;
978
+ }
979
+ return 0 ;
980
+ }
981
+
960
982
/**
961
983
* setup_sge_queues - configure SGE Tx/Rx/response queues
962
984
* @adap: the adapter
@@ -1018,51 +1040,27 @@ freeout: t4_free_sge_resources(adap);
1018
1040
1019
1041
j = s -> ofldqsets / adap -> params .nports ; /* ofld queues per channel */
1020
1042
for_each_ofldrxq (s , i ) {
1021
- struct sge_ofld_rxq * q = & s -> ofldrxq [i ];
1022
- struct net_device * dev = adap -> port [i / j ];
1023
-
1024
- if (msi_idx > 0 )
1025
- msi_idx ++ ;
1026
- err = t4_sge_alloc_rxq (adap , & q -> rspq , false, dev , msi_idx ,
1027
- q -> fl .size ? & q -> fl : NULL ,
1028
- uldrx_handler );
1029
- if (err )
1030
- goto freeout ;
1031
- memset (& q -> stats , 0 , sizeof (q -> stats ));
1032
- s -> ofld_rxq [i ] = q -> rspq .abs_id ;
1033
- err = t4_sge_alloc_ofld_txq (adap , & s -> ofldtxq [i ], dev ,
1043
+ err = t4_sge_alloc_ofld_txq (adap , & s -> ofldtxq [i ],
1044
+ adap -> port [i / j ],
1034
1045
s -> fw_evtq .cntxt_id );
1035
1046
if (err )
1036
1047
goto freeout ;
1037
1048
}
1038
1049
1039
- for_each_rdmarxq (s , i ) {
1040
- struct sge_ofld_rxq * q = & s -> rdmarxq [i ];
1050
+ #define ALLOC_OFLD_RXQS (firstq , nq , per_chan , ids ) do { \
1051
+ err = alloc_ofld_rxqs(adap, firstq, nq, per_chan, msi_idx, ids); \
1052
+ if (err) \
1053
+ goto freeout; \
1054
+ if (msi_idx > 0) \
1055
+ msi_idx += nq; \
1056
+ } while (0)
1041
1057
1042
- if (msi_idx > 0 )
1043
- msi_idx ++ ;
1044
- err = t4_sge_alloc_rxq (adap , & q -> rspq , false, adap -> port [i ],
1045
- msi_idx , q -> fl .size ? & q -> fl : NULL ,
1046
- uldrx_handler );
1047
- if (err )
1048
- goto freeout ;
1049
- memset (& q -> stats , 0 , sizeof (q -> stats ));
1050
- s -> rdma_rxq [i ] = q -> rspq .abs_id ;
1051
- }
1058
+ ALLOC_OFLD_RXQS (s -> ofldrxq , s -> ofldqsets , j , s -> ofld_rxq );
1059
+ ALLOC_OFLD_RXQS (s -> rdmarxq , s -> rdmaqs , 1 , s -> rdma_rxq );
1060
+ j = s -> rdmaciqs / adap -> params .nports ; /* rdmaq queues per channel */
1061
+ ALLOC_OFLD_RXQS (s -> rdmaciq , s -> rdmaciqs , j , s -> rdma_ciq );
1052
1062
1053
- for_each_rdmaciq (s , i ) {
1054
- struct sge_ofld_rxq * q = & s -> rdmaciq [i ];
1055
-
1056
- if (msi_idx > 0 )
1057
- msi_idx ++ ;
1058
- err = t4_sge_alloc_rxq (adap , & q -> rspq , false, adap -> port [i ],
1059
- msi_idx , q -> fl .size ? & q -> fl : NULL ,
1060
- uldrx_handler );
1061
- if (err )
1062
- goto freeout ;
1063
- memset (& q -> stats , 0 , sizeof (q -> stats ));
1064
- s -> rdma_ciq [i ] = q -> rspq .abs_id ;
1065
- }
1063
+ #undef ALLOC_OFLD_RXQS
1066
1064
1067
1065
for_each_port (adap , i ) {
1068
1066
/*
@@ -5705,7 +5703,16 @@ static void cfg_queues(struct adapter *adap)
5705
5703
s -> ofldqsets = adap -> params .nports ;
5706
5704
/* For RDMA one Rx queue per channel suffices */
5707
5705
s -> rdmaqs = adap -> params .nports ;
5708
- s -> rdmaciqs = adap -> params .nports ;
5706
+ /* Try and allow at least 1 CIQ per cpu rounding down
5707
+ * to the number of ports, with a minimum of 1 per port.
5708
+ * A 2 port card in a 6 cpu system: 6 CIQs, 3 / port.
5709
+ * A 4 port card in a 6 cpu system: 4 CIQs, 1 / port.
5710
+ * A 4 port card in a 2 cpu system: 4 CIQs, 1 / port.
5711
+ */
5712
+ s -> rdmaciqs = min_t (int , MAX_RDMA_CIQS , num_online_cpus ());
5713
+ s -> rdmaciqs = (s -> rdmaciqs / adap -> params .nports ) *
5714
+ adap -> params .nports ;
5715
+ s -> rdmaciqs = max_t (int , s -> rdmaciqs , adap -> params .nports );
5709
5716
}
5710
5717
5711
5718
for (i = 0 ; i < ARRAY_SIZE (s -> ethrxq ); i ++ ) {
@@ -5791,12 +5798,17 @@ static void reduce_ethqs(struct adapter *adap, int n)
5791
5798
static int enable_msix (struct adapter * adap )
5792
5799
{
5793
5800
int ofld_need = 0 ;
5794
- int i , want , need ;
5801
+ int i , want , need , allocated ;
5795
5802
struct sge * s = & adap -> sge ;
5796
5803
unsigned int nchan = adap -> params .nports ;
5797
- struct msix_entry entries [ MAX_INGQ + 1 ] ;
5804
+ struct msix_entry * entries ;
5798
5805
5799
- for (i = 0 ; i < ARRAY_SIZE (entries ); ++ i )
5806
+ entries = kmalloc (sizeof (* entries ) * (MAX_INGQ + 1 ),
5807
+ GFP_KERNEL );
5808
+ if (!entries )
5809
+ return - ENOMEM ;
5810
+
5811
+ for (i = 0 ; i < MAX_INGQ + 1 ; ++ i )
5800
5812
entries [i ].entry = i ;
5801
5813
5802
5814
want = s -> max_ethqsets + EXTRA_VECS ;
@@ -5813,29 +5825,39 @@ static int enable_msix(struct adapter *adap)
5813
5825
#else
5814
5826
need = adap -> params .nports + EXTRA_VECS + ofld_need ;
5815
5827
#endif
5816
- want = pci_enable_msix_range (adap -> pdev , entries , need , want );
5817
- if (want < 0 )
5818
- return want ;
5828
+ allocated = pci_enable_msix_range (adap -> pdev , entries , need , want );
5829
+ if (allocated < 0 ) {
5830
+ dev_info (adap -> pdev_dev , "not enough MSI-X vectors left,"
5831
+ " not using MSI-X\n" );
5832
+ kfree (entries );
5833
+ return allocated ;
5834
+ }
5819
5835
5820
- /*
5821
- * Distribute available vectors to the various queue groups.
5836
+ /* Distribute available vectors to the various queue groups.
5822
5837
* Every group gets its minimum requirement and NIC gets top
5823
5838
* priority for leftovers.
5824
5839
*/
5825
- i = want - EXTRA_VECS - ofld_need ;
5840
+ i = allocated - EXTRA_VECS - ofld_need ;
5826
5841
if (i < s -> max_ethqsets ) {
5827
5842
s -> max_ethqsets = i ;
5828
5843
if (i < s -> ethqsets )
5829
5844
reduce_ethqs (adap , i );
5830
5845
}
5831
5846
if (is_offload (adap )) {
5832
- i = want - EXTRA_VECS - s -> max_ethqsets ;
5833
- i -= ofld_need - nchan ;
5847
+ if (allocated < want ) {
5848
+ s -> rdmaqs = nchan ;
5849
+ s -> rdmaciqs = nchan ;
5850
+ }
5851
+
5852
+ /* leftovers go to OFLD */
5853
+ i = allocated - EXTRA_VECS - s -> max_ethqsets -
5854
+ s -> rdmaqs - s -> rdmaciqs ;
5834
5855
s -> ofldqsets = (i / nchan ) * nchan ; /* round down */
5835
5856
}
5836
- for (i = 0 ; i < want ; ++ i )
5857
+ for (i = 0 ; i < allocated ; ++ i )
5837
5858
adap -> msix_info [i ].vec = entries [i ].vector ;
5838
5859
5860
+ kfree (entries );
5839
5861
return 0 ;
5840
5862
}
5841
5863
0 commit comments