netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [patch net-next 0/2] net: sched: expose HW stats types per action used by drivers
@ 2020-03-28 15:37 Jiri Pirko
  2020-03-28 15:37 ` [patch net-next 1/2] net: introduce nla_put_bitfield32() helper and use it Jiri Pirko
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Jiri Pirko @ 2020-03-28 15:37 UTC (permalink / raw)
  To: netdev
  Cc: davem, kuba, idosch, saeedm, leon, michael.chan, vishal, pablo,
	jhs, xiyou.wangcong, paulb, alexandre.belloni, ozsh, roid,
	john.hurley, simon.horman, pieter.jansenvanvuuren

From: Jiri Pirko <jiri@mellanox.com>

The first patch is just adding a helper used by the second patch too.
The second patch is exposing HW stats types that are used by drivers.

Example:

$ tc filter add dev enp3s0np1 ingress proto ip handle 1 pref 1 flower dst_ip 192.168.1.1 action drop
$ tc -s filter show dev enp3s0np1 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
  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 10 sec used 10 sec
        Action statistics:
        Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
        backlog 0b 0p requeues 0
        used_hw_stats immediate     <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Jiri Pirko (2):
  net: introduce nla_put_bitfield32() helper and use it
  net: sched: expose HW stats types per action used by drivers

 drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c  |  2 +-
 .../ethernet/chelsio/cxgb4/cxgb4_tc_flower.c  |  3 ++-
 .../chelsio/cxgb4/cxgb4_tc_matchall.c         |  3 ++-
 .../ethernet/mellanox/mlx5/core/en/tc_ct.c    |  3 ++-
 .../net/ethernet/mellanox/mlx5/core/en_tc.c   |  6 +++--
 .../net/ethernet/mellanox/mlxsw/spectrum.h    |  3 ++-
 .../ethernet/mellanox/mlxsw/spectrum_acl.c    |  4 ++-
 .../ethernet/mellanox/mlxsw/spectrum_flower.c |  5 ++--
 drivers/net/ethernet/mscc/ocelot_flower.c     |  3 ++-
 .../ethernet/netronome/nfp/flower/offload.c   |  3 ++-
 .../ethernet/netronome/nfp/flower/qos_conf.c  |  3 ++-
 include/net/act_api.h                         |  2 ++
 include/net/flow_offload.h                    | 12 ++++++++-
 include/net/netlink.h                         | 15 +++++++++++
 include/net/pkt_cls.h                         |  5 +++-
 include/uapi/linux/pkt_cls.h                  |  1 +
 net/sched/act_api.c                           | 27 +++++++++----------
 net/sched/cls_flower.c                        |  4 ++-
 net/sched/cls_matchall.c                      |  4 ++-
 net/sched/sch_red.c                           |  7 ++---
 20 files changed, 78 insertions(+), 37 deletions(-)

-- 
2.21.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [patch net-next 1/2] net: introduce nla_put_bitfield32() helper and use it
  2020-03-28 15:37 [patch net-next 0/2] net: sched: expose HW stats types per action used by drivers Jiri Pirko
@ 2020-03-28 15:37 ` Jiri Pirko
  2020-03-28 15:37 ` [patch net-next 2/2] net: sched: expose HW stats types per action used by drivers Jiri Pirko
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Jiri Pirko @ 2020-03-28 15:37 UTC (permalink / raw)
  To: netdev
  Cc: davem, kuba, idosch, saeedm, leon, michael.chan, vishal, pablo,
	jhs, xiyou.wangcong, paulb, alexandre.belloni, ozsh, roid,
	john.hurley, simon.horman, pieter.jansenvanvuuren

From: Jiri Pirko <jiri@mellanox.com>

Introduce a helper to pass value and selector to. The helper packs them
into struct and puts them into netlink message.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 include/net/netlink.h | 15 +++++++++++++++
 net/sched/act_api.c   | 24 ++++++++----------------
 net/sched/sch_red.c   |  7 ++-----
 3 files changed, 25 insertions(+), 21 deletions(-)

diff --git a/include/net/netlink.h b/include/net/netlink.h
index 56c365dc6dc7..67c57d6942e3 100644
--- a/include/net/netlink.h
+++ b/include/net/netlink.h
@@ -1465,6 +1465,21 @@ static inline int nla_put_in6_addr(struct sk_buff *skb, int attrtype,
 	return nla_put(skb, attrtype, sizeof(*addr), addr);
 }
 
+/**
+ * nla_put_bitfield32 - Add a bitfield32 netlink attribute to a socket buffer
+ * @skb: socket buffer to add attribute to
+ * @attrtype: attribute type
+ * @value: value carrying bits
+ * @selector: selector of valid bits
+ */
+static inline int nla_put_bitfield32(struct sk_buff *skb, int attrtype,
+				     __u32 value, __u32 selector)
+{
+	struct nla_bitfield32 tmp = { value, selector, };
+
+	return nla_put(skb, attrtype, sizeof(tmp), &tmp);
+}
+
 /**
  * nla_get_u32 - return payload of u32 attribute
  * @nla: u32 netlink attribute
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 861a831b0ef7..33cc77e6e56c 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -789,23 +789,15 @@ tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
 	}
 	rcu_read_unlock();
 
-	if (a->hw_stats != TCA_ACT_HW_STATS_ANY) {
-		struct nla_bitfield32 hw_stats = {
-			a->hw_stats,
-			TCA_ACT_HW_STATS_ANY,
-		};
-
-		if (nla_put(skb, TCA_ACT_HW_STATS, sizeof(hw_stats), &hw_stats))
-			goto nla_put_failure;
-	}
-
-	if (a->tcfa_flags) {
-		struct nla_bitfield32 flags = { a->tcfa_flags,
-						a->tcfa_flags, };
+	if (a->hw_stats != TCA_ACT_HW_STATS_ANY &&
+	    nla_put_bitfield32(skb, TCA_ACT_HW_STATS,
+			       a->hw_stats, TCA_ACT_HW_STATS_ANY))
+		goto nla_put_failure;
 
-		if (nla_put(skb, TCA_ACT_FLAGS, sizeof(flags), &flags))
-			goto nla_put_failure;
-	}
+	if (a->tcfa_flags &&
+	    nla_put_bitfield32(skb, TCA_ACT_FLAGS,
+			       a->tcfa_flags, a->tcfa_flags))
+		goto nla_put_failure;
 
 	nest = nla_nest_start_noflag(skb, TCA_OPTIONS);
 	if (nest == NULL)
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
index 3ef0a4f7399b..c7de47c942e3 100644
--- a/net/sched/sch_red.c
+++ b/net/sched/sch_red.c
@@ -349,10 +349,6 @@ static int red_dump_offload_stats(struct Qdisc *sch)
 static int red_dump(struct Qdisc *sch, struct sk_buff *skb)
 {
 	struct red_sched_data *q = qdisc_priv(sch);
-	struct nla_bitfield32 flags_bf = {
-		.selector = red_supported_flags,
-		.value = q->flags,
-	};
 	struct nlattr *opts = NULL;
 	struct tc_red_qopt opt = {
 		.limit		= q->limit,
@@ -375,7 +371,8 @@ static int red_dump(struct Qdisc *sch, struct sk_buff *skb)
 		goto nla_put_failure;
 	if (nla_put(skb, TCA_RED_PARMS, sizeof(opt), &opt) ||
 	    nla_put_u32(skb, TCA_RED_MAX_P, q->parms.max_P) ||
-	    nla_put(skb, TCA_RED_FLAGS, sizeof(flags_bf), &flags_bf))
+	    nla_put_bitfield32(skb, TCA_RED_FLAGS,
+			       q->flags, red_supported_flags))
 		goto nla_put_failure;
 	return nla_nest_end(skb, opts);
 
-- 
2.21.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [patch net-next 2/2] net: sched: expose HW stats types per action used by drivers
  2020-03-28 15:37 [patch net-next 0/2] net: sched: expose HW stats types per action used by drivers Jiri Pirko
  2020-03-28 15:37 ` [patch net-next 1/2] net: introduce nla_put_bitfield32() helper and use it Jiri Pirko
