diff options
-rw-r--r-- | lib/netdev-offload-tc.c | 10 | ||||
-rw-r--r-- | lib/tc.c | 34 | ||||
-rw-r--r-- | lib/tc.h | 3 |
3 files changed, 35 insertions, 12 deletions
diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c index 9845e8d3f..3f7068c8e 100644 --- a/lib/netdev-offload-tc.c +++ b/lib/netdev-offload-tc.c @@ -585,8 +585,10 @@ parse_tc_flower_to_stats(struct tc_flower *flower, } memset(stats, 0, sizeof *stats); - stats->n_packets = get_32aligned_u64(&flower->stats.n_packets); - stats->n_bytes = get_32aligned_u64(&flower->stats.n_bytes); + stats->n_packets = get_32aligned_u64(&flower->stats_sw.n_packets); + stats->n_packets += get_32aligned_u64(&flower->stats_hw.n_packets); + stats->n_bytes = get_32aligned_u64(&flower->stats_sw.n_bytes); + stats->n_bytes += get_32aligned_u64(&flower->stats_hw.n_bytes); stats->used = flower->lastused; } @@ -2015,9 +2017,7 @@ netdev_tc_flow_del(struct netdev *netdev OVS_UNUSED, if (stats) { memset(stats, 0, sizeof *stats); if (!tc_get_flower(&id, &flower)) { - stats->n_packets = get_32aligned_u64(&flower.stats.n_packets); - stats->n_bytes = get_32aligned_u64(&flower.stats.n_bytes); - stats->used = flower.lastused; + parse_tc_flower_to_stats(&flower, stats); } } @@ -1702,6 +1702,9 @@ static const struct nl_policy stats_policy[] = { [TCA_STATS_BASIC] = { .type = NL_A_UNSPEC, .min_len = sizeof(struct gnet_stats_basic), .optional = false, }, + [TCA_STATS_BASIC_HW] = { .type = NL_A_UNSPEC, + .min_len = sizeof(struct gnet_stats_basic), + .optional = true, }, }; static int @@ -1714,8 +1717,11 @@ nl_parse_single_action(struct nlattr *action, struct tc_flower *flower, const char *act_kind; struct nlattr *action_attrs[ARRAY_SIZE(act_policy)]; struct nlattr *stats_attrs[ARRAY_SIZE(stats_policy)]; - struct ovs_flow_stats *stats = &flower->stats; - const struct gnet_stats_basic *bs; + struct ovs_flow_stats *stats_sw = &flower->stats_sw; + struct ovs_flow_stats *stats_hw = &flower->stats_hw; + const struct gnet_stats_basic *bs_all = NULL; + const struct gnet_stats_basic *bs_hw = NULL; + struct gnet_stats_basic bs_sw = { .packets = 0, .bytes = 0, }; int err = 0; if (!nl_parse_nested(action, act_policy, action_attrs, @@ -1771,10 +1777,26 @@ nl_parse_single_action(struct nlattr *action, struct tc_flower *flower, return EPROTO; } - bs = nl_attr_get_unspec(stats_attrs[TCA_STATS_BASIC], sizeof *bs); - if (bs->packets) { - put_32aligned_u64(&stats->n_packets, bs->packets); - put_32aligned_u64(&stats->n_bytes, bs->bytes); + bs_all = nl_attr_get_unspec(stats_attrs[TCA_STATS_BASIC], sizeof *bs_all); + if (stats_attrs[TCA_STATS_BASIC_HW]) { + bs_hw = nl_attr_get_unspec(stats_attrs[TCA_STATS_BASIC_HW], + sizeof *bs_hw); + + bs_sw.packets = bs_all->packets - bs_hw->packets; + bs_sw.bytes = bs_all->bytes - bs_hw->bytes; + } else { + bs_sw.packets = bs_all->packets; + bs_sw.bytes = bs_all->bytes; + } + + if (bs_sw.packets > get_32aligned_u64(&stats_sw->n_packets)) { + put_32aligned_u64(&stats_sw->n_packets, bs_sw.packets); + put_32aligned_u64(&stats_sw->n_bytes, bs_sw.bytes); + } + + if (bs_hw && bs_hw->packets > get_32aligned_u64(&stats_hw->n_packets)) { + put_32aligned_u64(&stats_hw->n_packets, bs_hw->packets); + put_32aligned_u64(&stats_hw->n_bytes, bs_hw->bytes); } return 0; @@ -330,7 +330,8 @@ struct tc_flower { int action_count; struct tc_action actions[TCA_ACT_MAX_NUM]; - struct ovs_flow_stats stats; + struct ovs_flow_stats stats_sw; + struct ovs_flow_stats stats_hw; uint64_t lastused; struct { |