app/testpmd: use clock time in throughput calculation

The throughput calculation requires a counter that measures
passing of time. However, the kernel saves and restores the PMU
state when a thread is unscheduled and scheduled. This ensures
that the PMU cycles are not counted towards a thread that is
not scheduled. Hence, when RTE_ARM_EAL_RDTSC_USE_PMU is enabled,
the PMU cycles do not represent the passing of time.
This results in incorrect calculation of throughput numbers.
Use clock_gettime system call to calculate the time passed since
last call.

Bugzilla ID: 450
Fixes: 0e10698030 ("app/testpmd: show throughput in port stats")
Cc: stable@dpdk.org

Signed-off-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
Reviewed-by: Phil Yang <phil.yang@arm.com>
Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
Tested-by: Phil Yang <phil.yang@arm.com>
Tested-by: Ali Alnubani <alialnu@mellanox.com>
This commit is contained in:
Honnappa Nagarahalli 2020-07-06 18:32:29 -05:00 committed by Ferruh Yigit
parent cd6760da10
commit aac2b6a78d

View file

@ -54,6 +54,14 @@
#define ETHDEV_FWVERS_LEN 32
#ifdef CLOCK_MONOTONIC_RAW /* Defined in glibc bits/time.h */
#define CLOCK_TYPE_ID CLOCK_MONOTONIC_RAW
#else
#define CLOCK_TYPE_ID CLOCK_MONOTONIC
#endif
#define NS_PER_SEC 1E9
static char *flowtype_to_str(uint16_t flow_type);
static const struct {
@ -139,9 +147,10 @@ nic_stats_display(portid_t port_id)
static uint64_t prev_pkts_tx[RTE_MAX_ETHPORTS];
static uint64_t prev_bytes_rx[RTE_MAX_ETHPORTS];
static uint64_t prev_bytes_tx[RTE_MAX_ETHPORTS];
static uint64_t prev_cycles[RTE_MAX_ETHPORTS];
static uint64_t prev_ns[RTE_MAX_ETHPORTS];
struct timespec cur_time;
uint64_t diff_pkts_rx, diff_pkts_tx, diff_bytes_rx, diff_bytes_tx,
diff_cycles;
diff_ns;
uint64_t mpps_rx, mpps_tx, mbps_rx, mbps_tx;
struct rte_eth_stats stats;
struct rte_port *port = &ports[port_id];
@ -198,10 +207,17 @@ nic_stats_display(portid_t port_id)
}
}
diff_cycles = prev_cycles[port_id];
prev_cycles[port_id] = rte_rdtsc();
if (diff_cycles > 0)
diff_cycles = prev_cycles[port_id] - diff_cycles;
diff_ns = 0;
if (clock_gettime(CLOCK_TYPE_ID, &cur_time) == 0) {
uint64_t ns;
ns = cur_time.tv_sec * NS_PER_SEC;
ns += cur_time.tv_nsec;
if (prev_ns[port_id] != 0)
diff_ns = ns - prev_ns[port_id];
prev_ns[port_id] = ns;
}
diff_pkts_rx = (stats.ipackets > prev_pkts_rx[port_id]) ?
(stats.ipackets - prev_pkts_rx[port_id]) : 0;
@ -209,10 +225,10 @@ nic_stats_display(portid_t port_id)
(stats.opackets - prev_pkts_tx[port_id]) : 0;
prev_pkts_rx[port_id] = stats.ipackets;
prev_pkts_tx[port_id] = stats.opackets;
mpps_rx = diff_cycles > 0 ?
diff_pkts_rx * rte_get_tsc_hz() / diff_cycles : 0;
mpps_tx = diff_cycles > 0 ?
diff_pkts_tx * rte_get_tsc_hz() / diff_cycles : 0;
mpps_rx = diff_ns > 0 ?
(double)diff_pkts_rx / diff_ns * NS_PER_SEC : 0;
mpps_tx = diff_ns > 0 ?
(double)diff_pkts_tx / diff_ns * NS_PER_SEC : 0;
diff_bytes_rx = (stats.ibytes > prev_bytes_rx[port_id]) ?
(stats.ibytes - prev_bytes_rx[port_id]) : 0;
@ -220,10 +236,10 @@ nic_stats_display(portid_t port_id)
(stats.obytes - prev_bytes_tx[port_id]) : 0;
prev_bytes_rx[port_id] = stats.ibytes;
prev_bytes_tx[port_id] = stats.obytes;
mbps_rx = diff_cycles > 0 ?
diff_bytes_rx * rte_get_tsc_hz() / diff_cycles : 0;
mbps_tx = diff_cycles > 0 ?
diff_bytes_tx * rte_get_tsc_hz() / diff_cycles : 0;
mbps_rx = diff_ns > 0 ?
(double)diff_bytes_rx / diff_ns * NS_PER_SEC : 0;
mbps_tx = diff_ns > 0 ?
(double)diff_bytes_tx / diff_ns * NS_PER_SEC : 0;
printf("\n Throughput (since last show)\n");
printf(" Rx-pps: %12"PRIu64" Rx-bps: %12"PRIu64"\n Tx-pps: %12"