Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ice: Fix and refactor Rx queue disable for VFs

Currently when a VF driver sends the PF a request to disable Rx queues
we will disable them one at a time, even if the VF driver sent us a
batch of queues to disable. This is causing issues where the Rx queue
disable times out with LFC enabled. This can be improved by detecting
when the VF is trying to disable all of its queues.

Also remove the variable num_qs_ena from the ice_vf structure as it was
only used to see if there were no Rx and no Tx queues active. Instead
add a function that checks if both the vf->rxq_ena and vf->txq_ena
bitmaps are empty.

Signed-off-by: Brett Creeley <brett.creeley@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

authored by

Brett Creeley and committed by
Jeff Kirsher
e1fe6926 2309ae38

+27 -10
+27 -9
drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c
··· 91 91 } 92 92 93 93 /** 94 + * ice_vf_has_no_qs_ena - check if the VF has any Rx or Tx queues enabled 95 + * @vf: the VF to check 96 + * 97 + * Returns true if the VF has no Rx and no Tx queues enabled and returns false 98 + * otherwise 99 + */ 100 + static bool ice_vf_has_no_qs_ena(struct ice_vf *vf) 101 + { 102 + return (!bitmap_weight(vf->rxq_ena, ICE_MAX_BASE_QS_PER_VF) && 103 + !bitmap_weight(vf->txq_ena, ICE_MAX_BASE_QS_PER_VF)); 104 + } 105 + 106 + /** 94 107 * ice_is_vf_link_up - check if the VF's link is up 95 108 * @vf: VF to check if link is up 96 109 */ ··· 114 101 if (ice_check_vf_init(pf, vf)) 115 102 return false; 116 103 117 - if (!vf->num_qs_ena) 104 + if (ice_vf_has_no_qs_ena(vf)) 118 105 return false; 119 106 else if (vf->link_forced) 120 107 return vf->link_up; ··· 268 255 /* Clear Rx/Tx enabled queues flag */ 269 256 bitmap_zero(vf->txq_ena, ICE_MAX_BASE_QS_PER_VF); 270 257 bitmap_zero(vf->rxq_ena, ICE_MAX_BASE_QS_PER_VF); 271 - vf->num_qs_ena = 0; 272 258 clear_bit(ICE_VF_STATE_QS_ENA, vf->vf_states); 273 259 } 274 260 ··· 2137 2125 } 2138 2126 2139 2127 set_bit(vf_q_id, vf->rxq_ena); 2140 - vf->num_qs_ena++; 2141 2128 } 2142 2129 2143 2130 vsi = pf->vsi[vf->lan_vsi_idx]; ··· 2152 2141 continue; 2153 2142 2154 2143 set_bit(vf_q_id, vf->txq_ena); 2155 - vf->num_qs_ena++; 2156 2144 } 2157 2145 2158 2146 /* Set flag to indicate that queues are enabled */ ··· 2238 2228 2239 2229 /* Clear enabled queues flag */ 2240 2230 clear_bit(vf_q_id, vf->txq_ena); 2241 - vf->num_qs_ena--; 2242 2231 } 2243 2232 } 2244 2233 2245 - if (vqs->rx_queues) { 2246 - q_map = vqs->rx_queues; 2234 + q_map = vqs->rx_queues; 2235 + /* speed up Rx queue disable by batching them if possible */ 2236 + if (q_map && 2237 + bitmap_equal(&q_map, vf->rxq_ena, ICE_MAX_BASE_QS_PER_VF)) { 2238 + if (ice_vsi_stop_all_rx_rings(vsi)) { 2239 + dev_err(ice_pf_to_dev(vsi->back), "Failed to stop all Rx rings on VSI %d\n", 2240 + vsi->vsi_num); 2241 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2242 + goto error_param; 2243 + } 2247 2244 2245 + bitmap_zero(vf->rxq_ena, ICE_MAX_BASE_QS_PER_VF); 2246 + } else if (q_map) { 2248 2247 for_each_set_bit(vf_q_id, &q_map, ICE_MAX_BASE_QS_PER_VF) { 2249 2248 if (!ice_vc_isvalid_q_id(vf, vqs->vsi_id, vf_q_id)) { 2250 2249 v_ret = VIRTCHNL_STATUS_ERR_PARAM; ··· 2274 2255 2275 2256 /* Clear enabled queues flag */ 2276 2257 clear_bit(vf_q_id, vf->rxq_ena); 2277 - vf->num_qs_ena--; 2278 2258 } 2279 2259 } 2280 2260 2281 2261 /* Clear enabled queues flag */ 2282 - if (v_ret == VIRTCHNL_STATUS_SUCCESS && !vf->num_qs_ena) 2262 + if (v_ret == VIRTCHNL_STATUS_SUCCESS && ice_vf_has_no_qs_ena(vf)) 2283 2263 clear_bit(ICE_VF_STATE_QS_ENA, vf->vf_states); 2284 2264 2285 2265 error_param:
-1
drivers/net/ethernet/intel/ice/ice_virtchnl_pf.h
··· 90 90 u8 num_req_qs; /* num of queue pairs requested by VF */ 91 91 u16 num_mac; 92 92 u16 num_vf_qs; /* num of queue configured per VF */ 93 - u16 num_qs_ena; /* total num of Tx/Rx queue enabled */ 94 93 }; 95 94 96 95 #ifdef CONFIG_PCI_IOV