Commit 95ae2d1d authored by David S. Miller's avatar David S. Miller
Browse files


Saeed Mahameed says:

====================
Mellanox, mlx5 E-Switch chains and prios

This series has two parts,

1) A merge commit with mlx5-next branch that include updates for mlx5
HW layouts needed for this and upcoming submissions.

2) From Paul, Increase the number of chains and prios

Currently the Mellanox driver supports offloading tc rules that
are defined on the first 4 chains and the first 16 priorities.
The restriction stems from the firmware flow level enforcement
requiring a flow table of a certain level to point to a flow
table of a higher level. This limitation may be ignored by setting
the ignore_flow_level bit when creating flow table entries.
Use unmanaged tables and ignore flow level to create more tables than
declared by fs_core steering. Manually manage the connections between the
tables themselves.

HW table is instantiated for every tc <chain,prio> tuple. The miss rule
of every table either jumps to the next <chain,prio> table, or continues
to slow_fdb. This logic is realized by following this sequence:

1. Create an auto-grouped flow table for the specified priority with
    reserved entries

Reserved entries are allocated at the end of the flow table.
Flow groups are evaluated in sequence and therefore it is guaranteed
that the flow group defined on the last FTEs will be the last to evaluate.

Define a "match all" flow group on the reserved entries, providing
the platform to add table miss actions.

2. Set the miss rule action to jump to the next <chain,prio> table
    or the slow_fdb.

3. Link the previous priority table to point to the new table by
    updating its miss rule.

Please pull and let me know if there's any problem.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 0c58ac1e 278d51f2
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -3276,12 +3276,14 @@ static struct mlx5_ib_flow_prio *_get_prio(struct mlx5_flow_namespace *ns,
					   int num_entries, int num_groups,
					   u32 flags)
{
	struct mlx5_flow_table_attr ft_attr = {};
	struct mlx5_flow_table *ft;

	ft = mlx5_create_auto_grouped_flow_table(ns, priority,
						 num_entries,
						 num_groups,
						 0, flags);
	ft_attr.prio = priority;
	ft_attr.max_fte = num_entries;
	ft_attr.flags = flags;
	ft_attr.autogroup.max_num_groups = num_groups;
	ft = mlx5_create_auto_grouped_flow_table(ns, &ft_attr);
	if (IS_ERR(ft))
		return ERR_CAST(ft);

+1 −1
Original line number Diff line number Diff line
@@ -42,7 +42,7 @@ mlx5_core-$(CONFIG_PCI_HYPERV_INTERFACE) += en/hv_vhca_stats.o
# Core extra
#
mlx5_core-$(CONFIG_MLX5_ESWITCH)   += eswitch.o eswitch_offloads.o eswitch_offloads_termtbl.o \
				      ecpf.o rdma.o
				      ecpf.o rdma.o eswitch_offloads_chains.o
mlx5_core-$(CONFIG_MLX5_MPFS)      += lib/mpfs.o
mlx5_core-$(CONFIG_VXLAN)          += lib/vxlan.o
mlx5_core-$(CONFIG_PTP_1588_CLOCK) += lib/clock.o
+6 −3
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ static struct mlx5e_ethtool_table *get_flow_table(struct mlx5e_priv *priv,
						  struct ethtool_rx_flow_spec *fs,
						  int num_tuples)
{
	struct mlx5_flow_table_attr ft_attr = {};
	struct mlx5e_ethtool_table *eth_ft;
	struct mlx5_flow_namespace *ns;
	struct mlx5_flow_table *ft;
@@ -102,9 +103,11 @@ static struct mlx5e_ethtool_table *get_flow_table(struct mlx5e_priv *priv,
	table_size = min_t(u32, BIT(MLX5_CAP_FLOWTABLE(priv->mdev,
						       flow_table_properties_nic_receive.log_max_ft_size)),
			   MLX5E_ETHTOOL_NUM_ENTRIES);
	ft = mlx5_create_auto_grouped_flow_table(ns, prio,
						 table_size,
						 MLX5E_ETHTOOL_NUM_GROUPS, 0, 0);

	ft_attr.prio = prio;
	ft_attr.max_fte = table_size;
	ft_attr.autogroup.max_num_groups = MLX5E_ETHTOOL_NUM_GROUPS;
	ft = mlx5_create_auto_grouped_flow_table(ns, &ft_attr);
	if (IS_ERR(ft))
		return (void *)ft;

+21 −7
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@
#include <net/ipv6_stubs.h>

#include "eswitch.h"
#include "eswitch_offloads_chains.h"
#include "en.h"
#include "en_rep.h"
#include "en_tc.h"
@@ -1247,8 +1248,7 @@ static int mlx5e_rep_setup_tc_cb(enum tc_setup_type type, void *type_data,
static int mlx5e_rep_setup_ft_cb(enum tc_setup_type type, void *type_data,
				 void *cb_priv)
{
	struct flow_cls_offload *f = type_data;
	struct flow_cls_offload cls_flower;
	struct flow_cls_offload tmp, *f = type_data;
	struct mlx5e_priv *priv = cb_priv;
	struct mlx5_eswitch *esw;
	unsigned long flags;
@@ -1261,16 +1261,30 @@ static int mlx5e_rep_setup_ft_cb(enum tc_setup_type type, void *type_data,

	switch (type) {
	case TC_SETUP_CLSFLOWER:
		if (!mlx5_eswitch_prios_supported(esw) || f->common.chain_index)
		memcpy(&tmp, f, sizeof(*f));

		if (!mlx5_esw_chains_prios_supported(esw) ||
		    tmp.common.chain_index)
			return -EOPNOTSUPP;

		/* Re-use tc offload path by moving the ft flow to the
		 * reserved ft chain.
		 *
		 * FT offload can use prio range [0, INT_MAX], so we normalize
		 * it to range [1, mlx5_esw_chains_get_prio_range(esw)]
		 * as with tc, where prio 0 isn't supported.
		 *
		 * We only support chain 0 of FT offload.
		 */
		memcpy(&cls_flower, f, sizeof(*f));
		cls_flower.common.chain_index = FDB_FT_CHAIN;
		err = mlx5e_rep_setup_tc_cls_flower(priv, &cls_flower, flags);
		memcpy(&f->stats, &cls_flower.stats, sizeof(f->stats));
		if (tmp.common.prio >= mlx5_esw_chains_get_prio_range(esw))
			return -EOPNOTSUPP;
		if (tmp.common.chain_index != 0)
			return -EOPNOTSUPP;

		tmp.common.chain_index = mlx5_esw_chains_get_ft_chain(esw);
		tmp.common.prio++;
		err = mlx5e_rep_setup_tc_cls_flower(priv, &tmp, flags);
		memcpy(&f->stats, &tmp.stats, sizeof(f->stats));
		return err;
	default:
		return -EOPNOTSUPP;
+1 −0
Original line number Diff line number Diff line
@@ -1133,6 +1133,7 @@ static void mlx5e_grp_per_port_buffer_congest_update_stats(struct mlx5e_priv *pr
static const struct counter_desc pport_per_prio_traffic_stats_desc[] = {
	{ "rx_prio%d_bytes", PPORT_PER_PRIO_OFF(rx_octets) },
	{ "rx_prio%d_packets", PPORT_PER_PRIO_OFF(rx_frames) },
	{ "rx_prio%d_discards", PPORT_PER_PRIO_OFF(rx_discards) },
	{ "tx_prio%d_bytes", PPORT_PER_PRIO_OFF(tx_octets) },
	{ "tx_prio%d_packets", PPORT_PER_PRIO_OFF(tx_frames) },
};
Loading