Skip to content

Commit

Permalink
Add offload packets statistics
Browse files Browse the repository at this point in the history
Add argument '--offload-stats' for command ovs-appctl bridge/dump-flows
to display the offloaded packets statistics.

The commands display as below:

orignal command:

ovs-appctl bridge/dump-flows br0

duration=574s, n_packets=1152, n_bytes=110768, priority=0,actions=NORMAL
table_id=254, duration=574s, n_packets=0, n_bytes=0, priority=2,recirc_id=0,actions=drop
table_id=254, duration=574s, n_packets=0, n_bytes=0, priority=0,reg0=0x1,actions=controller(reason=)
table_id=254, duration=574s, n_packets=0, n_bytes=0, priority=0,reg0=0x2,actions=drop
table_id=254, duration=574s, n_packets=0, n_bytes=0, priority=0,reg0=0x3,actions=drop

new command with argument '--offload-stats'

Notice: 'n_offload_packets' are a subset of n_packets and 'n_offload_bytes' are
a subset of n_bytes.

ovs-appctl bridge/dump-flows --offload-stats br0

duration=582s, n_packets=1152, n_bytes=110768, n_offload_packets=1107, n_offload_bytes=107992, priority=0,actions=NORMAL
table_id=254, duration=582s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=2,recirc_id=0,actions=drop
table_id=254, duration=582s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x1,actions=controller(reason=)
table_id=254, duration=582s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x2,actions=drop
table_id=254, duration=582s, n_packets=0, n_bytes=0, n_offload_packets=0, n_offload_bytes=0, priority=0,reg0=0x3,actions=drop

Signed-off-by: zhaozhanxu <[email protected]>
Signed-off-by: Simon Horman <[email protected]>
  • Loading branch information
zhaozhanxu authored and shorman-netronome committed Dec 6, 2019
1 parent 3843208 commit 1644131
Show file tree
Hide file tree
Showing 14 changed files with 112 additions and 62 deletions.
3 changes: 3 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ v2.12.0 - 03 Sep 2019
* Add support for conntrack zone-based timeout policy.
- 'ovs-dpctl dump-flows' is no longer suitable for dumping offloaded flows.
'ovs-appctl dpctl/dump-flows' should be used instead.
- Add new argument '--offload-stats' for command
'ovs-appctl bridge/dump-flows',
so it can display offloaded packets statistics.
- Add L2 GRE tunnel over IPv6 support.

v2.11.0 - 19 Feb 2019
Expand Down
12 changes: 12 additions & 0 deletions lib/dpif.h
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,18 @@ struct dpif_flow_stats {
uint16_t tcp_flags;
};

/* more statistics info for offloaded packets and bytes */
struct dpif_flow_detailed_stats {
uint64_t n_packets;
uint64_t n_bytes;
/* n_offload_packets are a subset of n_packets */
uint64_t n_offload_packets;
/* n_offload_bytes are a subset of n_bytes */
uint64_t n_offload_bytes;
long long int used;
uint16_t tcp_flags;
};

