Commit 9d2e4e16 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'net-allow-user-specify-TC-action-HW-stats-type'



Jiri Pirko says:

====================
net: allow user specify TC action HW stats type

Currently, when user adds a TC action and the action gets offloaded,
the user expects the HW stats to be counted and included in stats dump.
However, since drivers may implement different types of counting, there
is no way to specify which one the user is interested in.

For example for mlx5, only delayed counters are available as the driver
periodically polls for updated stats.

In case of mlxsw, the counters are queried on dump time. However, the
HW resources for this type of counters is quite limited (couple of
thousands). This limits the amount of supported offloaded filters
significantly. Without counter assigned, the HW is capable to carry
millions of those.

On top of that, mlxsw HW is able to support delayed counters as well in
greater numbers. That is going to be added in a follow-up patch.

This patchset allows user to specify one of the following types of HW
stats for added action:
immediate - queried during dump time
delayed - polled from HW periodically or sent by HW in async manner
disabled - no stats needed

Note that if "hw_stats" option is not passed, user does not care about
the type, just expects any type of stats.

Examples:
$ tc filter add dev enp0s16np28 ingress proto ip handle 1 pref 1 flower skip_sw dst_ip 192.168.1.1 action drop hw_stats disabled
$ tc -s filter show dev enp0s16np28 ingress
filter protocol ip pref 1 flower chain 0
filter protocol ip pref 1 flower chain 0 handle 0x1
  eth_type ipv4
  dst_ip 192.168.1.1
  skip_sw
  in_hw in_hw_count 2
        action order 1: gact action drop
         random type none pass val 0
         index 1 ref 1 bind 1 installed 7 sec used 2 sec
        Action statistics:
        Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
        backlog 0b 0p requeues 0
        hw_stats disabled

$ tc filter add dev enp0s16np28 ingress proto ip handle 1 pref 1 flower skip_sw dst_ip 192.168.1.1 action drop hw_stats immediate
$ tc -s filter show dev enp0s16np28 ingress
filter protocol ip pref 1 flower chain 0
filter protocol ip pref 1 flower chain 0 handle 0x1
  eth_type ipv4
  dst_ip 192.168.1.1
  skip_sw
  in_hw in_hw_count 2
        action order 1: gact action drop
         random type none pass val 0
         index 1 ref 1 bind 1 installed 11 sec used 4 sec
        Action statistics:
        Sent 102 bytes 1 pkt (dropped 1, overlimits 0 requeues 0)
        Sent software 0 bytes 0 pkt
        Sent hardware 102 bytes 1 pkt
        backlog 0b 0p requeues 0
        hw_stats immediate
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents caf48383 44f86580
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -279,7 +279,8 @@ bnxt_tc_parse_pedit(struct bnxt *bp, struct bnxt_tc_actions *actions,

static int bnxt_tc_parse_actions(struct bnxt *bp,
				 struct bnxt_tc_actions *actions,
				 struct flow_action *flow_action)
				 struct flow_action *flow_action,
				 struct netlink_ext_ack *extack)
{
	/* Used to store the L2 rewrite mask for dmac (6 bytes) followed by
	 * smac (6 bytes) if rewrite of both is specified, otherwise either
@@ -299,6 +300,9 @@ static int bnxt_tc_parse_actions(struct bnxt *bp,
		return -EINVAL;
	}

	if (!flow_action_basic_hw_stats_types_check(flow_action, extack))
		return -EOPNOTSUPP;

	flow_action_for_each(i, act, flow_action) {
		switch (act->id) {
		case FLOW_ACTION_DROP:
@@ -491,7 +495,8 @@ static int bnxt_tc_parse_flow(struct bnxt *bp,
		flow->tun_mask.tp_src = match.mask->src;
	}

	return bnxt_tc_parse_actions(bp, &flow->actions, &rule->action);
	return bnxt_tc_parse_actions(bp, &flow->actions, &rule->action,
				     tc_flow_cmd->common.extack);
}

static int bnxt_hwrm_cfa_flow_free(struct bnxt *bp,
+6 −2
Original line number Diff line number Diff line
@@ -544,7 +544,8 @@ static bool valid_pedit_action(struct net_device *dev,
}

int cxgb4_validate_flow_actions(struct net_device *dev,
				struct flow_action *actions)
				struct flow_action *actions,
				struct netlink_ext_ack *extack)
{
	struct flow_action_entry *act;
	bool act_redir = false;
@@ -552,6 +553,9 @@ int cxgb4_validate_flow_actions(struct net_device *dev,
	bool act_vlan = false;
	int i;

	if (!flow_action_basic_hw_stats_types_check(actions, extack))
		return -EOPNOTSUPP;

	flow_action_for_each(i, act, actions) {
		switch (act->id) {
		case FLOW_ACTION_ACCEPT:
@@ -642,7 +646,7 @@ int cxgb4_tc_flower_replace(struct net_device *dev,
	struct filter_ctx ctx;
	int fidx, ret;

	if (cxgb4_validate_flow_actions(dev, &rule->action))
	if (cxgb4_validate_flow_actions(dev, &rule->action, extack))
		return -EOPNOTSUPP;

	if (cxgb4_validate_flow_match(dev, cls))
+2 −1
Original line number Diff line number Diff line
@@ -112,7 +112,8 @@ void cxgb4_process_flow_actions(struct net_device *in,
				struct flow_action *actions,
				struct ch_filter_specification *fs);
int cxgb4_validate_flow_actions(struct net_device *dev,
				struct flow_action *actions);
				struct flow_action *actions,
				struct netlink_ext_ack *extack);

int cxgb4_tc_flower_replace(struct net_device *dev,
			    struct flow_cls_offload *cls);
+2 −1
Original line number Diff line number Diff line
@@ -286,7 +286,8 @@ int cxgb4_tc_matchall_replace(struct net_device *dev,
		}

		ret = cxgb4_validate_flow_actions(dev,
						  &cls_matchall->rule->action);
						  &cls_matchall->rule->action,
						  extack);
		if (ret)
			return ret;

+6 −0
Original line number Diff line number Diff line
@@ -1082,6 +1082,9 @@ static int mvpp2_port_c2_tcam_rule_add(struct mvpp2_port *port,
	u8 qh, ql, pmap;
	int index, ctx;

	if (!flow_action_basic_hw_stats_types_check(&rule->flow->action, NULL))
		return -EOPNOTSUPP;

	memset(&c2, 0, sizeof(c2));

	index = mvpp2_cls_c2_port_flow_index(port, rule->loc);
@@ -1305,6 +1308,9 @@ static int mvpp2_cls_rfs_parse_rule(struct mvpp2_rfs_rule *rule)
	struct flow_rule *flow = rule->flow;
	struct flow_action_entry *act;

	if (!flow_action_basic_hw_stats_types_check(&rule->flow->action, NULL))
		return -EOPNOTSUPP;

	act = &flow->action.entries[0];
	if (act->id != FLOW_ACTION_QUEUE && act->id != FLOW_ACTION_DROP)
		return -EOPNOTSUPP;
Loading