Skip to content

Commit

Permalink
ice: use src VSI instead of src MAC in slow-path
Browse files Browse the repository at this point in the history
The use of a source MAC to direct packets from the VF to the corresponding
port representor is only ok if there is only one MAC on a VF. To support
this functionality when the number of MACs on a VF is greater, it is
necessary to match a source VSI instead of a source MAC.

Let's use the new switch API that allows matching on metadata.

If MAC isn't used in match criteria there is no need to handle adding
rule after virtchnl command. Instead add new rule while port representor
is being configured.

Remove rule_added field, checking for sp_rule can be used instead.
Remove also checking for switchdev running in deleting rule as it can be
called from unroll context when running flag isn't set. Checking for
sp_rule covers both context (with and without running flag).

Rules are added in eswitch configuration flow, so there is no need to
have replay function.

Signed-off-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
Reviewed-by: Piotr Raczynski <piotr.raczynski@intel.com>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
Tested-by: Sujai Buvaneswaran <sujai.buvaneswaran@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
  • Loading branch information
Michal Swiatkowski authored and Tony Nguyen committed May 19, 2023
1 parent 03592a1 commit 0ef4479
Show file tree
Hide file tree
Showing 9 changed files with 40 additions and 102 deletions.
83 changes: 27 additions & 56 deletions drivers/net/ethernet/intel/ice/ice_eswitch.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,15 @@
#include "ice_tc_lib.h"

/**
* ice_eswitch_add_vf_mac_rule - add adv rule with VF's MAC
* ice_eswitch_add_vf_sp_rule - add adv rule with VF's VSI index
* @pf: pointer to PF struct
* @vf: pointer to VF struct
* @mac: VF's MAC address
*
* This function adds advanced rule that forwards packets with
* VF's MAC address (src MAC) to the corresponding switchdev ctrl VSI queue.
* VF's VSI index to the corresponding switchdev ctrl VSI queue.
*/
int
ice_eswitch_add_vf_mac_rule(struct ice_pf *pf, struct ice_vf *vf, const u8 *mac)
static int
ice_eswitch_add_vf_sp_rule(struct ice_pf *pf, struct ice_vf *vf)
{
struct ice_vsi *ctrl_vsi = pf->switchdev.control_vsi;
struct ice_adv_rule_info rule_info = { 0 };
Expand All @@ -32,75 +31,41 @@ ice_eswitch_add_vf_mac_rule(struct ice_pf *pf, struct ice_vf *vf, const u8 *mac)
if (!list)
return -ENOMEM;

list[0].type = ICE_MAC_OFOS;
ether_addr_copy(list[0].h_u.eth_hdr.src_addr, mac);
eth_broadcast_addr(list[0].m_u.eth_hdr.src_addr);
ice_rule_add_src_vsi_metadata(list);

rule_info.sw_act.flag |= ICE_FLTR_TX;
rule_info.sw_act.flag = ICE_FLTR_TX;
rule_info.sw_act.vsi_handle = ctrl_vsi->idx;
rule_info.sw_act.fltr_act = ICE_FWD_TO_Q;
rule_info.sw_act.fwd_id.q_id = hw->func_caps.common_cap.rxq_first_id +
ctrl_vsi->rxq_map[vf->vf_id];
rule_info.flags_info.act |= ICE_SINGLE_ACT_LB_ENABLE;
rule_info.flags_info.act_valid = true;
rule_info.tun_type = ICE_SW_TUN_AND_NON_TUN;
rule_info.src_vsi = vf->lan_vsi_idx;

err = ice_add_adv_rule(hw, list, lkups_cnt, &rule_info,
vf->repr->mac_rule);
&vf->repr->sp_rule);
if (err)
dev_err(ice_pf_to_dev(pf), "Unable to add VF mac rule in switchdev mode for VF %d",
dev_err(ice_pf_to_dev(pf), "Unable to add VF slow-path rule in switchdev mode for VF %d",
vf->vf_id);
else
vf->repr->rule_added = true;

kfree(list);
return err;
}

/**
* ice_eswitch_replay_vf_mac_rule - replay adv rule with VF's MAC
* @vf: pointer to vF struct
*
* This function replays VF's MAC rule after reset.
*/
void ice_eswitch_replay_vf_mac_rule(struct ice_vf *vf)
{
int err;

if (!ice_is_switchdev_running(vf->pf))
return;

if (is_valid_ether_addr(vf->hw_lan_addr)) {
err = ice_eswitch_add_vf_mac_rule(vf->pf, vf,
vf->hw_lan_addr);
if (err) {
dev_err(ice_pf_to_dev(vf->pf), "Failed to add MAC %pM for VF %d\n, error %d\n",
vf->hw_lan_addr, vf->vf_id, err);
return;
}
vf->num_mac++;

ether_addr_copy(vf->dev_lan_addr, vf->hw_lan_addr);
}
}

