From 90e69f01d75a76dbac971174db0e701ebd40f543 Mon Sep 17 00:00:00 2001 From: ahothan Date: Wed, 4 Apr 2018 00:56:04 -0700 Subject: [NFVBENCH-81]With some Intel X710 NIC cards, NFVbench reports erroneous RX counters 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 --- nfvbench/chain_managers.py | 31 ++++++++++++++++++++----------- nfvbench/traffic_client.py | 8 +++----- nfvbench/traffic_gen/trex.py | 36 +++++++++++------------------------- 3 files changed, 34 insertions(+), 41 deletions(-) diff --git a/nfvbench/chain_managers.py b/nfvbench/chain_managers.py index 087c751..de6afca 100644 --- a/nfvbench/chain_managers.py +++ b/nfvbench/chain_managers.py @@ -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) diff --git a/nfvbench/traffic_client.py b/nfvbench/traffic_client.py index 056075a..2ce118c 100755 --- a/nfvbench/traffic_client.py +++ b/nfvbench/traffic_client.py @@ -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): diff --git a/nfvbench/traffic_gen/trex.py b/nfvbench/traffic_gen/trex.py index 7d64f0f..683e97e 100644 --- a/nfvbench/traffic_gen/trex.py +++ b/nfvbench/traffic_gen/trex.py @@ -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): -- cgit 1.2.3-korg