Skip to content

Commit

Permalink
Merge branch 'mlx5-SRIOV-offload-tunnel_key-set-release'
Browse files Browse the repository at this point in the history
Saeed Mahameed says:

====================
Mellanox 100G SRIOV offloads tunnel_key set/release

From Hadar Hen Zion:

This series further enhances the SRIOV TC offloads of mlx5 to handle the
TC tunnel_key release and set actions.

This serves a common use-case in virtualization systems where the virtual
switch encapsulate packets (tunnel_key set action) sent from VMs with
outer headers corresponding to the local/remote host IPs and de-capsulate
(tunnel_key release) outer headers before the packets are received by the
VM.

We use the new E-Switch switchdev mode and TC tunnel_key set/release
action to achieve that also in SW defined SRIOV environments by
offloading TC rules that contain these actions along with forwarding
(TC mirred/redirect action) the packets.

The first six patches are adding the needed support in flow dissector,
flower and tc for offloading tunnel_key actions:
    - The first three patches are adding the needed help functions
      and enums
    - The next three patches in the series are adding UDP port attribute
      to tunnel_key release and set actions.

The addition of UDP ports would allow the HW driver to make sure they are
given (say) a VXLAN tunnel to offload (mlx5e uses that).

Patches 7-10 are mlx5 preparations for tunnel_key actions offloads support.