/**
* ice_eswitch_del_vf_mac_rule - delete adv rule with VF's MAC
* ice_eswitch_del_vf_sp_rule - delete adv rule with VF's VSI index
* @vf: pointer to the VF struct
*
* Delete the advanced rule that was used to forward packets with the VF's MAC
* address (src MAC) to the corresponding switchdev ctrl VSI queue.
* Delete the advanced rule that was used to forward packets with the VF's VSI
* index to the corresponding switchdev ctrl VSI queue.
*/
void ice_eswitch_del_vf_mac_rule(struct ice_vf *vf)
static void ice_eswitch_del_vf_sp_rule(struct ice_vf *vf)
{
if (!ice_is_switchdev_running(vf->pf))
return;

if (!vf->repr->rule_added)
if (!vf->repr)
return;

ice_rem_adv_rule_by_id(&vf->pf->hw, vf->repr->mac_rule);
vf->repr->rule_added = false;
ice_rem_adv_rule_by_id(&vf->pf->hw, &vf->repr->sp_rule);
}

/**
Expand Down Expand Up @@ -236,6 +201,7 @@ ice_eswitch_release_reprs(struct ice_pf *pf, struct ice_vsi *ctrl_vsi)
ice_vsi_update_security(vsi, ice_vsi_ctx_set_antispoof);
metadata_dst_free(vf->repr->dst);
vf->repr->dst = NULL;
ice_eswitch_del_vf_sp_rule(vf);
ice_fltr_add_mac_and_broadcast(vsi, vf->hw_lan_addr,
ICE_FWD_TO_VSI);

Expand Down Expand Up @@ -263,25 +229,30 @@ static int ice_eswitch_setup_reprs(struct ice_pf *pf)
vf->repr->dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX,
GFP_KERNEL);
if (!vf->repr->dst) {
ice_fltr_add_mac_and_broadcast(vsi,
vf->hw_lan_addr,
ice_fltr_add_mac_and_broadcast(vsi, vf->hw_lan_addr,
ICE_FWD_TO_VSI);
goto err;
}

if (ice_eswitch_add_vf_sp_rule(pf, vf)) {
ice_fltr_add_mac_and_broadcast(vsi, vf->hw_lan_addr,
ICE_FWD_TO_VSI);
goto err;
}

if (ice_vsi_update_security(vsi, ice_vsi_ctx_clear_antispoof)) {
ice_fltr_add_mac_and_broadcast(vsi,
vf->hw_lan_addr,
ice_fltr_add_mac_and_broadcast(vsi, vf->hw_lan_addr,
ICE_FWD_TO_VSI);
ice_eswitch_del_vf_sp_rule(vf);
metadata_dst_free(vf->repr->dst);
vf->repr->dst = NULL;
goto err;
}

if (ice_vsi_add_vlan_zero(vsi)) {
ice_fltr_add_mac_and_broadcast(vsi,
vf->hw_lan_addr,
ice_fltr_add_mac_and_broadcast(vsi, vf->hw_lan_addr,
ICE_FWD_TO_VSI);
ice_eswitch_del_vf_sp_rule(vf);
metadata_dst_free(vf->repr->dst);
vf->repr->dst = NULL;
ice_vsi_update_security(vsi, ice_vsi_ctx_set_antispoof);
Expand Down
14 changes: 0 additions & 14 deletions drivers/net/ethernet/intel/ice/ice_eswitch.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,6 @@ bool ice_is_eswitch_mode_switchdev(struct ice_pf *pf);
void ice_eswitch_update_repr(struct ice_vsi *vsi);

void ice_eswitch_stop_all_tx_queues(struct ice_pf *pf);
int
ice_eswitch_add_vf_mac_rule(struct ice_pf *pf, struct ice_vf *vf,
const u8 *mac);
void ice_eswitch_replay_vf_mac_rule(struct ice_vf *vf);
void ice_eswitch_del_vf_mac_rule(struct ice_vf *vf);

void ice_eswitch_set_target_vsi(struct sk_buff *skb,
struct ice_tx_offload_params *off);
Expand All @@ -34,15 +29,6 @@ ice_eswitch_port_start_xmit(struct sk_buff *skb, struct net_device *netdev);
static inline void ice_eswitch_release(struct ice_pf *pf) { }

static inline void ice_eswitch_stop_all_tx_queues(struct ice_pf *pf) { }
static inline void ice_eswitch_replay_vf_mac_rule(struct ice_vf *vf) { }
static inline void ice_eswitch_del_vf_mac_rule(struct ice_vf *vf) { }

static inline int
ice_eswitch_add_vf_mac_rule(struct ice_pf *pf, struct ice_vf *vf,
const u8 *mac)
{
return -EOPNOTSUPP;
}

static inline void
ice_eswitch_set_target_vsi(struct sk_buff *skb,
Expand Down
5 changes: 4 additions & 1 deletion drivers/net/ethernet/intel/ice/ice_protocol_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,10 @@ struct ice_nvgre_hdr {
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* Source VSI = Source VSI of packet loopbacked in switch (for egress) (10b).
*
*/
#define ICE_MDID_SOURCE_VSI_MASK GENMASK(9, 0)

