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

ice: Support RSS configure removal for AVF

Add the handler for virtchnl message VIRTCHNL_OP_DEL_RSS_CFG to remove
an existing RSS configuration with matching hashed fields.

Signed-off-by: Vignesh Sridhar <vignesh.sridhar@intel.com>
Co-developed-by: Jia Guo <jia.guo@intel.com>
Signed-off-by: Jia Guo <jia.guo@intel.com>
Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
Tested-by: Bo Chen <BoX.C.Chen@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>

authored by

Qi Zhang and committed by
Tony Nguyen
ddd1f3cf 222a8ab0

+105 -2
+88
drivers/net/ethernet/intel/ice/ice_flow.c
··· 2149 2149 return status; 2150 2150 } 2151 2151 2152 + /** 2153 + * ice_rem_rss_cfg_sync - remove an existing RSS configuration 2154 + * @hw: pointer to the hardware structure 2155 + * @vsi_handle: software VSI handle 2156 + * @hashed_flds: Packet hash types (ICE_FLOW_HASH_*) to remove 2157 + * @addl_hdrs: Protocol header fields within a packet segment 2158 + * @segs_cnt: packet segment count 2159 + * 2160 + * Assumption: lock has already been acquired for RSS list 2161 + */ 2162 + static enum ice_status 2163 + ice_rem_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds, 2164 + u32 addl_hdrs, u8 segs_cnt) 2165 + { 2166 + const enum ice_block blk = ICE_BLK_RSS; 2167 + struct ice_flow_seg_info *segs; 2168 + struct ice_flow_prof *prof; 2169 + enum ice_status status; 2170 + 2171 + segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL); 2172 + if (!segs) 2173 + return ICE_ERR_NO_MEMORY; 2174 + 2175 + /* Construct the packet segment info from the hashed fields */ 2176 + status = ice_flow_set_rss_seg_info(&segs[segs_cnt - 1], hashed_flds, 2177 + addl_hdrs); 2178 + if (status) 2179 + goto out; 2180 + 2181 + prof = ice_flow_find_prof_conds(hw, blk, ICE_FLOW_RX, segs, segs_cnt, 2182 + vsi_handle, 2183 + ICE_FLOW_FIND_PROF_CHK_FLDS); 2184 + if (!prof) { 2185 + status = ICE_ERR_DOES_NOT_EXIST; 2186 + goto out; 2187 + } 2188 + 2189 + status = ice_flow_disassoc_prof(hw, blk, prof, vsi_handle); 2190 + if (status) 2191 + goto out; 2192 + 2193 + /* Remove RSS configuration from VSI context before deleting 2194 + * the flow profile. 2195 + */ 2196 + ice_rem_rss_list(hw, vsi_handle, prof); 2197 + 2198 + if (bitmap_empty(prof->vsis, ICE_MAX_VSI)) 2199 + status = ice_flow_rem_prof(hw, blk, prof->id); 2200 + 2201 + out: 2202 + kfree(segs); 2203 + return status; 2204 + } 2205 + 2206 + /** 2207 + * ice_rem_rss_cfg - remove an existing RSS config with matching hashed fields 2208 + * @hw: pointer to the hardware structure 2209 + * @vsi_handle: software VSI handle 2210 + * @hashed_flds: Packet hash types (ICE_FLOW_HASH_*) to remove 2211 + * @addl_hdrs: Protocol header fields within a packet segment 2212 + * 2213 + * This function will lookup the flow profile based on the input 2214 + * hash field bitmap, iterate through the profile entry list of 2215 + * that profile and find entry associated with input VSI to be 2216 + * removed. Calls are made to underlying flow s which will APIs 2217 + * turn build or update buffers for RSS XLT1 section. 2218 + */ 2219 + enum ice_status __maybe_unused 2220 + ice_rem_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds, 2221 + u32 addl_hdrs) 2222 + { 2223 + enum ice_status status; 2224 + 2225 + if (hashed_flds == ICE_HASH_INVALID || 2226 + !ice_is_vsi_valid(hw, vsi_handle)) 2227 + return ICE_ERR_PARAM; 2228 + 2229 + mutex_lock(&hw->rss_locks); 2230 + status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds, addl_hdrs, 2231 + ICE_RSS_OUTER_HEADERS); 2232 + if (!status) 2233 + status = ice_rem_rss_cfg_sync(hw, vsi_handle, hashed_flds, 2234 + addl_hdrs, ICE_RSS_INNER_HEADERS); 2235 + mutex_unlock(&hw->rss_locks); 2236 + 2237 + return status; 2238 + } 2239 + 2152 2240 /* Mapping of AVF hash bit fields to an L3-L4 hash combination. 2153 2241 * As the ice_flow_avf_hdr_field represent individual bit shifts in a hash, 2154 2242 * convert its values to their appropriate flow L3, L4 values.
+3
drivers/net/ethernet/intel/ice/ice_flow.h
··· 409 409 enum ice_status 410 410 ice_add_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds, 411 411 u32 addl_hdrs); 412 + enum ice_status 413 + ice_rem_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u64 hashed_flds, 414 + u32 addl_hdrs); 412 415 u64 ice_get_rss_cfg(struct ice_hw *hw, u16 vsi_handle, u32 hdrs); 413 416 #endif /* _ICE_FLOW_H_ */
+14 -2
drivers/net/ethernet/intel/ice/ice_virtchnl_pf.c
··· 2672 2672 vsi->vsi_num, v_ret); 2673 2673 } 2674 2674 } else { 2675 - v_ret = VIRTCHNL_STATUS_ERR_NOT_SUPPORTED; 2676 - dev_err(dev, "RSS removal not supported\n"); 2675 + enum ice_status status; 2676 + 2677 + status = ice_rem_rss_cfg(hw, vsi->idx, hash_flds, 2678 + addl_hdrs); 2679 + /* We just ignore ICE_ERR_DOES_NOT_EXIST, because 2680 + * if two configurations share the same profile remove 2681 + * one of them actually removes both, since the 2682 + * profile is deleted. 2683 + */ 2684 + if (status && status != ICE_ERR_DOES_NOT_EXIST) { 2685 + v_ret = VIRTCHNL_STATUS_ERR_PARAM; 2686 + dev_err(dev, "ice_rem_rss_cfg failed for VF ID:%d, error:%s\n", 2687 + vf->vf_id, ice_stat_str(status)); 2688 + } 2677 2689 } 2678 2690 } 2679 2691