summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/netdev-offload-tc.c10
-rw-r--r--lib/tc.c34
-rw-r--r--lib/tc.h3
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);
}
}
diff --git a/lib/tc.c b/lib/tc.c
index adb2d3182..a52cd46d9 100644
--- a/lib/tc.c
+++ b/lib/tc.c
@@ -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;
diff --git a/lib/tc.h b/lib/tc.h
index a147ca461..fb0534a08 100644
--- a/lib/tc.h
+++ b/lib/tc.h
@@ -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 {