/*
* MDID 20
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |A|B|C|D|E|F|R|R|G|H|I|J|K|L|M|N|
Expand Down
17 changes: 0 additions & 17 deletions drivers/net/ethernet/intel/ice/ice_repr.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,14 +298,6 @@ static int ice_repr_add(struct ice_vf *vf)
if (!repr)
return -ENOMEM;

#ifdef CONFIG_ICE_SWITCHDEV
repr->mac_rule = kzalloc(sizeof(*repr->mac_rule), GFP_KERNEL);
if (!repr->mac_rule) {
err = -ENOMEM;
goto err_alloc_rule;
}
#endif

repr->netdev = alloc_etherdev(sizeof(struct ice_netdev_priv));
if (!repr->netdev) {
err = -ENOMEM;
Expand Down Expand Up @@ -351,11 +343,6 @@ static int ice_repr_add(struct ice_vf *vf)
free_netdev(repr->netdev);
repr->netdev = NULL;
err_alloc:
#ifdef CONFIG_ICE_SWITCHDEV
kfree(repr->mac_rule);
repr->mac_rule = NULL;
err_alloc_rule:
#endif
kfree(repr);
vf->repr = NULL;
return err;
Expand All @@ -376,10 +363,6 @@ static void ice_repr_rem(struct ice_vf *vf)
ice_devlink_destroy_vf_port(vf);
free_netdev(vf->repr->netdev);
vf->repr->netdev = NULL;
#ifdef CONFIG_ICE_SWITCHDEV
kfree(vf->repr->mac_rule);
vf->repr->mac_rule = NULL;
#endif
kfree(vf->repr);
vf->repr = NULL;

Expand Down
5 changes: 2 additions & 3 deletions drivers/net/ethernet/intel/ice/ice_repr.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ struct ice_repr {
struct net_device *netdev;
struct metadata_dst *dst;
#ifdef CONFIG_ICE_SWITCHDEV
/* info about slow path MAC rule */
struct ice_rule_query_data *mac_rule;
u8 rule_added;
/* info about slow path rule */
struct ice_rule_query_data sp_rule;
#endif
};

Expand Down
6 changes: 6 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_switch.c
Original file line number Diff line number Diff line change
Expand Up @@ -6012,6 +6012,12 @@ void ice_rule_add_vlan_metadata(struct ice_adv_lkup_elem *lkup)
cpu_to_be16(ICE_PKT_VLAN_MASK);
}

void ice_rule_add_src_vsi_metadata(struct ice_adv_lkup_elem *lkup)
{
lkup->type = ICE_HW_METADATA;
lkup->m_u.metadata.source_vsi = cpu_to_be16(ICE_MDID_SOURCE_VSI_MASK);
}

/**
* ice_add_adv_rule - helper function to create an advanced switch rule
* @hw: pointer to the hardware structure
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/ice/ice_switch.h
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ ice_free_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
/* Switch/bridge related commands */
void ice_rule_add_tunnel_metadata(struct ice_adv_lkup_elem *lkup);
void ice_rule_add_vlan_metadata(struct ice_adv_lkup_elem *lkup);
void ice_rule_add_src_vsi_metadata(struct ice_adv_lkup_elem *lkup);
int
ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
u16 lkups_cnt, struct ice_adv_rule_info *rinfo,
Expand Down
3 changes: 0 additions & 3 deletions drivers/net/ethernet/intel/ice/ice_vf_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -689,8 +689,6 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags)
*/
ice_vf_clear_all_promisc_modes(vf, vsi);

ice_eswitch_del_vf_mac_rule(vf);

ice_vf_fdir_exit(vf);
ice_vf_fdir_init(vf);
/* clean VF control VSI when resetting VF since it should be setup
Expand All @@ -716,7 +714,6 @@ int ice_reset_vf(struct ice_vf *vf, u32 flags)
}

ice_eswitch_update_repr(vsi);
ice_eswitch_replay_vf_mac_rule(vf);

/* if the VF has been reset allow it to come up again */
ice_mbx_clear_malvf(&vf->mbx_info);
Expand Down
8 changes: 0 additions & 8 deletions drivers/net/ethernet/intel/ice/ice_virtchnl.c
Original file line number Diff line number Diff line change
Expand Up @@ -3730,7 +3730,6 @@ static int ice_vc_repr_add_mac(struct ice_vf *vf, u8 *msg)

for (i = 0; i < al->num_elements; i++) {
u8 *mac_addr = al->list[i].addr;
int result;

if (!is_unicast_ether_addr(mac_addr) ||
ether_addr_equal(mac_addr, vf->hw_lan_addr))
Expand All @@ -3742,13 +3741,6 @@ static int ice_vc_repr_add_mac(struct ice_vf *vf, u8 *msg)
goto handle_mac_exit;
}

result = ice_eswitch_add_vf_mac_rule(pf, vf, mac_addr);
if (result) {
dev_err(ice_pf_to_dev(pf), "Failed to add MAC %pM for VF %d\n, error %d\n",
mac_addr, vf->vf_id, result);
goto handle_mac_exit;
}

ice_vfhw_mac_add(vf, &al->list[i]);
vf->num_mac++;
break;
Expand Down

0 comments on commit 0ef4479

Please sign in to comment.