If transmit callback is called, and there are no packets
in the burst with timestamp set, then the expensive operations
of locking and accessing TSC can be skipped.

Signed-off-by: Stephen Hemminger <step...@networkplumber.org>
---
 lib/latencystats/rte_latencystats.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/lib/latencystats/rte_latencystats.c 
b/lib/latencystats/rte_latencystats.c
index 181c53dd0e..dc415c4682 100644
--- a/lib/latencystats/rte_latencystats.c
+++ b/lib/latencystats/rte_latencystats.c
@@ -190,17 +190,26 @@ calc_latency(uint16_t pid __rte_unused,
                void *_ __rte_unused)
 {
        unsigned int i;
-       uint64_t now, latency;
+       uint64_t ts_flags = 0;
        static uint64_t prev_latency;
 
-       now = rte_rdtsc();
+       for (i = 0; i < nb_pkts; i++)
+               ts_flags |= (pkts[i]->ol_flags & timestamp_dynflag);
 
+       /* no samples in this burst, skip locking */
+       if (likely(ts_flags == 0))
+               return nb_pkts;
+
+       uint64_t now = rte_rdtsc();
        rte_spinlock_lock(&glob_stats->lock);
        for (i = 0; i < nb_pkts; i++) {
-               if (!(pkts[i]->ol_flags & timestamp_dynflag))
+               struct rte_mbuf *m = pkts[i];
+               uint64_t latency;
+
+               if (!(m->ol_flags & timestamp_dynflag))
                        continue;
 
-               latency = now - *timestamp_dynfield(pkts[i]);
+               latency = now - *timestamp_dynfield(m);
 
                if (glob_stats->samples++ == 0) {
                        glob_stats->min_latency = latency;
-- 
2.47.2

Reply via email to