net: qos offload add flow status with dropped count
authorPo Liu <Po.Liu@nxp.com>
Fri, 19 Jun 2020 06:01:07 +0000 (14:01 +0800)
committerDavid S. Miller <davem@davemloft.net>
Fri, 19 Jun 2020 19:53:30 +0000 (12:53 -0700)
This patch adds a drop frames counter to tc flower offloading.
Reporting h/w dropped frames is necessary for some actions.
Some actions like police action and the coming introduced stream gate
action would produce dropped frames which is necessary for user. Status
update shows how many filtered packets increasing and how many dropped
in those packets.

v2: Changes
 - Update commit comments suggest by Jiri Pirko.

Signed-off-by: Po Liu <Po.Liu@nxp.com>
Reviewed-by: Simon Horman <simon.horman@netronome.com>
Reviewed-by: Vlad Buslov <vladbu@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
25 files changed:
drivers/net/dsa/sja1105/sja1105_vl.c
drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_matchall.c
drivers/net/ethernet/freescale/enetc/enetc_qos.c
drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c
drivers/net/ethernet/mscc/ocelot_flower.c
drivers/net/ethernet/netronome/nfp/flower/offload.c
drivers/net/ethernet/netronome/nfp/flower/qos_conf.c
include/net/act_api.h
include/net/flow_offload.h
include/net/pkt_cls.h
net/sched/act_api.c
net/sched/act_ct.c
net/sched/act_gact.c
net/sched/act_gate.c
net/sched/act_mirred.c
net/sched/act_pedit.c
net/sched/act_police.c
net/sched/act_skbedit.c
net/sched/act_vlan.c
net/sched/cls_flower.c
net/sched/cls_matchall.c

index bdfd6c4e190d6295cadfcc2f975628d0e25e1510..9ddc49b7eb8fc966512a4683b033ca811e6bc58e 100644 (file)
@@ -771,7 +771,7 @@ int sja1105_vl_stats(struct sja1105_private *priv, int port,
 
        pkts = timingerr + unreleased + lengtherr;
 
-       flow_stats_update(stats, 0, pkts - rule->vl.stats.pkts,
+       flow_stats_update(stats, 0, pkts - rule->vl.stats.pkts, 0,
                          jiffies - rule->vl.stats.lastused,
                          FLOW_ACTION_HW_STATS_IMMEDIATE);
 
index 0eef4f5e4a469518cfeae262febba0c1cb6084ca..4d482d75a20b41254780ea3f17f8c33c57a8ab6b 100644 (file)
@@ -1638,7 +1638,7 @@ static int bnxt_tc_get_flow_stats(struct bnxt *bp,
        lastused = flow->lastused;
        spin_unlock(&flow->stats_lock);
 
-       flow_stats_update(&tc_flow_cmd->stats, stats.bytes, stats.packets,
+       flow_stats_update(&tc_flow_cmd->stats, stats.bytes, stats.packets, 0,
                          lastused, FLOW_ACTION_HW_STATS_DELAYED);
        return 0;
 }
index 4a5fa9eba0b64cb7a26cc7ac21cd674e5e2e11d4..030de20a5d2754d451bb778d79e4c636932c8c99 100644 (file)
@@ -902,7 +902,7 @@ int cxgb4_tc_flower_stats(struct net_device *dev,
                if (ofld_stats->prev_packet_count != packets)
                        ofld_stats->last_used = jiffies;
                flow_stats_update(&cls->stats, bytes - ofld_stats->byte_count,
-                                 packets - ofld_stats->packet_count,
+                                 packets - ofld_stats->packet_count, 0,
                                  ofld_stats->last_used,
                                  FLOW_ACTION_HW_STATS_IMMEDIATE);
 
index c88c47a14fbb3f2ac15cad3a276090a2824dfd22..c439b5bce9c9d05b4cd9837dee6029de71e16e41 100644 (file)
@@ -346,7 +346,7 @@ 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,
+                                 0, tc_port_matchall->ingress.last_used,
                                  FLOW_ACTION_HW_STATS_IMMEDIATE);
 
                tc_port_matchall->ingress.packets = packets;
index fd3df19eaa328a2424b771b31d3ac7377c42fd20..fb76903eca90cda7dcc821ed55cfef1ee235c727 100644 (file)
@@ -1291,12 +1291,15 @@ static int enetc_psfp_get_stats(struct enetc_ndev_priv *priv,
 
        spin_lock(&epsfp.psfp_lock);
        stats.pkts = counters.matching_frames_count - filter->stats.pkts;
+       stats.drops = counters.not_passing_frames_count -
+                                       filter->stats.drops;
        stats.lastused = filter->stats.lastused;
        filter->stats.pkts += stats.pkts;
+       filter->stats.drops += stats.drops;
        spin_unlock(&epsfp.psfp_lock);
 
-       flow_stats_update(&f->stats, 0x0, stats.pkts, stats.lastused,
-                         FLOW_ACTION_HW_STATS_DELAYED);
+       flow_stats_update(&f->stats, 0x0, stats.pkts, stats.drops,
+                         stats.lastused, FLOW_ACTION_HW_STATS_DELAYED);
 
        return 0;
 }
index 430025550fad2ba7c222dc4b0ae5c81ec8211d2d..c7107da032120e7e023773d7330678335dc62c7c 100644 (file)
@@ -672,7 +672,7 @@ 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, 0, lastuse,
                          FLOW_ACTION_HW_STATS_DELAYED);
 
        return 0;
index 7fc84f58e28a4f9d96408aeb59dcbaed4cc84b60..bc9c0ac15f99decc4a15aa58564453d7ad72dff0 100644 (file)
@@ -4828,7 +4828,7 @@ 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, 0, lastuse,
                          FLOW_ACTION_HW_STATS_DELAYED);
        trace_mlx5e_stats_flower(f);
 errout:
@@ -4946,7 +4946,7 @@ 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, dbytes, dpkts, jiffies,
+       flow_stats_update(&ma->stats, dbytes, dpkts, 0, jiffies,
                          FLOW_ACTION_HW_STATS_DELAYED);
 }
 
