diff options
author | imarom <imarom@cisco.com> | 2016-05-30 17:36:03 +0300 |
---|---|---|
committer | imarom <imarom@cisco.com> | 2016-05-30 17:39:41 +0300 |
commit | 958d3c258293929e80b215d2b56b4032dae3910d (patch) | |
tree | 773f1b14427f058bc4845e81441a43004c4669ce | |
parent | e73f799983788c328fa5901b9171acfc66de6d5c (diff) |
async util. monitor
i40 FDIR delay issue
4 files changed, 112 insertions, 17 deletions
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_async_client.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_async_client.py index 745a7fc5..0f73792a 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_async_client.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_async_client.py @@ -153,6 +153,8 @@ class CTRexAsyncClient(): self.last_data_recv_ts = 0 self.async_barrier = None + self.monitor = AsyncUtil() + self.connected = False # connects the async channel @@ -223,10 +225,17 @@ class CTRexAsyncClient(): got_data = False + self.monitor.reset() + + while self.active: try: - line = self.socket.recv_string() + with self.monitor: + line = self.socket.recv_string() + + self.monitor.on_recv_msg(line) + self.last_data_recv_ts = time.time() # signal once @@ -237,7 +246,6 @@ class CTRexAsyncClient(): # got a timeout - mark as not alive and retry except zmq.Again: - # signal once if got_data: self.event_handler.on_async_dead() @@ -341,4 +349,82 @@ class CTRexAsyncClient(): return RC_OK() +# a class to measure util. of async subscriber thread +class AsyncUtil(object): + + STATE_SLEEP = 1 + STATE_AWAKE = 2 + + def __init__ (self): + self.reset() + + + def reset (self): + self.state = self.STATE_AWAKE + self.clock = time.time() + + # reset the current interval + self.interval = {'ts': time.time(), 'total_sleep': 0, 'total_bits': 0} + + # global counters + self.cpu_util = 0 + self.bps = 0 + + + def on_recv_msg (self, message): + self.interval['total_bits'] += len(message) * 8.0 + + self._tick() + + + def __enter__ (self): + assert(self.state == self.STATE_AWAKE) + self.state = self.STATE_SLEEP + + self.sleep_start_ts = time.time() + + + def __exit__(self, exc_type, exc_val, exc_tb): + assert(self.state == self.STATE_SLEEP) + self.state = self.STATE_AWAKE + + # measure total sleep time for interval + self.interval['total_sleep'] += time.time() - self.sleep_start_ts + + self._tick() + + def _tick (self): + # how much time did the current interval lasted + ts = time.time() - self.interval['ts'] + if ts < 1: + return + + # if tick is in the middle of sleep - add the interval and reset + if self.state == self.STATE_SLEEP: + self.interval['total_sleep'] += time.time() - self.sleep_start_ts + self.sleep_start_ts = time.time() + + # add the interval + if self.interval['total_sleep'] > 0: + # calculate + self.cpu_util = self.cpu_util * 0.75 + (float(ts - self.interval['total_sleep']) / ts) * 0.25 + self.interval['total_sleep'] = 0 + + + if self.interval['total_bits'] > 0: + # calculate + self.bps = self.bps * 0.75 + ( self.interval['total_bits'] / ts ) * 0.25 + self.interval['total_bits'] = 0 + + # reset the interval's clock + self.interval['ts'] = time.time() + + + def get_cpu_util (self): + self._tick() + return (self.cpu_util * 100) + + def get_bps (self): + self._tick() + return (self.bps) diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py index fa24574f..22895a75 100755 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py @@ -558,7 +558,8 @@ class STLClient(object): self.stats_generator = trex_stl_stats.CTRexInfoGenerator(self.global_stats, self.ports, self.flow_stats, - self.latency_stats) + self.latency_stats, + self.async_client.monitor) diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py index 0ebea607..94a45577 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py @@ -138,11 +138,12 @@ class CTRexInfoGenerator(object): STLClient and the ports. """ - def __init__(self, global_stats_ref, ports_dict_ref, rx_stats_ref, latency_stats_ref): + def __init__(self, global_stats_ref, ports_dict_ref, rx_stats_ref, latency_stats_ref, async_monitor): self._global_stats = global_stats_ref self._ports_dict = ports_dict_ref self._rx_stats_ref = rx_stats_ref self._latency_stats_ref = latency_stats_ref + self._async_monitor = async_monitor def generate_single_statistic(self, port_id_list, statistic_type): if statistic_type == GLOBAL_STATS: @@ -187,24 +188,22 @@ class CTRexInfoGenerator(object): def _generate_global_stats(self): global_stats = self._global_stats - #if is_integer(global_stats.max_global_latency): - # max_global_latency_str = ', Max latency: %s' % format_num(global_stats.max_global_latency, - # suffix = 'usec', - # compact = False, - # opts = 'green' if global_stats.max_global_latency < 1000 else 'red') - #else: - # max_global_latency_str = '' + stats_data = OrderedDict([("connection", "{host}, Port {port}".format(host=global_stats.connection_info.get("server"), port=global_stats.connection_info.get("sync_port"))), ("version", "{ver}, UUID: {uuid}".format(ver=global_stats.server_version.get("version", "N/A"), uuid="N/A")), - ("cpu_util", "{0}% {1}".format( format_threshold(round_float(global_stats.get("m_cpu_util")), [85, 100], [0, 85]), + ("cpu_util.", "{0}% {1}".format( format_threshold(round_float(global_stats.get("m_cpu_util")), [85, 100], [0, 85]), global_stats.get_trend_gui("m_cpu_util", use_raw = True))), - ("rx_cpu_util", "{0}% {1}".format( format_threshold(round_float(global_stats.get("m_rx_cpu_util")), [85, 100], [0, 85]), + ("rx_cpu_util.", "{0}% {1}".format( format_threshold(round_float(global_stats.get("m_rx_cpu_util")), [85, 100], [0, 85]), global_stats.get_trend_gui("m_rx_cpu_util", use_raw = True))), + ("async_util.", "{0}% / {1}".format( format_threshold(round_float(self._async_monitor.get_cpu_util()), [85, 100], [0, 85]), + format_num(self._async_monitor.get_bps() / 8.0, suffix = "B/sec"))), + + (" ", ""), ("total_tx_L2", "{0} {1}".format( global_stats.get("m_tx_bps", format=True, suffix="b/sec"), diff --git a/src/dpdk22/drivers/net/i40e/i40e_fdir.c b/src/dpdk22/drivers/net/i40e/i40e_fdir.c index f644ef3d..888b7977 100644 --- a/src/dpdk22/drivers/net/i40e/i40e_fdir.c +++ b/src/dpdk22/drivers/net/i40e/i40e_fdir.c @@ -71,8 +71,8 @@ #define I40E_FDIR_UDP_DEFAULT_LEN 400 /* Wait count and interval for fdir filter programming */ -#define I40E_FDIR_WAIT_COUNT 10 -#define I40E_FDIR_WAIT_INTERVAL_US 1000 +#define I40E_FDIR_WAIT_COUNT 100 +#define I40E_FDIR_WAIT_INTERVAL_US 100 /* Wait count and interval for fdir filter flush */ #define I40E_FDIR_FLUSH_RETRY 50 @@ -1176,19 +1176,28 @@ i40e_fdir_filter_programming(struct i40e_pf *pf, I40E_PCI_REG_WRITE(txq->qtx_tail, txq->tx_tail); for (i = 0; i < I40E_FDIR_WAIT_COUNT; i++) { - rte_delay_us(I40E_FDIR_WAIT_INTERVAL_US); + + /* itay: moved this delay after the check to avoid first check */ + //rte_delay_us(I40E_FDIR_WAIT_INTERVAL_US); + if ((txdp->cmd_type_offset_bsz & rte_cpu_to_le_64(I40E_TXD_QW1_DTYPE_MASK)) == rte_cpu_to_le_64(I40E_TX_DESC_DTYPE_DESC_DONE)) break; + + rte_delay_us(I40E_FDIR_WAIT_INTERVAL_US); } + if (i >= I40E_FDIR_WAIT_COUNT) { PMD_DRV_LOG(ERR, "Failed to program FDIR filter:" " time out to get DD on tx queue."); return -ETIMEDOUT; } + /* totally delay 10 ms to check programming status*/ - rte_delay_us((I40E_FDIR_WAIT_COUNT - i) * I40E_FDIR_WAIT_INTERVAL_US); + /* itay: tests show this is not needed */ + //rte_delay_us((I40E_FDIR_WAIT_COUNT - i) * I40E_FDIR_WAIT_INTERVAL_US); + if (i40e_check_fdir_programming_status(rxq) < 0) { PMD_DRV_LOG(ERR, "Failed to program FDIR filter:" " programming status reported."); |