struct dpif_flow_attrs {
bool offloaded; /* True if flow is offloaded to HW. */
const char *dp_layer; /* DP layer the flow is handled in. */
Expand Down
7 changes: 3 additions & 4 deletions ofproto/bond.c
Original file line number Diff line number Diff line change
Expand Up @@ -950,13 +950,12 @@ bond_recirculation_account(struct bond *bond)
struct rule *rule = entry->pr_rule;

if (rule) {
uint64_t n_packets OVS_UNUSED;
struct pkt_stats stats;
long long int used OVS_UNUSED;
uint64_t n_bytes;

rule->ofproto->ofproto_class->rule_get_stats(
rule, &n_packets, &n_bytes, &used);
bond_entry_account(entry, n_bytes);
rule, &stats, &used);
bond_entry_account(entry, stats.n_bytes);
}
}
}
Expand Down
11 changes: 6 additions & 5 deletions ofproto/ofproto-dpif-upcall.c
Original file line number Diff line number Diff line change
Expand Up @@ -2264,7 +2264,7 @@ static enum reval_result
revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey,
const struct dpif_flow_stats *stats,
struct ofpbuf *odp_actions, uint64_t reval_seq,
struct recirc_refs *recircs)
struct recirc_refs *recircs, bool offloaded)
OVS_REQUIRES(ukey->mutex)
{
bool need_revalidate = ukey->reval_seq != reval_seq;
Expand Down Expand Up @@ -2299,7 +2299,7 @@ revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey,

/* Stats for deleted flows will be attributed upon flow deletion. Skip. */
if (result != UKEY_DELETE) {
xlate_push_stats(ukey->xcache, &push);
xlate_push_stats(ukey->xcache, &push, offloaded);
ukey->stats = *stats;
ukey->reval_seq = reval_seq;
}
Expand Down Expand Up @@ -2412,7 +2412,7 @@ push_dp_ops(struct udpif *udpif, struct ukey_op *ops, size_t n_ops)
if (op->ukey) {
ovs_mutex_lock(&op->ukey->mutex);
if (op->ukey->xcache) {
xlate_push_stats(op->ukey->xcache, push);
xlate_push_stats(op->ukey->xcache, push, false);
ovs_mutex_unlock(&op->ukey->mutex);
continue;
}
Expand Down Expand Up @@ -2689,7 +2689,8 @@ revalidate(struct revalidator *revalidator)
result = UKEY_DELETE;
} else {
result = revalidate_ukey(udpif, ukey, &f->stats, &odp_actions,
reval_seq, &recircs);
reval_seq, &recircs,
f->attrs.offloaded);
}
ukey->dump_seq = dump_seq;

