[NFVBENCH-81]With some Intel X710 NIC cards, NFVbench reports erroneous RX counters 83/54883/1
authorahothan <ahothan@cisco.com>
Wed, 4 Apr 2018 07:56:04 +0000 (00:56 -0700)
committerahothan <ahothan@cisco.com>
Wed, 4 Apr 2018 07:56:04 +0000 (00:56 -0700)
Work around this NIC FW issue by using port level stats for packets/bytes
ALso fix mutliple calls to get_stats()

Change-Id: Id19086d0db6bcc4417adff4ed4ce9606ffb30fe2
Signed-off-by: ahothan <ahothan@cisco.com>
nfvbench/chain_managers.py
nfvbench/traffic_client.py
nfvbench/traffic_gen/trex.py

index 087c751..de6afca 100644 (file)
@@ -98,8 +98,8 @@ class StatsManager(object):
     def _get_data(self):
         return self.worker.get_data() if self.worker else {}
 
-    def _get_network(self, traffic_port, index=None, reverse=False):
-        interfaces = [self.clients['traffic'].get_interface(traffic_port)]
+    def _get_network(self, traffic_port, index, stats, reverse=False):
+        interfaces = [self.clients['traffic'].get_interface(traffic_port, stats)]
         if self.worker:
             interfaces.extend(self.worker.get_network_interfaces(index))
         return Network(interfaces, reverse)
@@ -144,16 +144,21 @@ class StatsManager(object):
             'stats': stats
         }
 
+        # fetch latest stats from traffic gen
+        if self.config.no_traffic:
+            stats = None
+        else:
+            stats = self.clients['traffic'].get_stats()
         LOG.info('Requesting packet analysis on the forward direction...')
         result['packet_analysis']['direction-forward'] = \
-            self.get_analysis([self._get_network(0, 0),
-                               self._get_network(0, 1, reverse=True)])
+            self.get_analysis([self._get_network(0, 0, stats),
+                               self._get_network(0, 1, stats, reverse=True)])
         LOG.info('Packet analysis on the forward direction completed')
 
         LOG.info('Requesting packet analysis on the reverse direction...')
         result['packet_analysis']['direction-reverse'] = \
-            self.get_analysis([self._get_network(1, 1),
-                               self._get_network(1, 0, reverse=True)])
+            self.get_analysis([self._get_network(1, 1, stats),
+                               self._get_network(1, 0, stats, reverse=True)])
 
         LOG.info('Packet analysis on the reverse direction completed')
         return result
@@ -205,16 +210,20 @@ class PVVPStatsManager(StatsManager):
             'packet_analysis': {},
             'stats': stats
         }
-
-        fwd_nets = [self._get_network(0, 0)]
+        # fetch latest stats from traffic gen
+        if self.config.no_traffic:
+            stats = None
+        else:
+            stats = self.clients['traffic'].get_stats()
+        fwd_nets = [self._get_network(0, 0, stats)]
         if fwd_v2v_net:
             fwd_nets.append(fwd_v2v_net)
-        fwd_nets.append(self._get_network(0, 1, reverse=True))
+        fwd_nets.append(self._get_network(0, 1, stats, reverse=True))
 
-        rev_nets = [self._get_network(1, 1)]
+        rev_nets = [self._get_network(1, 1, stats)]
         if rev_v2v_net:
             rev_nets.append(rev_v2v_net)
-        rev_nets.append(self._get_network(1, 0, reverse=True))
+        rev_nets.append(self._get_network(1, 0, stats, reverse=True))
 
         LOG.info('Requesting packet analysis on the forward direction...')
         result['packet_analysis']['direction-forward'] = self.get_analysis(fwd_nets)
index 056075a..2ce118c 100755 (executable)
@@ -787,13 +787,11 @@ class TrafficClient(object):
     def cancel_traffic(self):
         self.runner.stop()
 
-    def get_interface(self, port_index):
+    def get_interface(self, port_index, stats):
         port = self.gen.port_handle[port_index]
         tx, rx = 0, 0
-        if not self.config.no_traffic:
-            stats = self.get_stats()
-            if port in stats:
-                tx, rx = int(stats[port]['tx']['total_pkts']), int(stats[port]['rx']['total_pkts'])
+        if stats and port in stats:
+            tx, rx = int(stats[port]['tx']['total_pkts']), int(stats[port]['rx']['total_pkts'])
         return Interface('traffic-generator', self.tool.lower(), tx, rx)
 
     def get_traffic_config(self):
index 7d64f0f..683e97e 100644 (file)
@@ -78,21 +78,21 @@ class TRex(AbstractTrafficGenerator):
 
         result = {}
         for ph in self.port_handle:
-            stats = self.__combine_stats(in_stats, ph)
+            stats = in_stats[ph]
             result[ph] = {
                 'tx': {
-                    'total_pkts': cast_integer(stats['tx_pkts']['total']),
-                    'total_pkt_bytes': cast_integer(stats['tx_bytes']['total']),
-                    'pkt_rate': cast_integer(stats['tx_pps']['total']),
-                    'pkt_bit_rate': cast_integer(stats['tx_bps']['total'])
+                    'total_pkts': cast_integer(stats['opackets']),
+                    'total_pkt_bytes': cast_integer(stats['obytes']),
+                    'pkt_rate': cast_integer(stats['tx_pps']),
+                    'pkt_bit_rate': cast_integer(stats['tx_bps'])
                 },
                 'rx': {
-                    'total_pkts': cast_integer(stats['rx_pkts']['total']),
-                    'total_pkt_bytes': cast_integer(stats['rx_bytes']['total']),
-                    'pkt_rate': cast_integer(stats['rx_pps']['total']),
-                    'pkt_bit_rate': cast_integer(stats['rx_bps']['total']),
+                    'total_pkts': cast_integer(stats['ipackets']),
+                    'total_pkt_bytes': cast_integer(stats['ibytes']),
+                    'pkt_rate': cast_integer(stats['rx_pps']),
+                    'pkt_bit_rate': cast_integer(stats['rx_bps']),
                     'dropped_pkts': cast_integer(
-                        stats['tx_pkts']['total'] - stats['rx_pkts']['total'])
+                        stats['opackets'] - stats['ipackets'])
                 }
             }
 
@@ -107,20 +107,6 @@ class TRex(AbstractTrafficGenerator):
         result["total_tx_rate"] = cast_integer(total_tx_pkts / self.config.duration_sec)
         return result
 
-    def __combine_stats(self, in_stats, port_handle):
-        """Traverses TRex result dictionary and combines stream stats. Used for combining latency
-        and regular streams together.
-        """
-        result = defaultdict(lambda: defaultdict(float))
-
-        for pg_id in [self.stream_ids[port_handle]] + self.latencies[port_handle]:
-            record = in_stats['flow_stats'][pg_id]
-            for stat_type, stat_type_values in record.iteritems():
-                for ph, value in stat_type_values.iteritems():
-                    result[stat_type][ph] += value
-
-        return result
-
     def __combine_latencies(self, in_stats, port_handle):
         """Traverses TRex result dictionary and combines chosen latency stats."""
         if not self.latencies[port_handle]:
@@ -441,7 +427,7 @@ class TRex(AbstractTrafficGenerator):
         LOG.info('Cleared all existing streams.')
 
     def get_stats(self):
-        stats = self.client.get_pgid_stats()
+        stats = self.client.get_stats()
         return self.extract_stats(stats)
 
     def get_macs(self):