Patch #11 adds mlx5e support to offload tunnel_key release action, and the
last two patches (#12-13) add mlx5e support to tc tunnel_key set action.

Currently in order to offload tc tunnel_key release action, the tc rule
should be placed on top of the mlx5e offloading (uplink) interface instead
of the shared tunnel interface. The resolution between the tunnel interface
to the HW netdevice will be implemented in a follow up series.

This series was generated against commit
94edc86 ("Merge branch 'dwmac-sti-refactor-cleanup'")
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Nov 9, 2016
2 parents 35b8073 + a54e20b commit 04b206b
Show file tree
Hide file tree
Showing 24 changed files with 764 additions and 148 deletions.
12 changes: 6 additions & 6 deletions drivers/infiniband/hw/mlx5/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1857,7 +1857,7 @@ static struct mlx5_ib_flow_prio *get_flow_table(struct mlx5_ib_dev *dev,
ft = mlx5_create_auto_grouped_flow_table(ns, priority,
num_entries,
num_groups,
0);
0, 0);

if (!IS_ERR(ft)) {
prio->refcount = 0;
Expand All @@ -1877,10 +1877,10 @@ static struct mlx5_ib_flow_handler *create_flow_rule(struct mlx5_ib_dev *dev,
{
struct mlx5_flow_table *ft = ft_prio->flow_table;
struct mlx5_ib_flow_handler *handler;
struct mlx5_flow_act flow_act = {0};
struct mlx5_flow_spec *spec;
const void *ib_flow = (const void *)flow_attr + sizeof(*flow_attr);
unsigned int spec_index;
u32 action;
int err = 0;

if (!is_valid_attr(flow_attr))
Expand All @@ -1905,12 +1905,12 @@ static struct mlx5_ib_flow_handler *create_flow_rule(struct mlx5_ib_dev *dev,
}

spec->match_criteria_enable = get_match_criteria_enable(spec->match_criteria);
action = dst ? MLX5_FLOW_CONTEXT_ACTION_FWD_DEST :
flow_act.action = dst ? MLX5_FLOW_CONTEXT_ACTION_FWD_DEST :
MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO;
flow_act.flow_tag = MLX5_FS_DEFAULT_FLOW_TAG;
handler->rule = mlx5_add_flow_rules(ft, spec,
action,
MLX5_FS_DEFAULT_FLOW_TAG,
dst, 1);
&flow_act,
dst, 1);

if (IS_ERR(handler->rule)) {
err = PTR_ERR(handler->rule);
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en.h
Original file line number Diff line number Diff line change
Expand Up @@ -893,5 +893,9 @@ void mlx5e_detach_netdev(struct mlx5_core_dev *mdev, struct net_device *netdev);
struct rtnl_link_stats64 *
mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats);
u32 mlx5e_choose_lro_timeout(struct mlx5_core_dev *mdev, u32 wanted_timeout);
void mlx5e_add_vxlan_port(struct net_device *netdev,
struct udp_tunnel_info *ti);
void mlx5e_del_vxlan_port(struct net_device *netdev,
struct udp_tunnel_info *ti);

#endif /* __MLX5_EN_H__ */
19 changes: 13 additions & 6 deletions drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,11 @@ static int arfs_add_default_rule(struct mlx5e_priv *priv,
enum arfs_type type)
{
struct arfs_table *arfs_t = &priv->fs.arfs.arfs_tables[type];
struct mlx5_flow_act flow_act = {
.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST,
.flow_tag = MLX5_FS_DEFAULT_FLOW_TAG,
.encap_id = 0,
};
struct mlx5_flow_destination dest;
struct mlx5e_tir *tir = priv->indir_tir;
struct mlx5_flow_spec *spec;
Expand Down Expand Up @@ -206,8 +211,7 @@ static int arfs_add_default_rule(struct mlx5e_priv *priv,
}

arfs_t->default_rule = mlx5_add_flow_rules(arfs_t->ft.t, spec,
MLX5_FLOW_CONTEXT_ACTION_FWD_DEST,
MLX5_FS_DEFAULT_FLOW_TAG,
&flow_act,
&dest, 1);
if (IS_ERR(arfs_t->default_rule)) {
err = PTR_ERR(arfs_t->default_rule);
Expand Down Expand Up @@ -324,7 +328,7 @@ static int arfs_create_table(struct mlx5e_priv *priv,
int err;

ft->t = mlx5_create_flow_table(priv->fs.ns, MLX5E_NIC_PRIO,
MLX5E_ARFS_TABLE_SIZE, MLX5E_ARFS_FT_LEVEL);
MLX5E_ARFS_TABLE_SIZE, MLX5E_ARFS_FT_LEVEL, 0);
if (IS_ERR(ft->t)) {
err = PTR_ERR(ft->t);
ft->t = NULL;
Expand Down Expand Up @@ -465,6 +469,11 @@ static struct arfs_table *arfs_get_table(struct mlx5e_arfs_tables *arfs,
static struct mlx5_flow_handle *arfs_add_rule(struct mlx5e_priv *priv,
struct arfs_rule *arfs_rule)
{
struct mlx5_flow_act flow_act = {
.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST,
.flow_tag = MLX5_FS_DEFAULT_FLOW_TAG,
.encap_id = 0,
};
struct mlx5e_arfs_tables *arfs = &priv->fs.arfs;
struct arfs_tuple *tuple = &arfs_rule->tuple;
struct mlx5_flow_handle *rule = NULL;
Expand Down Expand Up @@ -544,9 +553,7 @@ static struct mlx5_flow_handle *arfs_add_rule(struct mlx5e_priv *priv,
}
dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR;
dest.tir_num = priv->direct_tir[arfs_rule->rxq].tirn;
rule = mlx5_add_flow_rules(ft, spec, MLX5_FLOW_CONTEXT_ACTION_FWD_DEST,
MLX5_FS_DEFAULT_FLOW_TAG,
&dest, 1);
rule = mlx5_add_flow_rules(ft, spec, &flow_act, &dest, 1);
if (IS_ERR(rule)) {
err = PTR_ERR(rule);
netdev_err(priv->netdev, "%s: add rule(filter id=%d, rq idx=%d) failed, err=%d\n",
Expand Down
35 changes: 21 additions & 14 deletions drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,11 @@ static int __mlx5e_add_vlan_rule(struct mlx5e_priv *priv,
enum mlx5e_vlan_rule_type rule_type,
u16 vid, struct mlx5_flow_spec *spec)
{
struct mlx5_flow_act flow_act = {
.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST,
.flow_tag = MLX5_FS_DEFAULT_FLOW_TAG,
.encap_id = 0,
};
struct mlx5_flow_table *ft = priv->fs.vlan.ft.t;
struct mlx5_flow_destination dest;
struct mlx5_flow_handle **rule_p;
Expand Down Expand Up @@ -187,10 +192,7 @@ static int __mlx5e_add_vlan_rule(struct mlx5e_priv *priv,
break;
}

*rule_p = mlx5_add_flow_rules(ft, spec,
MLX5_FLOW_CONTEXT_ACTION_FWD_DEST,
MLX5_FS_DEFAULT_FLOW_TAG,
&dest, 1);
*rule_p = mlx5_add_flow_rules(ft, spec, &flow_act, &dest, 1);

if (IS_ERR(*rule_p)) {
err = PTR_ERR(*rule_p);
Expand Down Expand Up @@ -623,6 +625,11 @@ mlx5e_generate_ttc_rule(struct mlx5e_priv *priv,
u16 etype,
u8 proto)
{
struct mlx5_flow_act flow_act = {
.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST,
.flow_tag = MLX5_FS_DEFAULT_FLOW_TAG,
.encap_id = 0,
};
struct mlx5_flow_handle *rule;
struct mlx5_flow_spec *spec;
int err = 0;
Expand All @@ -644,10 +651,7 @@ mlx5e_generate_ttc_rule(struct mlx5e_priv *priv,
MLX5_SET(fte_match_param, spec->match_value, outer_headers.ethertype, etype);
}

rule = mlx5_add_flow_rules(ft, spec,
MLX5_FLOW_CONTEXT_ACTION_FWD_DEST,
MLX5_FS_DEFAULT_FLOW_TAG,
dest, 1);
rule = mlx5_add_flow_rules(ft, spec, &flow_act, dest, 1);
if (IS_ERR(rule)) {
err = PTR_ERR(rule);
netdev_err(priv->netdev, "%s: add rule failed\n", __func__);
Expand Down Expand Up @@ -777,7 +781,7 @@ static int mlx5e_create_ttc_table(struct mlx5e_priv *priv)
int err;

ft->t = mlx5_create_flow_table(priv->fs.ns, MLX5E_NIC_PRIO,
MLX5E_TTC_TABLE_SIZE, MLX5E_TTC_FT_LEVEL);
MLX5E_TTC_TABLE_SIZE, MLX5E_TTC_FT_LEVEL, 0);
if (IS_ERR(ft->t)) {
err = PTR_ERR(ft->t);
ft->t = NULL;
Expand Down Expand Up @@ -810,6 +814,11 @@ static void mlx5e_del_l2_flow_rule(struct mlx5e_priv *priv,
static int mlx5e_add_l2_flow_rule(struct mlx5e_priv *priv,
struct mlx5e_l2_rule *ai, int type)
{
struct mlx5_flow_act flow_act = {
.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST,
.flow_tag = MLX5_FS_DEFAULT_FLOW_TAG,
.encap_id = 0,
};
struct mlx5_flow_table *ft = priv->fs.l2.ft.t;
struct mlx5_flow_destination dest;
struct mlx5_flow_spec *spec;
Expand Down Expand Up @@ -848,9 +857,7 @@ static int mlx5e_add_l2_flow_rule(struct mlx5e_priv *priv,
break;
}

ai->rule = mlx5_add_flow_rules(ft, spec,
MLX5_FLOW_CONTEXT_ACTION_FWD_DEST,
MLX5_FS_DEFAULT_FLOW_TAG, &dest, 1);
ai->rule = mlx5_add_flow_rules(ft, spec, &flow_act, &dest, 1);
if (IS_ERR(ai->rule)) {
netdev_err(priv->netdev, "%s: add l2 rule(mac:%pM) failed\n",
__func__, mv_dmac);
Expand Down Expand Up @@ -948,7 +955,7 @@ static int mlx5e_create_l2_table(struct mlx5e_priv *priv)

ft->num_groups = 0;
ft->t = mlx5_create_flow_table(priv->fs.ns, MLX5E_NIC_PRIO,
MLX5E_L2_TABLE_SIZE, MLX5E_L2_FT_LEVEL);
MLX5E_L2_TABLE_SIZE, MLX5E_L2_FT_LEVEL, 0);

if (IS_ERR(ft->t)) {
err = PTR_ERR(ft->t);
Expand Down Expand Up @@ -1038,7 +1045,7 @@ static int mlx5e_create_vlan_table(struct mlx5e_priv *priv)

ft->num_groups = 0;
ft->t = mlx5_create_flow_table(priv->fs.ns, MLX5E_NIC_PRIO,
MLX5E_VLAN_TABLE_SIZE, MLX5E_VLAN_FT_LEVEL);
MLX5E_VLAN_TABLE_SIZE, MLX5E_VLAN_FT_LEVEL, 0);

if (IS_ERR(ft->t)) {
err = PTR_ERR(ft->t);
Expand Down
12 changes: 6 additions & 6 deletions drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ static struct mlx5e_ethtool_table *get_flow_table(struct mlx5e_priv *priv,
MLX5E_ETHTOOL_NUM_ENTRIES);
ft = mlx5_create_auto_grouped_flow_table(ns, prio,
table_size,
MLX5E_ETHTOOL_NUM_GROUPS, 0);
MLX5E_ETHTOOL_NUM_GROUPS, 0, 0);
if (IS_ERR(ft))
return (void *)ft;

Expand Down Expand Up @@ -290,10 +290,10 @@ add_ethtool_flow_rule(struct mlx5e_priv *priv,
struct ethtool_rx_flow_spec *fs)
{
struct mlx5_flow_destination *dst = NULL;
struct mlx5_flow_act flow_act = {0};
struct mlx5_flow_spec *spec;
struct mlx5_flow_handle *rule;
int err = 0;
u32 action;

spec = mlx5_vzalloc(sizeof(*spec));
if (!spec)
Expand All @@ -304,7 +304,7 @@ add_ethtool_flow_rule(struct mlx5e_priv *priv,
goto free;

if (fs->ring_cookie == RX_CLS_FLOW_DISC) {
action = MLX5_FLOW_CONTEXT_ACTION_DROP;
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP;
} else {
dst = kzalloc(sizeof(*dst), GFP_KERNEL);
if (!dst) {
Expand All @@ -314,12 +314,12 @@ add_ethtool_flow_rule(struct mlx5e_priv *priv,

dst->type = MLX5_FLOW_DESTINATION_TYPE_TIR;
dst->tir_num = priv->direct_tir[fs->ring_cookie].tirn;
action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
}

spec->match_criteria_enable = (!outer_header_zero(spec->match_criteria));
rule = mlx5_add_flow_rules(ft, spec, action,
MLX5_FS_DEFAULT_FLOW_TAG, dst, 1);
flow_act.flow_tag = MLX5_FS_DEFAULT_FLOW_TAG;
rule = mlx5_add_flow_rules(ft, spec, &flow_act, dst, 1);
if (IS_ERR(rule)) {
err = PTR_ERR(rule);
netdev_err(priv->netdev, "%s: failed to add ethtool steering rule: %d\n",
Expand Down
8 changes: 4 additions & 4 deletions drivers/net/ethernet/mellanox/mlx5/core/en_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2995,8 +2995,8 @@ static int mlx5e_get_vf_stats(struct net_device *dev,
vf_stats);
}

static void mlx5e_add_vxlan_port(struct net_device *netdev,
struct udp_tunnel_info *ti)
void mlx5e_add_vxlan_port(struct net_device *netdev,
struct udp_tunnel_info *ti)
{
struct mlx5e_priv *priv = netdev_priv(netdev);

Expand All @@ -3009,8 +3009,8 @@ static void mlx5e_add_vxlan_port(struct net_device *netdev,
mlx5e_vxlan_queue_work(priv, ti->sa_family, be16_to_cpu(ti->port), 1);
}

static void mlx5e_del_vxlan_port(struct net_device *netdev,
struct udp_tunnel_info *ti)
void mlx5e_del_vxlan_port(struct net_device *netdev,
struct udp_tunnel_info *ti)
{
struct mlx5e_priv *priv = netdev_priv(netdev);

Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,8 @@ static const struct net_device_ops mlx5e_netdev_ops_rep = {
.ndo_get_phys_port_name = mlx5e_rep_get_phys_port_name,
.ndo_setup_tc = mlx5e_rep_ndo_setup_tc,
.ndo_get_stats64 = mlx5e_get_stats,
.ndo_udp_tunnel_add = mlx5e_add_vxlan_port,
.ndo_udp_tunnel_del = mlx5e_del_vxlan_port,
};

static void mlx5e_build_rep_netdev_priv(struct mlx5_core_dev *mdev,
Expand Down
Loading

0 comments on commit 04b206b

Please sign in to comment.