index 51e1b3930c568f89c77f053af22723cae80445c8..61d21043d83abab9f9dd535392fdfd54adc61839 100644 (file)
@@ -633,7 +633,7 @@ int mlxsw_sp_flower_stats(struct mlxsw_sp *mlxsw_sp,
        if (err)
                goto err_rule_get_stats;
 
-       flow_stats_update(&f->stats, bytes, packets, lastuse, used_hw_stats);
+       flow_stats_update(&f->stats, bytes, packets, 0, lastuse, used_hw_stats);
 
        mlxsw_sp_acl_ruleset_put(mlxsw_sp, ruleset);
        return 0;
index 5ce172e22b43f631c0a4a93a2dc2b0fbc1782fbe..c90bafbd651f66b603c46094ae6afd188ba9ff40 100644 (file)
@@ -244,7 +244,7 @@ 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, 0, 0x0,
                          FLOW_ACTION_HW_STATS_IMMEDIATE);
        return 0;
 }
index 695d24b9dd928addb9d002d2bae0f790ce29dd3e..234c652700e1afad17eb0bc5a0f98126dd3ae0f5 100644 (file)
@@ -1491,7 +1491,7 @@ 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, 0, priv->stats[ctx_id].used,
                          FLOW_ACTION_HW_STATS_DELAYED);
 
        priv->stats[ctx_id].pkts = 0;
