openvswitch: collect mega flow mask stats
Collect mega flow mask stats. ovs-dpctl show command can be used to display them for debugging and performance tuning. Signed-off-by: Andy Zhou <azhou@nicira.com> Signed-off-by: Jesse Gross <jesse@nicira.com>
This commit is contained in:
@ -221,6 +221,7 @@ void ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb)
|
||||
struct dp_stats_percpu *stats;
|
||||
struct sw_flow_key key;
|
||||
u64 *stats_counter;
|
||||
u32 n_mask_hit;
|
||||
int error;
|
||||
|
||||
stats = this_cpu_ptr(dp->stats_percpu);
|
||||
@ -233,7 +234,7 @@ void ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb)
|
||||
}
|
||||
|
||||
/* Look up flow. */
|
||||
flow = ovs_flow_tbl_lookup(&dp->table, &key);
|
||||
flow = ovs_flow_tbl_lookup(&dp->table, &key, &n_mask_hit);
|
||||
if (unlikely(!flow)) {
|
||||
struct dp_upcall_info upcall;
|
||||
|
||||
@ -258,6 +259,7 @@ out:
|
||||
/* Update datapath statistics. */
|
||||
u64_stats_update_begin(&stats->sync);
|
||||
(*stats_counter)++;
|
||||
stats->n_mask_hit += n_mask_hit;
|
||||
u64_stats_update_end(&stats->sync);
|
||||
}
|
||||
|
||||
@ -563,13 +565,18 @@ static struct genl_ops dp_packet_genl_ops[] = {
|
||||
}
|
||||
};
|
||||
|
||||
static void get_dp_stats(struct datapath *dp, struct ovs_dp_stats *stats)
|
||||
static void get_dp_stats(struct datapath *dp, struct ovs_dp_stats *stats,
|
||||
struct ovs_dp_megaflow_stats *mega_stats)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset(mega_stats, 0, sizeof(*mega_stats));
|
||||
|
||||
stats->n_flows = ovs_flow_tbl_count(&dp->table);
|
||||
mega_stats->n_masks = ovs_flow_tbl_num_masks(&dp->table);
|
||||
|
||||
stats->n_hit = stats->n_missed = stats->n_lost = 0;
|
||||
|
||||
for_each_possible_cpu(i) {
|
||||
const struct dp_stats_percpu *percpu_stats;
|
||||
struct dp_stats_percpu local_stats;
|
||||
@ -585,6 +592,7 @@ static void get_dp_stats(struct datapath *dp, struct ovs_dp_stats *stats)
|
||||
stats->n_hit += local_stats.n_hit;
|
||||
stats->n_missed += local_stats.n_missed;
|
||||
stats->n_lost += local_stats.n_lost;
|
||||
mega_stats->n_mask_hit += local_stats.n_mask_hit;
|
||||
}
|
||||
}
|
||||
|
||||
@ -743,6 +751,14 @@ static struct sk_buff *ovs_flow_cmd_build_info(struct sw_flow *flow,
|
||||
return skb;
|
||||
}
|
||||
|
||||
static struct sw_flow *__ovs_flow_tbl_lookup(struct flow_table *tbl,
|
||||
const struct sw_flow_key *key)
|
||||
{
|
||||
u32 __always_unused n_mask_hit;
|
||||
|
||||
return ovs_flow_tbl_lookup(tbl, key, &n_mask_hit);
|
||||
}
|
||||
|
||||
static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct nlattr **a = info->attrs;
|
||||
@ -793,7 +809,7 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
|
||||
goto err_unlock_ovs;
|
||||
|
||||
/* Check if this is a duplicate flow */
|
||||
flow = ovs_flow_tbl_lookup(&dp->table, &key);
|
||||
flow = __ovs_flow_tbl_lookup(&dp->table, &key);
|
||||
if (!flow) {
|
||||
/* Bail out if we're not allowed to create a new flow. */
|
||||
error = -ENOENT;
|
||||
@ -905,7 +921,7 @@ static int ovs_flow_cmd_get(struct sk_buff *skb, struct genl_info *info)
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
flow = ovs_flow_tbl_lookup(&dp->table, &key);
|
||||
flow = __ovs_flow_tbl_lookup(&dp->table, &key);
|
||||
if (!flow || !ovs_flow_cmp_unmasked_key(flow, &match)) {
|
||||
err = -ENOENT;
|
||||
goto unlock;
|
||||
@ -953,7 +969,7 @@ static int ovs_flow_cmd_del(struct sk_buff *skb, struct genl_info *info)
|
||||
if (err)
|
||||
goto unlock;
|
||||
|
||||
flow = ovs_flow_tbl_lookup(&dp->table, &key);
|
||||
flow = __ovs_flow_tbl_lookup(&dp->table, &key);
|
||||
if (!flow || !ovs_flow_cmp_unmasked_key(flow, &match)) {
|
||||
err = -ENOENT;
|
||||
goto unlock;
|
||||
@ -1067,6 +1083,7 @@ static size_t ovs_dp_cmd_msg_size(void)
|
||||
|
||||
msgsize += nla_total_size(IFNAMSIZ);
|
||||
msgsize += nla_total_size(sizeof(struct ovs_dp_stats));
|
||||
msgsize += nla_total_size(sizeof(struct ovs_dp_megaflow_stats));
|
||||
|
||||
return msgsize;
|
||||
}
|
||||
@ -1076,6 +1093,7 @@ static int ovs_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb,
|
||||
{
|
||||
struct ovs_header *ovs_header;
|
||||
struct ovs_dp_stats dp_stats;
|
||||
struct ovs_dp_megaflow_stats dp_megaflow_stats;
|
||||
int err;
|
||||
|
||||
ovs_header = genlmsg_put(skb, portid, seq, &dp_datapath_genl_family,
|
||||
@ -1091,8 +1109,14 @@ static int ovs_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb,
|
||||
if (err)
|
||||
goto nla_put_failure;
|
||||
|
||||
get_dp_stats(dp, &dp_stats);
|
||||
if (nla_put(skb, OVS_DP_ATTR_STATS, sizeof(struct ovs_dp_stats), &dp_stats))
|
||||
get_dp_stats(dp, &dp_stats, &dp_megaflow_stats);
|
||||
if (nla_put(skb, OVS_DP_ATTR_STATS, sizeof(struct ovs_dp_stats),
|
||||
&dp_stats))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (nla_put(skb, OVS_DP_ATTR_MEGAFLOW_STATS,
|
||||
sizeof(struct ovs_dp_megaflow_stats),
|
||||
&dp_megaflow_stats))
|
||||
goto nla_put_failure;
|
||||
|
||||
return genlmsg_end(skb, ovs_header);
|
||||
|
Reference in New Issue
Block a user