drivers/net/ethernet/intel/ice/ice_arfs.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/intel/ice/ice_arfs.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/intel/ice/ice_arfs.c
Extension
.c
Size
20125 bytes
Lines
671
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (e->fltr_state == ICE_ARFS_INACTIVE) {
			enum ice_fltr_ptype flow_type = e->fltr_info.flow_type;
			struct ice_arfs_entry_ptr *ep =
				devm_kzalloc(dev, sizeof(*ep), GFP_ATOMIC);

			if (!ep)
				continue;
			INIT_HLIST_NODE(&ep->list_entry);
			/* reference aRFS entry to add HW filter */
			ep->arfs_entry = e;
			hlist_add_head(&ep->list_entry, add_list);
			e->fltr_state = ICE_ARFS_ACTIVE;
			/* expiration timer only used for UDP flows */
			if (flow_type == ICE_FLTR_PTYPE_NONF_IPV4_UDP ||
			    flow_type == ICE_FLTR_PTYPE_NONF_IPV6_UDP)
				e->time_activated = get_jiffies_64();
		} else if (e->fltr_state == ICE_ARFS_ACTIVE) {
			/* check if filter needs to be removed from HW */
			if (ice_arfs_is_flow_expired(vsi, e)) {
				/* remove aRFS entry from hash table for delete
				 * and to prevent referencing it the next time
				 * through this hlist index
				 */
				hlist_del(&e->list_entry);
				e->fltr_state = ICE_ARFS_TODEL;
				/* save reference to aRFS entry for delete */
				hlist_add_head(&e->list_entry, del_list);
			}
		}
}

/**
 * ice_sync_arfs_fltrs - update all aRFS filters
 * @pf: board private structure
 */
void ice_sync_arfs_fltrs(struct ice_pf *pf)
{
	HLIST_HEAD(tmp_del_list);
	HLIST_HEAD(tmp_add_list);
	struct ice_vsi *pf_vsi;
	unsigned int i;

	pf_vsi = ice_get_main_vsi(pf);
	if (!pf_vsi)
		return;

	if (!ice_is_arfs_active(pf_vsi))
		return;

	spin_lock_bh(&pf_vsi->arfs_lock);
	/* Once we process aRFS for the PF VSI get out */
	for (i = 0; i < ICE_MAX_ARFS_LIST; i++)
		ice_arfs_update_flow_rules(pf_vsi, i, &tmp_add_list,
					   &tmp_del_list);
	spin_unlock_bh(&pf_vsi->arfs_lock);

	/* use list of ice_arfs_entry(s) for delete */
	ice_arfs_del_flow_rules(pf_vsi, &tmp_del_list);

	/* use list of ice_arfs_entry_ptr(s) for add */
	ice_arfs_add_flow_rules(pf_vsi, &tmp_add_list);
}

/**
 * ice_arfs_build_entry - builds an aRFS entry based on input
 * @vsi: destination VSI for this flow
 * @fk: flow dissector keys for creating the tuple
 * @rxq_idx: Rx queue to steer this flow to
 * @flow_id: passed down from the stack and saved for flow expiration
 *
 * returns an aRFS entry on success and NULL on failure
 */
static struct ice_arfs_entry *
ice_arfs_build_entry(struct ice_vsi *vsi, const struct flow_keys *fk,
		     u16 rxq_idx, u32 flow_id)
{
	struct ice_arfs_entry *arfs_entry;
	struct ice_fdir_fltr *fltr_info;
	u8 ip_proto;

	arfs_entry = devm_kzalloc(ice_pf_to_dev(vsi->back),
				  sizeof(*arfs_entry),
				  GFP_ATOMIC | __GFP_NOWARN);
	if (!arfs_entry)
		return NULL;

	fltr_info = &arfs_entry->fltr_info;
	fltr_info->q_index = rxq_idx;
	fltr_info->dest_ctl = ICE_FLTR_PRGM_DESC_DEST_DIRECT_PKT_QINDEX;
	fltr_info->dest_vsi = vsi->idx;

Annotation

Implementation Notes