[ovs-dev] [patch_v5 2/3] dpif-netdev: Refactor some pmd stats.

Darrell Ball dlu998 at gmail.com
Mon Aug 21 18:51:40 UTC 2017


A few improvements are made:

1. The cycles per packet counts are now based on packets
received rather than packet passes through the datapath.

2. Packet counters are now kept for packets received and
packets recirculated. These are kept as separate counters for
maintainability reasons. The cost of incrementing these counters
is negligible.  These new counters are also displayed to the user.

3. A display statistic is added for the average number of
datapath passes per packet. This should be useful for user
debugging and understanding of packet processing.

4. The user visible 'miss' counter is used for successful upcalls,
rather than the sum of sucessful and unsuccessful upcalls. Hence,
this becomes what user historically understands by OVS 'miss upcall'.
The user display is annotated to make this clear as well.

5. The user visible 'lost' counter remains as failed upcalls, but
is annotated to make it clear what the meaning is.

6. The enum dp_stat_type is annotated to make the usage of the
stats counters clear.

7. The subtable lookup stats is renamed to make it clear that it
relates to masked lookups.

8. The PMD stats test is updated to handle the new user stats of
packets received, packets recirculated and average number of datapath
passes per packet.

Signed-off-by: Darrell Ball <dlu998 at gmail.com>
---
 lib/dpif-netdev.c | 82 ++++++++++++++++++++++++++++++++++---------------------
 tests/pmd.at      | 22 +++++++++------
 2 files changed, 65 insertions(+), 39 deletions(-)

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index 17e1666..a91ff69 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -323,12 +323,21 @@ static struct dp_netdev_port *dp_netdev_lookup_port(const struct dp_netdev *dp,
     OVS_REQUIRES(dp->port_mutex);
 
 enum dp_stat_type {
-    DP_STAT_EXACT_HIT,          /* Packets that had an exact match (emc). */
-    DP_STAT_MASKED_HIT,         /* Packets that matched in the flow table. */
-    DP_STAT_MISS,               /* Packets that did not match. */
-    DP_STAT_LOST,               /* Packets not passed up to the client. */
-    DP_STAT_LOOKUP_HIT,         /* Number of subtable lookups for flow table
-                                   hits */
+    DP_STAT_EXACT_HIT,     /* Packets that had an exact match (emc). */
+    DP_STAT_MASKED_HIT,    /* Packets that matched in the flow table. */
+    DP_STAT_MISS,          /* Packets that did not match and upcall was ok. */
+    DP_STAT_LOST,          /* Packets that did not match and upcall failed. */
+                           /* The above statistics account for the total
+                            * number of packet passes through the datapath
+                            * pipeline and should not be overlapping with each
+                            * other. */
+    DP_STAT_MASKED_LOOKUP, /* Number of subtable lookups for flow table
+                              hits. Each MASKED_HIT hit will have >= 1
+                              MASKED_LOOKUP(s). */
+    DP_STAT_RECV,          /* Packets entering the datapath pipeline from an
+                            * interface. */
+    DP_STAT_RECIRC,        /* Packets reentering the datapath pipeline due to
+                            * recirculation. */
     DP_N_STATS
 };
 
@@ -755,7 +764,6 @@ pmd_info_show_stats(struct ds *reply,
                     unsigned long long stats[DP_N_STATS],
                     uint64_t cycles[PMD_N_CYCLES])
 {
-    unsigned long long total_packets;
     uint64_t total_cycles = 0;
     int i;
 
@@ -773,10 +781,6 @@ pmd_info_show_stats(struct ds *reply,
         }
     }
 
-    /* Sum of all the matched and not matched packets gives the total.  */
-    total_packets = stats[DP_STAT_EXACT_HIT] + stats[DP_STAT_MASKED_HIT]
-                    + stats[DP_STAT_MISS];
-
     for (i = 0; i < PMD_N_CYCLES; i++) {
         if (cycles[i] > pmd->cycles_zero[i]) {
            cycles[i] -= pmd->cycles_zero[i];
@@ -799,14 +803,21 @@ pmd_info_show_stats(struct ds *reply,
     ds_put_cstr(reply, ":\n");
 
     ds_put_format(reply,
+                  "\tpackets received:%llu\n\tpacket recirculations:%llu\n"
+                  "\tavg. datapath passes per packet:%.2f\n"
                   "\temc hits:%llu\n\tmegaflow hits:%llu\n"
-                  "\tavg. subtable lookups per hit:%.2f\n"
-                  "\tmiss:%llu\n\tlost:%llu\n",
+                  "\tavg. subtable lookups per megaflow hit:%.2f\n"
+                  "\tmiss(i.e. lookup miss with success upcall):%llu\n"
+                  "\tlost(i.e. lookup miss with failed upcall):%llu\n",
+                  stats[DP_STAT_RECV], stats[DP_STAT_RECIRC],
+                  stats[DP_STAT_RECV] > 0
+                  ? (1.0 * (stats[DP_STAT_RECV] + stats[DP_STAT_RECIRC]))
+                     / stats[DP_STAT_RECV] : 0,
                   stats[DP_STAT_EXACT_HIT], stats[DP_STAT_MASKED_HIT],
                   stats[DP_STAT_MASKED_HIT] > 0
-                  ? (1.0*stats[DP_STAT_LOOKUP_HIT])/stats[DP_STAT_MASKED_HIT]
-                  : 0,
-                  stats[DP_STAT_MISS], stats[DP_STAT_LOST]);
+                  ? (1.0 * stats[DP_STAT_MASKED_LOOKUP])
+                     / stats[DP_STAT_MASKED_HIT]
+                  : 0, stats[DP_STAT_MISS], stats[DP_STAT_LOST]);
 
     if (total_cycles == 0) {
         return;
@@ -820,6 +831,7 @@ pmd_info_show_stats(struct ds *reply,
                   cycles[PMD_CYCLES_PROCESSING],
                   cycles[PMD_CYCLES_PROCESSING] / (double)total_cycles * 100);
 
+    unsigned long long total_packets = stats[DP_STAT_RECV];
     if (total_packets == 0) {
         return;
     }
@@ -4677,6 +4689,9 @@ emc_processing(struct dp_netdev_pmd_thread *pmd,
     uint32_t cur_min;
     int i;
 
+    dp_netdev_count_packet(pmd, md_is_valid ? DP_STAT_RECIRC : DP_STAT_RECV,
+                           size);
+
     atomic_read_relaxed(&pmd->dp->emc_insert_min, &cur_min);
 
     DP_PACKET_BATCH_REFILL_FOR_EACH (i, size, packet, packets_) {
@@ -4724,18 +4739,18 @@ emc_processing(struct dp_netdev_pmd_thread *pmd,
     return dp_packet_batch_size(packets_);
 }
 
-static inline void
+static inline int
 handle_packet_upcall(struct dp_netdev_pmd_thread *pmd,
                      struct dp_packet *packet,
                      const struct netdev_flow_key *key,
                      struct ofpbuf *actions, struct ofpbuf *put_actions,
-                     int *lost_cnt, long long now)
+                     long long now)
 {
     struct ofpbuf *add_actions;
     struct dp_packet_batch b;
     struct match match;
     ovs_u128 ufid;
-    int error;
+    int error = 0;
 
     match.tun_md.valid = false;
     miniflow_expand(&key->mf, &match.flow);
@@ -4749,8 +4764,7 @@ handle_packet_upcall(struct dp_netdev_pmd_thread *pmd,
                              put_actions);
     if (OVS_UNLIKELY(error && error != ENOSPC)) {
         dp_packet_delete(packet);
-        (*lost_cnt)++;
-        return;
+        return error;
     }
 
     /* The Netlink encoding of datapath flow keys cannot express
@@ -4790,6 +4804,7 @@ handle_packet_upcall(struct dp_netdev_pmd_thread *pmd,
         ovs_mutex_unlock(&pmd->flow_mutex);
         emc_probabilistic_insert(pmd, key, netdev_flow);
     }
+    return error;
 }
 
 static inline void
@@ -4811,7 +4826,7 @@ fast_path_processing(struct dp_netdev_pmd_thread *pmd,
     struct dpcls *cls;
     struct dpcls_rule *rules[PKT_ARRAY_SIZE];
     struct dp_netdev *dp = pmd->dp;
-    int miss_cnt = 0, lost_cnt = 0;
+    int upcall_ok_cnt = 0, upcall_fail_cnt = 0;
     int lookup_cnt = 0, add_lookup_cnt;
     bool any_miss;
     size_t i;
@@ -4853,9 +4868,14 @@ fast_path_processing(struct dp_netdev_pmd_thread *pmd,
                 continue;
             }
 
-            miss_cnt++;
-            handle_packet_upcall(pmd, packets[i], &keys[i], &actions,
-                                 &put_actions, &lost_cnt, now);
+            int error = handle_packet_upcall(pmd, packets[i], &keys[i],
+                           &actions, &put_actions, now);
+
+            if (OVS_UNLIKELY(error)) {
+                upcall_fail_cnt++;
+            } else {
+                upcall_ok_cnt++;
+            }
         }
 
         ofpbuf_uninit(&actions);
@@ -4865,8 +4885,7 @@ fast_path_processing(struct dp_netdev_pmd_thread *pmd,
         for (i = 0; i < cnt; i++) {
             if (OVS_UNLIKELY(!rules[i])) {
                 dp_packet_delete(packets[i]);
-                lost_cnt++;
-                miss_cnt++;
+                upcall_fail_cnt++;
             }
         }
     }
@@ -4885,10 +4904,11 @@ fast_path_processing(struct dp_netdev_pmd_thread *pmd,
         dp_netdev_queue_batches(packet, flow, &keys[i].mf, batches, n_batches);
     }
 
-    dp_netdev_count_packet(pmd, DP_STAT_MASKED_HIT, cnt - miss_cnt);
-    dp_netdev_count_packet(pmd, DP_STAT_LOOKUP_HIT, lookup_cnt);
-    dp_netdev_count_packet(pmd, DP_STAT_MISS, miss_cnt);
-    dp_netdev_count_packet(pmd, DP_STAT_LOST, lost_cnt);
+    dp_netdev_count_packet(pmd, DP_STAT_MASKED_HIT, cnt - upcall_ok_cnt -
+                           upcall_fail_cnt);
+    dp_netdev_count_packet(pmd, DP_STAT_MASKED_LOOKUP, lookup_cnt);
+    dp_netdev_count_packet(pmd, DP_STAT_MISS, upcall_ok_cnt);
+    dp_netdev_count_packet(pmd, DP_STAT_LOST, upcall_fail_cnt);
 }
 
 /* Packets enter the datapath from a port (or from recirculation) here.
diff --git a/tests/pmd.at b/tests/pmd.at
index b6732ea..d36ee57 100644
--- a/tests/pmd.at
+++ b/tests/pmd.at
@@ -170,13 +170,16 @@ dummy at ovs-dummy: hit:0 missed:0
 		p0 7/1: (dummy-pmd: configured_rx_queues=4, configured_tx_queues=<cleared>, requested_rx_queues=4, requested_tx_queues=<cleared>)
 ])
 
-AT_CHECK([ovs-appctl dpif-netdev/pmd-stats-show | sed SED_NUMA_CORE_PATTERN | sed '/cycles/d' | grep pmd -A 5], [0], [dnl
+AT_CHECK([ovs-appctl dpif-netdev/pmd-stats-show | sed SED_NUMA_CORE_PATTERN | sed '/cycles/d' | grep pmd -A 8], [0], [dnl
 pmd thread numa_id <cleared> core_id <cleared>:
+	packets received:0
+	packet recirculations:0
+	avg. datapath passes per packet:0.00
 	emc hits:0
 	megaflow hits:0
-	avg. subtable lookups per hit:0.00
-	miss:0
-	lost:0
+	avg. subtable lookups per megaflow hit:0.00
+	miss(i.e. lookup miss with success upcall):0
+	lost(i.e. lookup miss with failed upcall):0
 ])
 
 ovs-appctl time/stop
@@ -197,13 +200,16 @@ AT_CHECK([cat ovs-vswitchd.log | filter_flow_install | strip_xout], [0], [dnl
 recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:77,dst=50:54:00:00:01:78),eth_type(0x0800),ipv4(frag=no), actions: <del>
 ])
 
-AT_CHECK([ovs-appctl dpif-netdev/pmd-stats-show | sed SED_NUMA_CORE_PATTERN | sed '/cycles/d' | grep pmd -A 5], [0], [dnl
+AT_CHECK([ovs-appctl dpif-netdev/pmd-stats-show | sed SED_NUMA_CORE_PATTERN | sed '/cycles/d' | grep pmd -A 8], [0], [dnl
 pmd thread numa_id <cleared> core_id <cleared>:
+	packets received:20
+	packet recirculations:0
+	avg. datapath passes per packet:1.00
 	emc hits:19
 	megaflow hits:0
-	avg. subtable lookups per hit:0.00
-	miss:1
-	lost:0
+	avg. subtable lookups per megaflow hit:0.00
+	miss(i.e. lookup miss with success upcall):1
+	lost(i.e. lookup miss with failed upcall):0
 ])
 
 OVS_VSWITCHD_STOP
-- 
1.9.1



More information about the dev mailing list