@ 2020-03-28 15:37 ` Jiri Pirko
  2020-03-28 15:40 ` [patch iproute2/net-next] tc: show used HW stats types Jiri Pirko
  2020-03-30 18:07 ` [patch net-next 0/2] net: sched: expose HW stats types per action used by drivers David Miller
  3 siblings, 0 replies; 5+ messages in thread
From: Jiri Pirko @ 2020-03-28 15:37 UTC (permalink / raw)
  To: netdev
  Cc: davem, kuba, idosch, saeedm, leon, michael.chan, vishal, pablo,
	jhs, xiyou.wangcong, paulb, alexandre.belloni, ozsh, roid,
	john.hurley, simon.horman, pieter.jansenvanvuuren

From: Jiri Pirko <jiri@mellanox.com>

It may be up to the driver (in case ANY HW stats is passed) to select
which type of HW stats he is going to use. Add an infrastructure to
expose this information to user.

$ tc filter add dev enp3s0np1 ingress proto ip handle 1 pref 1 flower dst_ip 192.168.1.1 action drop
$ tc -s filter show dev enp3s0np1 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
  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 10 sec used 10 sec
        Action statistics:
        Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
        backlog 0b 0p requeues 0
        used_hw_stats immediate     <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c         |  2 +-
 drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c |  3 ++-
 .../net/ethernet/chelsio/cxgb4/cxgb4_tc_matchall.c   |  3 ++-
 drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c   |  3 ++-
 drivers/net/ethernet/mellanox/mlx5/core/en_tc.c      |  6 ++++--
 drivers/net/ethernet/mellanox/mlxsw/spectrum.h       |  3 ++-
 drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c   |  4 +++-
 .../net/ethernet/mellanox/mlxsw/spectrum_flower.c    |  5 +++--
 drivers/net/ethernet/mscc/ocelot_flower.c            |  3 ++-
 drivers/net/ethernet/netronome/nfp/flower/offload.c  |  3 ++-
 drivers/net/ethernet/netronome/nfp/flower/qos_conf.c |  3 ++-
 include/net/act_api.h                                |  2 ++
 include/net/flow_offload.h                           | 12 +++++++++++-
 include/net/pkt_cls.h                                |  5 ++++-
 include/uapi/linux/pkt_cls.h                         |  1 +
 net/sched/act_api.c                                  |  5 +++++
 net/sched/cls_flower.c                               |  4 +++-
 net/sched/cls_matchall.c                             |  4 +++-
 18 files changed, 54 insertions(+), 17 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
index b19be7549aad..782ea0771221 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
@@ -1639,7 +1639,7 @@ static int bnxt_tc_get_flow_stats(struct bnxt *bp,
 	spin_unlock(&flow->stats_lock);
 
 	flow_stats_update(&tc_flow_cmd->stats, stats.bytes, stats.packets,
-			  lastused);
+			  lastused, FLOW_ACTION_HW_STATS_DELAYED);
 	return 0;
 }
 
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
index aec9b90313e7..4a5fa9eba0b6 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
@@ -903,7 +903,8 @@ int cxgb4_tc_flower_stats(struct net_device *dev,
 			ofld_stats->last_used = jiffies;
 		flow_stats_update(&cls->stats, bytes - ofld_stats->byte_count,
 				  packets - ofld_stats->packet_count,
-				  ofld_stats->last_used);
+				  ofld_stats->last_used,
+				  FLOW_ACTION_HW_STATS_IMMEDIATE);
 
 		ofld_stats->packet_count = packets;
 		ofld_stats->byte_count = bytes;
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_matchall.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_matchall.c
index 8a5ae8bc9b7d..c88c47a14fbb 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_matchall.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_matchall.c
@@ -346,7 +346,8 @@ int cxgb4_tc_matchall_stats(struct net_device *dev,
 		flow_stats_update(&cls_matchall->stats,
 				  bytes - tc_port_matchall->ingress.bytes,
 				  packets - tc_port_matchall->ingress.packets,
-				  tc_port_matchall->ingress.last_used);
+				  tc_port_matchall->ingress.last_used,
+				  FLOW_ACTION_HW_STATS_IMMEDIATE);
 
 		tc_port_matchall->ingress.packets = packets;
 		tc_port_matchall->ingress.bytes = bytes;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
index a22ad6b90847..dca449722ea7 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
@@ -666,7 +666,8 @@ mlx5_tc_ct_block_flow_offload_stats(struct mlx5_ct_ft *ft,
 		return -ENOENT;
 
 	mlx5_fc_query_cached(entry->counter, &bytes, &packets, &lastuse);
-	flow_stats_update(&f->stats, bytes, packets, lastuse);
+	flow_stats_update(&f->stats, bytes, packets, lastuse,
+			  FLOW_ACTION_HW_STATS_DELAYED);
 
 	return 0;
 }
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
index 901b5fa5568f..efa143874cde 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
@@ -4468,7 +4468,8 @@ int mlx5e_stats_flower(struct net_device *dev, struct mlx5e_priv *priv,
 no_peer_counter:
 	mlx5_devcom_release_peer_data(devcom, MLX5_DEVCOM_ESW_OFFLOADS);
 out:
-	flow_stats_update(&f->stats, bytes, packets, lastuse);
+	flow_stats_update(&f->stats, bytes, packets, lastuse,
+			  FLOW_ACTION_HW_STATS_DELAYED);
 	trace_mlx5e_stats_flower(f);
 errout:
 	mlx5e_flow_put(priv, flow);
@@ -4585,7 +4586,8 @@ void mlx5e_tc_stats_matchall(struct mlx5e_priv *priv,
 	dpkts = cur_stats.rx_packets - rpriv->prev_vf_vport_stats.rx_packets;
 	dbytes = cur_stats.rx_bytes - rpriv->prev_vf_vport_stats.rx_bytes;
 	rpriv->prev_vf_vport_stats = cur_stats;
-	flow_stats_update(&ma->stats, dpkts, dbytes, jiffies);
+	flow_stats_update(&ma->stats, dpkts, dbytes, jiffies,
+			  FLOW_ACTION_HW_STATS_DELAYED);
 }
 
 static void mlx5e_tc_hairpin_update_dead_peer(struct mlx5e_priv *priv,
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
index 273e373a37b6..9f06f7a5308a 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
@@ -786,7 +786,8 @@ struct mlxsw_sp_acl_rule_info *
 mlxsw_sp_acl_rule_rulei(struct mlxsw_sp_acl_rule *rule);
 int mlxsw_sp_acl_rule_get_stats(struct mlxsw_sp *mlxsw_sp,
 				struct mlxsw_sp_acl_rule *rule,
-				u64 *packets, u64 *bytes, u64 *last_use);
+				u64 *packets, u64 *bytes, u64 *last_use,
+				enum flow_action_hw_stats *used_hw_stats);
 
 struct mlxsw_sp_fid *mlxsw_sp_acl_dummy_fid(struct mlxsw_sp *mlxsw_sp);
 
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
index 6fc1496b9514..67ee880a8727 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
@@ -967,7 +967,8 @@ static void mlxsw_sp_acl_rule_activity_update_work(struct work_struct *work)
 
 int mlxsw_sp_acl_rule_get_stats(struct mlxsw_sp *mlxsw_sp,
 				struct mlxsw_sp_acl_rule *rule,
-				u64 *packets, u64 *bytes, u64 *last_use)
+				u64 *packets, u64 *bytes, u64 *last_use,
+				enum flow_action_hw_stats *used_hw_stats)
 
 {
 	struct mlxsw_sp_acl_rule_info *rulei;
@@ -982,6 +983,7 @@ int mlxsw_sp_acl_rule_get_stats(struct mlxsw_sp *mlxsw_sp,
 						&current_bytes);
 		if (err)
 			return err;
+		*used_hw_stats = FLOW_ACTION_HW_STATS_IMMEDIATE;
 	}
 	*packets = current_packets - rule->last_packets;
 	*bytes = current_bytes - rule->last_bytes;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c
index 33a5e2a0a1ad..2f76908cae73 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c
@@ -571,6 +571,7 @@ int mlxsw_sp_flower_stats(struct mlxsw_sp *mlxsw_sp,
 			  struct mlxsw_sp_acl_block *block,
 			  struct flow_cls_offload *f)
 {
+	enum flow_action_hw_stats used_hw_stats = FLOW_ACTION_HW_STATS_DISABLED;
 	struct mlxsw_sp_acl_ruleset *ruleset;
 	struct mlxsw_sp_acl_rule *rule;
 	u64 packets;
@@ -589,11 +590,11 @@ int mlxsw_sp_flower_stats(struct mlxsw_sp *mlxsw_sp,
 		return -EINVAL;
 
 	err = mlxsw_sp_acl_rule_get_stats(mlxsw_sp, rule, &packets, &bytes,
-					  &lastuse);
+					  &lastuse, &used_hw_stats);
 	if (err)
 		goto err_rule_get_stats;
 
-	flow_stats_update(&f->stats, bytes, packets, lastuse);
+	flow_stats_update(&f->stats, bytes, packets, lastuse, used_hw_stats);
 
 	mlxsw_sp_acl_ruleset_put(mlxsw_sp, ruleset);
 	return 0;
diff --git a/drivers/net/ethernet/mscc/ocelot_flower.c b/drivers/net/ethernet/mscc/ocelot_flower.c
index 873a9944fbfb..829987eb74cb 100644
--- a/drivers/net/ethernet/mscc/ocelot_flower.c
+++ b/drivers/net/ethernet/mscc/ocelot_flower.c
@@ -224,7 +224,8 @@ int ocelot_cls_flower_stats(struct ocelot *ocelot, int port,
 	if (ret)
 		return ret;
 
-	flow_stats_update(&f->stats, 0x0, ace.stats.pkts, 0x0);
+	flow_stats_update(&f->stats, 0x0, ace.stats.pkts, 0x0,
+			  FLOW_ACTION_HW_STATS_IMMEDIATE);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(ocelot_cls_flower_stats);
diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c
index 7ca5c1becfcf..c694dbc239d0 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/offload.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c
@@ -1490,7 +1490,8 @@ nfp_flower_get_stats(struct nfp_app *app, struct net_device *netdev,
 		nfp_flower_update_merge_stats(app, nfp_flow);
 
 	flow_stats_update(&flow->stats, priv->stats[ctx_id].bytes,
-			  priv->stats[ctx_id].pkts, priv->stats[ctx_id].used);
+			  priv->stats[ctx_id].pkts, priv->stats[ctx_id].used,
+			  FLOW_ACTION_HW_STATS_DELAYED);
 
 	priv->stats[ctx_id].pkts = 0;
 	priv->stats[ctx_id].bytes = 0;
diff --git a/drivers/net/ethernet/netronome/nfp/flower/qos_conf.c b/drivers/net/ethernet/netronome/nfp/flower/qos_conf.c
index 124a43dc136a..d18a830e4264 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/qos_conf.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/qos_conf.c
@@ -320,7 +320,8 @@ nfp_flower_stats_rate_limiter(struct nfp_app *app, struct net_device *netdev,
 	spin_unlock_bh(&fl_priv->qos_stats_lock);
 
 	flow_stats_update(&flow->stats, diff_bytes, diff_pkts,
-			  repr_priv->qos_table.last_update);
+			  repr_priv->qos_table.last_update,
+			  FLOW_ACTION_HW_STATS_DELAYED);
 	return 0;
 }
 
diff --git a/include/net/act_api.h b/include/net/act_api.h
index ecdec9d6ead0..c24d7643548e 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -42,6 +42,8 @@ struct tc_action {
 	struct tcf_chain	__rcu *goto_chain;
 	u32			tcfa_flags;
 	u8			hw_stats;
+	u8			used_hw_stats;
+	bool			used_hw_stats_valid;
 };
 #define tcf_index	common.tcfa_index
 #define tcf_refcnt	common.tcfa_refcnt
diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h
index ff071eaede17..f66fc6a3020d 100644
--- a/include/net/flow_offload.h
+++ b/include/net/flow_offload.h
@@ -370,14 +370,24 @@ struct flow_stats {
 	u64	pkts;
 	u64	bytes;
 	u64	lastused;
+	enum flow_action_hw_stats used_hw_stats;
+	bool used_hw_stats_valid;
 };
 
 static inline void flow_stats_update(struct flow_stats *flow_stats,
-				     u64 bytes, u64 pkts, u64 lastused)
+				     u64 bytes, u64 pkts, u64 lastused,
+				     enum flow_action_hw_stats used_hw_stats)
 {
 	flow_stats->pkts	+= pkts;
 	flow_stats->bytes	+= bytes;
 	flow_stats->lastused	= max_t(u64, flow_stats->lastused, lastused);
+
+	/* The driver should pass value with a maximum of one bit set.
+	 * Passing FLOW_ACTION_HW_STATS_ANY is invalid.
+	 */
+	WARN_ON(used_hw_stats == FLOW_ACTION_HW_STATS_ANY);
+	flow_stats->used_hw_stats |= used_hw_stats;
+	flow_stats->used_hw_stats_valid = true;
 }
 
 enum flow_block_command {
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 41902e10d503..04aa0649f3b0 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -262,7 +262,8 @@ static inline void tcf_exts_put_net(struct tcf_exts *exts)
 
 static inline void
 tcf_exts_stats_update(const struct tcf_exts *exts,
-		      u64 bytes, u64 packets, u64 lastuse)
+		      u64 bytes, u64 packets, u64 lastuse,
+		      u8 used_hw_stats, bool used_hw_stats_valid)
 {
 #ifdef CONFIG_NET_CLS_ACT
 	int i;
@@ -273,6 +274,8 @@ tcf_exts_stats_update(const struct tcf_exts *exts,
 		struct tc_action *a = exts->actions[i];
 
 		tcf_action_stats_update(a, bytes, packets, lastuse, true);
+		a->used_hw_stats = used_hw_stats;
+		a->used_hw_stats_valid = used_hw_stats_valid;
 	}
 
 	preempt_enable();
diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
index 6fcf7307e534..9f06d29cab70 100644
--- a/include/uapi/linux/pkt_cls.h
+++ b/include/uapi/linux/pkt_cls.h
@@ -18,6 +18,7 @@ enum {
 	TCA_ACT_COOKIE,
 	TCA_ACT_FLAGS,
 	TCA_ACT_HW_STATS,
+	TCA_ACT_USED_HW_STATS,
 	__TCA_ACT_MAX
 };
 
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 33cc77e6e56c..df4560909157 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -794,6 +794,11 @@ tcf_action_dump_1(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
 			       a->hw_stats, TCA_ACT_HW_STATS_ANY))
 		goto nla_put_failure;
 
+	if (a->used_hw_stats_valid &&
+	    nla_put_bitfield32(skb, TCA_ACT_USED_HW_STATS,
+			       a->used_hw_stats, TCA_ACT_HW_STATS_ANY))
+		goto nla_put_failure;
+
 	if (a->tcfa_flags &&
 	    nla_put_bitfield32(skb, TCA_ACT_FLAGS,
 			       a->tcfa_flags, a->tcfa_flags))
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index 9b6acd736dc8..74a0febcafb8 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -492,7 +492,9 @@ static void fl_hw_update_stats(struct tcf_proto *tp, struct cls_fl_filter *f,
 
 	tcf_exts_stats_update(&f->exts, cls_flower.stats.bytes,
 			      cls_flower.stats.pkts,
-			      cls_flower.stats.lastused);
+			      cls_flower.stats.lastused,
+			      cls_flower.stats.used_hw_stats,
+			      cls_flower.stats.used_hw_stats_valid);
 }
 
 static void __fl_put(struct cls_fl_filter *f)
diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c
index a34b36adb9b7..8d39dbcf1746 100644
--- a/net/sched/cls_matchall.c
+++ b/net/sched/cls_matchall.c
@@ -338,7 +338,9 @@ static void mall_stats_hw_filter(struct tcf_proto *tp,
 	tc_setup_cb_call(block, TC_SETUP_CLSMATCHALL, &cls_mall, false, true);
 
 	tcf_exts_stats_update(&head->exts, cls_mall.stats.bytes,
-			      cls_mall.stats.pkts, cls_mall.stats.lastused);
+			      cls_mall.stats.pkts, cls_mall.stats.lastused,
+			      cls_mall.stats.used_hw_stats,
+			      cls_mall.stats.used_hw_stats_valid);
 }
 
 static int mall_dump(struct net *net, struct tcf_proto *tp, void *fh,
-- 
2.21.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [patch iproute2/net-next] tc: show used HW stats types
  2020-03-28 15:37 [patch net-next 0/2] net: sched: expose HW stats types per action used by drivers Jiri Pirko
  2020-03-28 15:37 ` [patch net-next 1/2] net: introduce nla_put_bitfield32() helper and use it Jiri Pirko
  2020-03-28 15:37 ` [patch net-next 2/2] net: sched: expose HW stats types per action used by drivers Jiri Pirko
@ 2020-03-28 15:40 ` Jiri Pirko
  2020-03-30 18:07 ` [patch net-next 0/2] net: sched: expose HW stats types per action used by drivers David Miller
  3 siblings, 0 replies; 5+ messages in thread
From: Jiri Pirko @ 2020-03-28 15:40 UTC (permalink / raw)
  To: netdev
  Cc: davem, kuba, idosch, saeedm, leon, michael.chan, vishal, pablo,
	jhs, xiyou.wangcong, paulb, alexandre.belloni, ozsh, roid,
	john.hurley, simon.horman, pieter.jansenvanvuuren

From: Jiri Pirko <jiri@mellanox.com>

If kernel provides the attribute, show the used HW stats types.

Example:

$ tc filter add dev enp3s0np1 ingress proto ip handle 1 pref 1 flower dst_ip 192.168.1.1 action drop
$ tc -s filter show dev enp3s0np1 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
  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 10 sec used 10 sec
        Action statistics:
        Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
        backlog 0b 0p requeues 0
        used_hw_stats immediate     <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 include/uapi/linux/pkt_cls.h | 1 +
 tc/m_action.c                | 9 ++++++---
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
index 6fcf7307e534..9f06d29cab70 100644
--- a/include/uapi/linux/pkt_cls.h
+++ b/include/uapi/linux/pkt_cls.h
@@ -18,6 +18,7 @@ enum {
 	TCA_ACT_COOKIE,
 	TCA_ACT_FLAGS,
 	TCA_ACT_HW_STATS,
+	TCA_ACT_USED_HW_STATS,
 	__TCA_ACT_MAX
 };
 
diff --git a/tc/m_action.c b/tc/m_action.c
index 2c4b5df6e05c..d499a38c9f57 100644
--- a/tc/m_action.c
+++ b/tc/m_action.c
@@ -159,7 +159,7 @@ static const struct hw_stats_item {
 	{ "disabled", 0 }, /* no bit set */
 };
 
-static void print_hw_stats(const struct rtattr *arg)
+static void print_hw_stats(const struct rtattr *arg, bool print_used)
 {
 	struct nla_bitfield32 *hw_stats_bf = RTA_DATA(arg);
 	__u8 hw_stats;
@@ -167,7 +167,7 @@ static void print_hw_stats(const struct rtattr *arg)
 
 	hw_stats = hw_stats_bf->value & hw_stats_bf->selector;
 	print_string(PRINT_FP, NULL, "\t", NULL);
-	open_json_array(PRINT_ANY, "hw_stats");
+	open_json_array(PRINT_ANY, print_used ? "used_hw_stats" : "hw_stats");
 
 	for (i = 0; i < ARRAY_SIZE(hw_stats_items); i++) {
 		const struct hw_stats_item *item;
@@ -399,7 +399,10 @@ static int tc_print_one_action(FILE *f, struct rtattr *arg)
 		print_string(PRINT_FP, NULL, "%s", _SL_);
 	}
 	if (tb[TCA_ACT_HW_STATS])
-		print_hw_stats(tb[TCA_ACT_HW_STATS]);
+		print_hw_stats(tb[TCA_ACT_HW_STATS], false);
+
+	if (tb[TCA_ACT_USED_HW_STATS])
+		print_hw_stats(tb[TCA_ACT_USED_HW_STATS], true);
 
 	return 0;
 }
-- 
2.21.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [patch net-next 0/2] net: sched: expose HW stats types per action used by drivers
  2020-03-28 15:37 [patch net-next 0/2] net: sched: expose HW stats types per action used by drivers Jiri Pirko
                   ` (2 preceding siblings ...)
  2020-03-28 15:40 ` [patch iproute2/net-next] tc: show used HW stats types Jiri Pirko
@ 2020-03-30 18:07 ` David Miller
  3 siblings, 0 replies; 5+ messages in thread