index d18a830e426490496f5e3281a9641f009131a3b4..bb327d48d1abcad28aa3ba4952d8565e8749bd21 100644 (file)
@@ -319,7 +319,7 @@ nfp_flower_stats_rate_limiter(struct nfp_app *app, struct net_device *netdev,
        prev_stats->bytes = curr_stats->bytes;
        spin_unlock_bh(&fl_priv->qos_stats_lock);
 
-       flow_stats_update(&flow->stats, diff_bytes, diff_pkts,
+       flow_stats_update(&flow->stats, diff_bytes, diff_pkts, 0,
                          repr_priv->qos_table.last_update,
                          FLOW_ACTION_HW_STATS_DELAYED);
        return 0;
index 8c393488067057525ffea9814b38b94fbcb00c09..cb382a89ea5800cae9878e1f20833f20580ba658 100644 (file)
@@ -106,7 +106,7 @@ struct tc_action_ops {
                        struct netlink_callback *, int,
                        const struct tc_action_ops *,
                        struct netlink_ext_ack *);
-       void    (*stats_update)(struct tc_action *, u64, u32, u64, bool);
+       void    (*stats_update)(struct tc_action *, u64, u64, u64, u64, bool);
        size_t  (*get_fill_size)(const struct tc_action *act);
        struct net_device *(*get_dev)(const struct tc_action *a,
                                      tc_action_priv_destructor *destructor);
@@ -232,8 +232,8 @@ static inline void tcf_action_inc_overlimit_qstats(struct tc_action *a)
        spin_unlock(&a->tcfa_lock);
 }
 
-void tcf_action_update_stats(struct tc_action *a, u64 bytes, u32 packets,
-                            bool drop, bool hw);
+void tcf_action_update_stats(struct tc_action *a, u64 bytes, u64 packets,
+                            u64 drops, bool hw);
 int tcf_action_copy_stats(struct sk_buff *, struct tc_action *, int);
 
 int tcf_action_check_ctrlact(int action, struct tcf_proto *tp,
@@ -244,13 +244,14 @@ struct tcf_chain *tcf_action_set_ctrlact(struct tc_action *a, int action,
 #endif /* CONFIG_NET_CLS_ACT */
 
 static inline void tcf_action_stats_update(struct tc_action *a, u64 bytes,
-                                          u64 packets, u64 lastuse, bool hw)
+                                          u64 packets, u64 drops,
+                                          u64 lastuse, bool hw)
 {
 #ifdef CONFIG_NET_CLS_ACT
        if (!a->ops->stats_update)
                return;
 
-       a->ops->stats_update(a, bytes, packets, lastuse, hw);
+       a->ops->stats_update(a, bytes, packets, drops, lastuse, hw);
 #endif
 }
 
index f2c8311a043353958b0876a031e210bc28654db9..00c15f14c4348ca9f3c9185d89688b3e6094ecdf 100644 (file)
@@ -389,17 +389,20 @@ static inline bool flow_rule_match_key(const struct flow_rule *rule,
 struct flow_stats {
        u64     pkts;
        u64     bytes;
+       u64     drops;
        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 drops, u64 lastused,
                                     enum flow_action_hw_stats used_hw_stats)
 {
        flow_stats->pkts        += pkts;
        flow_stats->bytes       += bytes;
+       flow_stats->drops       += drops;
        flow_stats->lastused    = max_t(u64, flow_stats->lastused, lastused);
 
        /* The driver should pass value with a maximum of one bit set.
index ed65619cbc47ae597ae4a500b28127d47fd834d3..ff017e5b3ea27a9342fc7d5625087926742ce900 100644 (file)
@@ -262,7 +262,7 @@ 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 drops, u64 lastuse,
                      u8 used_hw_stats, bool used_hw_stats_valid)
 {
 #ifdef CONFIG_NET_CLS_ACT
@@ -273,7 +273,8 @@ tcf_exts_stats_update(const struct tcf_exts *exts,
        for (i = 0; i < exts->nr_actions; i++) {
                struct tc_action *a = exts->actions[i];
 
-               tcf_action_stats_update(a, bytes, packets, lastuse, true);
+               tcf_action_stats_update(a, bytes, packets, drops,
+                                       lastuse, true);
                a->used_hw_stats = used_hw_stats;
                a->used_hw_stats_valid = used_hw_stats_valid;
        }
index 8ac7eb0a8309619e67dfcfbd7bd254e33230c59a..4c4466f18801db0c8d2928860668f30c01425735 100644 (file)
@@ -1059,14 +1059,13 @@ err:
        return err;
 }
 
-void tcf_action_update_stats(struct tc_action *a, u64 bytes, u32 packets,
-                            bool drop, bool hw)
+void tcf_action_update_stats(struct tc_action *a, u64 bytes, u64 packets,
+                            u64 drops, bool hw)
 {
        if (a->cpu_bstats) {
                _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats), bytes, packets);
 
-               if (drop)
-                       this_cpu_ptr(a->cpu_qstats)->drops += packets;
+               this_cpu_ptr(a->cpu_qstats)->drops += drops;
 
                if (hw)
                        _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats_hw),
@@ -1075,8 +1074,7 @@ void tcf_action_update_stats(struct tc_action *a, u64 bytes, u32 packets,
        }
 
        _bstats_update(&a->tcfa_bstats, bytes, packets);
-       if (drop)
-               a->tcfa_qstats.drops += packets;
+       a->tcfa_qstats.drops += drops;
        if (hw)
                _bstats_update(&a->tcfa_bstats_hw, bytes, packets);
 }
index e9f3576cbf71ab702209337259f2105921497714..1b9c6d4a1b6b0714b3d5a5692010fa3f34cca18d 100644 (file)
@@ -1450,12 +1450,12 @@ static int tcf_ct_search(struct net *net, struct tc_action **a, u32 index)
        return tcf_idr_search(tn, a, index);
 }
 
-static void tcf_stats_update(struct tc_action *a, u64 bytes, u32 packets,
-                            u64 lastuse, bool hw)
+static void tcf_stats_update(struct tc_action *a, u64 bytes, u64 packets,
+                            u64 drops, u64 lastuse, bool hw)
 {
        struct tcf_ct *c = to_ct(a);
 
-       tcf_action_update_stats(a, bytes, packets, false, hw);
+       tcf_action_update_stats(a, bytes, packets, drops, hw);
        c->tcf_tm.lastuse = max_t(u64, c->tcf_tm.lastuse, lastuse);
 }
 
index 41606577271968c7dd03ecd99f040bec63199297..410e3bbfb9ca3b1009d7c23e0edfb25200be1a70 100644 (file)
@@ -171,14 +171,15 @@ static int tcf_gact_act(struct sk_buff *skb, const struct tc_action *a,
        return action;
 }
 
-static void tcf_gact_stats_update(struct tc_action *a, u64 bytes, u32 packets,
-                                 u64 lastuse, bool hw)
+static void tcf_gact_stats_update(struct tc_action *a, u64 bytes, u64 packets,
+                                 u64 drops, u64 lastuse, bool hw)
 {
        struct tcf_gact *gact = to_gact(a);
        int action = READ_ONCE(gact->tcf_action);
        struct tcf_t *tm = &gact->tcf_tm;
 
-       tcf_action_update_stats(a, bytes, packets, action == TC_ACT_SHOT, hw);
+       tcf_action_update_stats(a, bytes, packets,
+                               action == TC_ACT_SHOT ? packets : drops, hw);
        tm->lastuse = max_t(u64, tm->lastuse, lastuse);
 }
 
index 9c628591f452c384a211a461dfec4638548835fd..c818844846b1b38567d37617a1d7f0e209e92167 100644 (file)
@@ -568,13 +568,13 @@ static int tcf_gate_walker(struct net *net, struct sk_buff *skb,
        return tcf_generic_walker(tn, skb, cb, type, ops, extack);
 }
 
-static void tcf_gate_stats_update(struct tc_action *a, u64 bytes, u32 packets,
-                                 u64 lastuse, bool hw)
+static void tcf_gate_stats_update(struct tc_action *a, u64 bytes, u64 packets,
+                                 u64 drops, u64 lastuse, bool hw)
 {
        struct tcf_gate *gact = to_gate(a);
        struct tcf_t *tm = &gact->tcf_tm;
 
-       tcf_action_update_stats(a, bytes, packets, false, hw);
+       tcf_action_update_stats(a, bytes, packets, drops, hw);
        tm->lastuse = max_t(u64, tm->lastuse, lastuse);
 }
 
index 83dd82fc9f40ce800b99eae5c0b279dce5b2c1c9..b2705318993b5f96c7ce8c5371ed87a0ff72ec4f 100644 (file)
@@ -312,13 +312,13 @@ out:
        return retval;
 }
 
-static void tcf_stats_update(struct tc_action *a, u64 bytes, u32 packets,
-                            u64 lastuse, bool hw)
+static void tcf_stats_update(struct tc_action *a, u64 bytes, u64 packets,
+                            u64 drops, u64 lastuse, bool hw)
 {
        struct tcf_mirred *m = to_mirred(a);
        struct tcf_t *tm = &m->tcf_tm;
 
-       tcf_action_update_stats(a, bytes, packets, false, hw);
+       tcf_action_update_stats(a, bytes, packets, drops, hw);
        tm->lastuse = max_t(u64, tm->lastuse, lastuse);
 }
 
index d41d6200d9deced1a2c4469c817f433fca0edefc..66986db062edae9cb545c600f1e9b6312dfc7cdb 100644 (file)
@@ -409,13 +409,13 @@ done:
        return p->tcf_action;
 }
 
-static void tcf_pedit_stats_update(struct tc_action *a, u64 bytes, u32 packets,
-                                  u64 lastuse, bool hw)
+static void tcf_pedit_stats_update(struct tc_action *a, u64 bytes, u64 packets,
+                                  u64 drops, u64 lastuse, bool hw)
 {
        struct tcf_pedit *d = to_pedit(a);
        struct tcf_t *tm = &d->tcf_tm;
 
-       tcf_action_update_stats(a, bytes, packets, false, hw);
+       tcf_action_update_stats(a, bytes, packets, drops, hw);
        tm->lastuse = max_t(u64, tm->lastuse, lastuse);
 }
 
index 8b7a0ac96c5169e833c6f87898c6503a49c726af..0b431d493768614625866fd383dcf59058fa8bbc 100644 (file)
@@ -288,13 +288,13 @@ static void tcf_police_cleanup(struct tc_action *a)
 }
 
 static void tcf_police_stats_update(struct tc_action *a,
-                                   u64 bytes, u32 packets,
+                                   u64 bytes, u64 packets, u64 drops,
                                    u64 lastuse, bool hw)
 {
        struct tcf_police *police = to_police(a);
        struct tcf_t *tm = &police->tcf_tm;
 
-       tcf_action_update_stats(a, bytes, packets, false, hw);
+       tcf_action_update_stats(a, bytes, packets, drops, hw);
        tm->lastuse = max_t(u64, tm->lastuse, lastuse);
 }
 
index b125b2be4467a46c57208c21385a41bf722f6fc4..361b863e06344705254725c291438f00259f51d7 100644 (file)
@@ -74,12 +74,13 @@ err:
 }
 
 static void tcf_skbedit_stats_update(struct tc_action *a, u64 bytes,
-                                    u32 packets, u64 lastuse, bool hw)
+                                    u64 packets, u64 drops,
+                                    u64 lastuse, bool hw)
 {
        struct tcf_skbedit *d = to_skbedit(a);
        struct tcf_t *tm = &d->tcf_tm;
 
-       tcf_action_update_stats(a, bytes, packets, false, hw);
+       tcf_action_update_stats(a, bytes, packets, drops, hw);
        tm->lastuse = max_t(u64, tm->lastuse, lastuse);
 }
 
index c91d3958fcbb806ed05af62a140892fdf8ec726f..a5ff9f68ab023a4a3cba5ef25c43fe695ef1eee6 100644 (file)
@@ -302,13 +302,13 @@ static int tcf_vlan_walker(struct net *net, struct sk_buff *skb,
        return tcf_generic_walker(tn, skb, cb, type, ops, extack);
 }
 
-static void tcf_vlan_stats_update(struct tc_action *a, u64 bytes, u32 packets,
-                                 u64 lastuse, bool hw)
+static void tcf_vlan_stats_update(struct tc_action *a, u64 bytes, u64 packets,
+                                 u64 drops, u64 lastuse, bool hw)
 {
        struct tcf_vlan *v = to_vlan(a);
        struct tcf_t *tm = &v->tcf_tm;
 
-       tcf_action_update_stats(a, bytes, packets, false, hw);
+       tcf_action_update_stats(a, bytes, packets, drops, hw);
        tm->lastuse = max_t(u64, tm->lastuse, lastuse);
 }
 
index b2da3728608225a05e40c8a8c1d48964aa944056..391971672d545d5d84ce63b41679127fe22ec8b4 100644 (file)
@@ -491,6 +491,7 @@ 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.drops,
                              cls_flower.stats.lastused,
                              cls_flower.stats.used_hw_stats,
                              cls_flower.stats.used_hw_stats_valid);
index 8d39dbcf17466eafc031cd9b6f3f0c6cda596819..cafb84480bab8c431ee4dba2bbddbdf701042836 100644 (file)
@@ -338,7 +338,8 @@ 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.drops,
+                             cls_mall.stats.lastused,
                              cls_mall.stats.used_hw_stats,
                              cls_mall.stats.used_hw_stats_valid);
 }