Expand Down Expand Up @@ -2774,7 +2775,7 @@ revalidator_sweep__(struct revalidator *revalidator, bool purge)
COVERAGE_INC(revalidate_missed_dp_flow);
memset(&stats, 0, sizeof stats);
result = revalidate_ukey(udpif, ukey, &stats, &odp_actions,
reval_seq, &recircs);
reval_seq, &recircs, false);
}
if (result != UKEY_KEEP) {
/* Clears 'recircs' if filled by revalidate_ukey(). */
Expand Down
8 changes: 4 additions & 4 deletions ofproto/ofproto-dpif-xlate-cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ xlate_cache_netdev(struct xc_entry *entry, const struct dpif_flow_stats *stats)
/* Push stats and perform side effects of flow translation. */
void
xlate_push_stats_entry(struct xc_entry *entry,
struct dpif_flow_stats *stats)
struct dpif_flow_stats *stats, bool offloaded)
{
struct eth_addr dmac;

Expand All @@ -104,7 +104,7 @@ xlate_push_stats_entry(struct xc_entry *entry,
? 0 : stats->n_packets);
break;
case XC_RULE:
rule_dpif_credit_stats(entry->rule, stats);
rule_dpif_credit_stats(entry->rule, stats, offloaded);
break;
case XC_BOND:
bond_account(entry->bond.bond, entry->bond.flow,
Expand Down Expand Up @@ -169,7 +169,7 @@ xlate_push_stats_entry(struct xc_entry *entry,

void
xlate_push_stats(struct xlate_cache *xcache,
struct dpif_flow_stats *stats)
struct dpif_flow_stats *stats, bool offloaded)
{
if (!stats->n_packets) {
return;
Expand All @@ -178,7 +178,7 @@ xlate_push_stats(struct xlate_cache *xcache,
struct xc_entry *entry;
struct ofpbuf entries = xcache->entries;
XC_ENTRY_FOR_EACH (entry, &entries) {
xlate_push_stats_entry(entry, stats);
xlate_push_stats_entry(entry, stats, offloaded);
}
}

Expand Down
6 changes: 4 additions & 2 deletions ofproto/ofproto-dpif-xlate-cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,10 @@ struct xlate_cache {
void xlate_cache_init(struct xlate_cache *);
struct xlate_cache *xlate_cache_new(void);
struct xc_entry *xlate_cache_add_entry(struct xlate_cache *, enum xc_type);
void xlate_push_stats_entry(struct xc_entry *, struct dpif_flow_stats *);
void xlate_push_stats(struct xlate_cache *, struct dpif_flow_stats *);
void xlate_push_stats_entry(struct xc_entry *, struct dpif_flow_stats *,
bool);
void xlate_push_stats(struct xlate_cache *, struct dpif_flow_stats *,
bool);
void xlate_cache_clear_entry(struct xc_entry *);
void xlate_cache_clear(struct xlate_cache *);
void xlate_cache_uninit(struct xlate_cache *);
Expand Down
6 changes: 3 additions & 3 deletions ofproto/ofproto-dpif-xlate.c
Original file line number Diff line number Diff line change
Expand Up @@ -3704,7 +3704,7 @@ native_tunnel_output(struct xlate_ctx *ctx, const struct xport *xport,
*/
if (backup_resubmit_stats) {
struct dpif_flow_stats stats = *backup_resubmit_stats;
xlate_push_stats(ctx->xin->xcache, &stats);
xlate_push_stats(ctx->xin->xcache, &stats, false);
}
xlate_cache_steal_entries(backup_xcache, ctx->xin->xcache);

Expand Down Expand Up @@ -4270,7 +4270,7 @@ xlate_recursively(struct xlate_ctx *ctx, struct rule_dpif *rule,
const struct rule_actions *actions;

if (ctx->xin->resubmit_stats) {
rule_dpif_credit_stats(rule, ctx->xin->resubmit_stats);
rule_dpif_credit_stats(rule, ctx->xin->resubmit_stats, false);
}

ctx->resubmits++;
Expand Down Expand Up @@ -7597,7 +7597,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)
ctx.xin->resubmit_stats, &ctx.table_id,
flow->in_port.ofp_port, true, true, ctx.xin->xcache);
if (ctx.xin->resubmit_stats) {
rule_dpif_credit_stats(ctx.rule, ctx.xin->resubmit_stats);
rule_dpif_credit_stats(ctx.rule, ctx.xin->resubmit_stats, false);
}
if (ctx.xin->xcache) {
struct xc_entry *entry;
Expand Down
29 changes: 18 additions & 11 deletions ofproto/ofproto-dpif.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ COVERAGE_DEFINE(packet_in_overflow);

struct flow_miss;

static void rule_get_stats(struct rule *, uint64_t *packets, uint64_t *bytes,
static void rule_get_stats(struct rule *, struct pkt_stats *stats,
long long int *used);
static struct rule_dpif *rule_dpif_cast(const struct rule *);
static void rule_expire(struct rule_dpif *, long long now);
Expand Down Expand Up @@ -4168,7 +4168,7 @@ ofproto_dpif_execute_actions__(struct ofproto_dpif *ofproto,
dpif_flow_stats_extract(flow, packet, time_msec(), &stats);

if (rule) {
rule_dpif_credit_stats(rule, &stats);
rule_dpif_credit_stats(rule, &stats, false);
}

uint64_t odp_actions_stub[1024 / 8];
Expand Down Expand Up @@ -4222,10 +4222,14 @@ ofproto_dpif_execute_actions(struct ofproto_dpif *ofproto,
static void
rule_dpif_credit_stats__(struct rule_dpif *rule,
const struct dpif_flow_stats *stats,
bool credit_counts)
bool credit_counts, bool offloaded)
OVS_REQUIRES(rule->stats_mutex)
{
if (credit_counts) {
if (offloaded) {
rule->stats.n_offload_packets += stats->n_packets;
rule->stats.n_offload_bytes += stats->n_bytes;
}
rule->stats.n_packets += stats->n_packets;
rule->stats.n_bytes += stats->n_bytes;
}
Expand All @@ -4234,15 +4238,16 @@ rule_dpif_credit_stats__(struct rule_dpif *rule,

void
rule_dpif_credit_stats(struct rule_dpif *rule,
const struct dpif_flow_stats *stats)
const struct dpif_flow_stats *stats, bool offloaded)
{
ovs_mutex_lock(&rule->stats_mutex);
if (OVS_UNLIKELY(rule->new_rule)) {
ovs_mutex_lock(&rule->new_rule->stats_mutex);
rule_dpif_credit_stats__(rule->new_rule, stats, rule->forward_counts);
rule_dpif_credit_stats__(rule->new_rule, stats, rule->forward_counts,
offloaded);
ovs_mutex_unlock(&rule->new_rule->stats_mutex);
} else {
rule_dpif_credit_stats__(rule, stats, true);
rule_dpif_credit_stats__(rule, stats, true, offloaded);
}
ovs_mutex_unlock(&rule->stats_mutex);
}
Expand Down Expand Up @@ -4701,17 +4706,19 @@ rule_destruct(struct rule *rule_)
}

static void
rule_get_stats(struct rule *rule_, uint64_t *packets, uint64_t *bytes,
rule_get_stats(struct rule *rule_, struct pkt_stats *stats,
long long int *used)
{
struct rule_dpif *rule = rule_dpif_cast(rule_);

ovs_mutex_lock(&rule->stats_mutex);
if (OVS_UNLIKELY(rule->new_rule)) {
rule_get_stats(&rule->new_rule->up, packets, bytes, used);
rule_get_stats(&rule->new_rule->up, stats, used);
} else {
*packets = rule->stats.n_packets;
*bytes = rule->stats.n_bytes;
stats->n_packets = rule->stats.n_packets;
stats->n_bytes = rule->stats.n_bytes;
stats->n_offload_packets = rule->stats.n_offload_packets;
stats->n_offload_bytes = rule->stats.n_offload_bytes;
*used = rule->stats.used;
}
ovs_mutex_unlock(&rule->stats_mutex);
Expand Down Expand Up @@ -4875,7 +4882,7 @@ ofproto_dpif_xcache_execute(struct ofproto_dpif *ofproto,
case XC_GROUP:
case XC_TNL_NEIGH:
case XC_TUNNEL_HEADER:
xlate_push_stats_entry(entry, stats);
xlate_push_stats_entry(entry, stats, false);
break;
default:
OVS_NOT_REACHED();
Expand Down
4 changes: 2 additions & 2 deletions ofproto/ofproto-dpif.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ struct rule_dpif {
* - Do include packets and bytes from datapath flows which have not
* recently been processed by a revalidator. */
struct ovs_mutex stats_mutex;
struct dpif_flow_stats stats OVS_GUARDED;
struct dpif_flow_detailed_stats stats OVS_GUARDED;

/* In non-NULL, will point to a new rule (for which a reference is held) to
* which all the stats updates should be forwarded. This exists only
Expand Down Expand Up @@ -107,7 +107,7 @@ struct rule_dpif *rule_dpif_lookup_from_table(struct ofproto_dpif *,
struct xlate_cache *);

void rule_dpif_credit_stats(struct rule_dpif *,
const struct dpif_flow_stats *);
const struct dpif_flow_stats *, bool);

void rule_set_recirc_id(struct rule *, uint32_t id);

Expand Down
11 changes: 9 additions & 2 deletions ofproto/ofproto-provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,13 @@ struct ofgroup {
struct rule_collection rules OVS_GUARDED; /* Referring rules. */
};

struct pkt_stats {
uint64_t n_packets;
uint64_t n_bytes;
uint64_t n_offload_packets; /* n_offload_packets are a subset n_packets */
uint64_t n_offload_bytes; /* n_offload_bytes are a subset of n_bytes */
};

struct ofgroup *ofproto_group_lookup(const struct ofproto *ofproto,
uint32_t group_id, ovs_version_t version,
bool take_ref);
Expand Down Expand Up @@ -1348,8 +1355,8 @@ struct ofproto_class {
* matched it in '*packet_count' and the number of bytes in those packets
* in '*byte_count'. UINT64_MAX indicates that the packet count or byte
* count is unknown. */
void (*rule_get_stats)(struct rule *rule, uint64_t *packet_count,
uint64_t *byte_count, long long int *used)
void (*rule_get_stats)(struct rule *rule, struct pkt_stats *stats,
long long int *used)
/* OVS_EXCLUDED(ofproto_mutex) */;

/* Translates actions in 'opo->ofpacts', for 'opo->packet' in flow tables
Expand Down
Loading

0 comments on commit 1644131

Please sign in to comment.