From: David Miller @ 2020-03-30 18:07 UTC (permalink / raw)
  To: jiri
  Cc: netdev, kuba, idosch, saeedm, leon, michael.chan, vishal, pablo,
	jhs, xiyou.wangcong, paulb, alexandre.belloni, ozsh, roid,
	john.hurley, simon.horman, pieter.jansenvanvuuren

From: Jiri Pirko <jiri@resnulli.us>
Date: Sat, 28 Mar 2020 16:37:41 +0100

> From: Jiri Pirko <jiri@mellanox.com>
> 
> The first patch is just adding a helper used by the second patch too.
> The second patch is exposing HW stats types that are used by drivers.
> 
> Example:
> 
> $ tc filter add dev enp3s0np1 ingress proto ip handle 1 pref 1 flower dst_ip 192.168.1.1 action drop
> $ tc -s filter show dev enp3s0np1 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
>   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 10 sec used 10 sec
>         Action statistics:
>         Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
>         backlog 0b 0p requeues 0
>         used_hw_stats immediate     <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Series applied, thanks Jiri.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-03-30 18:07 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-28 15:37 [patch net-next 0/2] net: sched: expose HW stats types per action used by drivers Jiri Pirko
2020-03-28 15:37 ` [patch net-next 1/2] net: introduce nla_put_bitfield32() helper and use it Jiri Pirko
2020-03-28 15:37 ` [patch net-next 2/2] net: sched: expose HW stats types per action used by drivers Jiri Pirko
2020-03-28 15:40 ` [patch iproute2/net-next] tc: show used HW stats types Jiri Pirko
2020-03-30 18:07 ` [patch net-next 0/2] net: sched: expose HW stats types per action used by drivers David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).