On 4/16/26 12:40 PM, Kevin Traynor wrote:
> On 4/8/26 6:16 PM, Ilya Maximets wrote:
>> The 'pmd-perf-show' command provides all the same information and more.
>> It is also better visually structured and easier to read as a result.
>>
>> Let's remove the old 'pmd-stats-show' command, as there is no real need
>> to have two commands reporting the same data.
>>
>> The only difference until now was that 'pmd-perf-show' didn't provide
>> information for the "main" thread.  This change makes it report the
>> statistics for the aggregated "main" thread as well, omitting things
>> related to CPU cycles, as we can't collect those for threads that are
>> not pinned.  For the same reason histograms are also always disabled.
>> Omission is done by checking the total number of iterations to be zero.
>> "main" thread doesn't start/end iterations.
>>
>> The actual unixctl command is preserved undocumented and serves as an
>> alias for 'pmd-perf-show'.  This should allow old scripts that are just
>> capturing the output for humans (or LLMs?) to read to keep working.
>> Note, however, that the exact output format for unixctl commands was
>> never a guarantee, so scripts that attempt to parse the output may
>> still break.
>>
> 
> Hi Ilya,
> 
> thanks for this, couple of comment below, otherwise LGTM.
> 
>> Signed-off-by: Ilya Maximets <[email protected]>
>> ---
>>
>> Note: I believe the change in system-dpdk-offloads.at is correct,
>>       but I didn't run the testsuite, as I have no hardware for it.
>>
>>  Documentation/intro/install/afxdp.rst         |   2 +-
>>  Documentation/intro/install/dpdk.rst          |   2 +-
>>  Documentation/topics/dpdk/bridge.rst          |   4 +-
>>  Documentation/topics/dpdk/pmd.rst             |   4 -
>>  NEWS                                          |   4 +
>>  lib/dpif-netdev-perf.c                        |  39 +++--
>>  lib/dpif-netdev-perf.h                        |   2 +-
>>  lib/dpif-netdev-unixctl.man                   |  62 ++++---
>>  lib/dpif-netdev.c                             | 158 ++++--------------
>>  tests/dpif-netdev.at                          |  20 +--
>>  tests/pmd.at                                  |  47 +++---
>>  tests/system-dpdk-offloads.at                 |   8 +-
>>  .../plugins/system-logs/openvswitch.xml       |   2 +-
>>  13 files changed, 136 insertions(+), 218 deletions(-)
>>
>> diff --git a/Documentation/intro/install/afxdp.rst 
>> b/Documentation/intro/install/afxdp.rst
>> index 63a10e328..07225a885 100644
>> --- a/Documentation/intro/install/afxdp.rst
>> +++ b/Documentation/intro/install/afxdp.rst
>> @@ -273,7 +273,7 @@ Measure your system call rate by doing::
>>  
>>  Or, use OVS pmd tool::
>>  
>> -  ovs-appctl dpif-netdev/pmd-stats-show
>> +  ovs-appctl dpif-netdev/pmd-perf-show
>>  
>>  
>>  Example Script
>> diff --git a/Documentation/intro/install/dpdk.rst 
>> b/Documentation/intro/install/dpdk.rst
>> index 6f4687bde..d5c897e8b 100644
>> --- a/Documentation/intro/install/dpdk.rst
>> +++ b/Documentation/intro/install/dpdk.rst
>> @@ -709,7 +709,7 @@ level:
>>  
>>  The average number of packets per output batch can be checked in PMD stats::
>>  
>> -    $ ovs-appctl dpif-netdev/pmd-stats-show
>> +    $ ovs-appctl dpif-netdev/pmd-perf-show
>>  
>>  Limitations
>>  ------------
>> diff --git a/Documentation/topics/dpdk/bridge.rst 
>> b/Documentation/topics/dpdk/bridge.rst
>> index 03c4dd4e3..4468b904b 100644
>> --- a/Documentation/topics/dpdk/bridge.rst
>> +++ b/Documentation/topics/dpdk/bridge.rst
>> @@ -103,7 +103,7 @@ the packet itself and others (for example, VLAN tag or 
>> Ethernet type) can be
>>  extracted without fully parsing the packet.  This allows OVS to 
>> significantly
>>  speed up packet forwarding for these flows with simple match criteria.
>>  Statistics on the number of packets matched in this way can be found in a
>> -`simple match hits` counter of `ovs-appctl dpif-netdev/pmd-stats-show` 
>> command.
>> +`Simple Match hits` counter of `ovs-appctl dpif-netdev/pmd-perf-show` 
>> command.
>>  
>>  EMC Insertion Probability
>>  -------------------------
>> @@ -127,7 +127,7 @@ If ``N`` is set to 1, an insertion will be performed for 
>> every flow. If set to
>>  With default ``N`` set to 100, higher megaflow hits will occur initially as
>>  observed with pmd stats::
>>  
>> -    $ ovs-appctl dpif-netdev/pmd-stats-show
>> +    $ ovs-appctl dpif-netdev/pmd-perf-show
>>  
>>  For certain traffic profiles with many parallel flows, it's recommended to 
>> set
>>  ``N`` to '0' to achieve higher forwarding performance.
>> diff --git a/Documentation/topics/dpdk/pmd.rst 
>> b/Documentation/topics/dpdk/pmd.rst
>> index 2e8cf5edb..1589d521c 100644
>> --- a/Documentation/topics/dpdk/pmd.rst
>> +++ b/Documentation/topics/dpdk/pmd.rst
>> @@ -57,10 +57,6 @@ PMD Thread Statistics
>>  
>>  To show current stats::
>>  
>> -    $ ovs-appctl dpif-netdev/pmd-stats-show
>> -
>> -or::
>> -
>>      $ ovs-appctl dpif-netdev/pmd-perf-show
>>  
>>  Detailed performance metrics for ``pmd-perf-show`` can also be enabled::
>> diff --git a/NEWS b/NEWS
>> index 1a3044cbf..b35bcff6e 100644
>> --- a/NEWS
>> +++ b/NEWS
>> @@ -3,6 +3,10 @@ Post-v3.7.0
>>     - Userspace datapath:
>>       * ARP/ND lookups for native tunnel are now rate limited. The holdout
>>         timer can be configured with 'tnl/neigh/retrans_time'.
>> +   - ovs-appctl:
>> +     * 'dpif-netdev/pmd-stats-show' command was removed in favor of the more
>> +       informative and better structured 'dpif-netdev/pmd-perf-show', which
>> +       now also provides statistics for the "main" thread.
>>  
>>  
>>  v3.7.0 - 16 Feb 2026
>> diff --git a/lib/dpif-netdev-perf.c b/lib/dpif-netdev-perf.c
>> index 1cd4ee084..ba370d7c1 100644
>> --- a/lib/dpif-netdev-perf.c
>> +++ b/lib/dpif-netdev-perf.c
>> @@ -233,7 +233,8 @@ pmd_perf_format_overall_stats(struct ds *str, struct 
>> pmd_perf_stats *s,
>>      uint64_t sleep_iter = stats[PMD_SLEEP_ITER];
>>      uint64_t tot_sleep_cycles = stats[PMD_CYCLES_SLEEP];
>>  
>> -    ds_put_format(str,
>> +    if (tot_iter) {
> 
> While the change is to cater for main thread, it also changes display
> for pmd cores with no iterations. Previously there was:
> 
> pmd thread numa_id 1 core_id 9:
> 
>   Iterations:                    0  (0.00 us/it)
>   - Used TSC cycles:             0  (  0.0 % of total cycles)
>   - idle iterations:             0  (  0.0 % of used cycles)
>   - busy iterations:             0  (  0.0 % of used cycles)
>   - sleep iterations:            0  (  0.0 % of iterations)
>   Sleep time (us):               0  (  0 us/iteration avg.)
>   Rx packets:                    0
>   Tx packets:                    0
> 
> That is now changed so that iterations of zero are implicit.
> 
> pmd thread numa_id 1 core_id 11:
> 
>   Rx packets:                    0
>   Tx packets:                    0
> 
> 
> Considering we can also have a case where there are iterations but no
> packets like below, i think we should leave zero iterations explicit for
> pmd thread as it currently is.
> 
> pmd thread numa_id 0 core_id 8:
> 
>   Iterations:             17369522  (0.15 us/it)
>   - Used TSC cycles:    6816002305  ( 80.1 % of total cycles)
>   - idle iterations:      17369522  (100.0 % of used cycles)
>   - busy iterations:             0  (  0.0 % of used cycles)
>   - sleep iterations:            0  (  0.0 % of iterations)
>   Sleep time (us):               0  (  0 us/iteration avg.)
>   Rx packets:                    0
>   Tx packets:                    0
> 
> 
> I agree that for main thread it doesn't make sense to display it, so
> maybe we could add a bool to pmd_perf_format_overall_stats() args to
> make showing the iteration section conditional, then set differently
> when the non pmd core in pmd_info_show_perf().

Makes sense.  I'll add an argument to this function.

> 
>> +        ds_put_format(str,
>>              "  Iterations:         %12"PRIu64"  (%.2f us/it)\n"
> 
>>              "  - Used TSC cycles:  %12"PRIu64"  (%5.1f %% of total 
>> cycles)\n"
> 
> aside from comments above, with current version there is no need to
> re-check for tot_iter (not shown in diff)

True.  Though I'll need to keep the code as-is in v2, since the 'if'
condition will change to the new function argument and we'll still
need to check the tot_iter.

> 
>>              "  - idle iterations:  %12"PRIu64"  (%5.1f %% of used cycles)\n"
>> @@ -252,9 +253,18 @@ pmd_perf_format_overall_stats(struct ds *str, struct 
>> pmd_perf_stats *s,
>>              sleep_iter, tot_iter ? 100.0 * sleep_iter / tot_iter : 0,
>>              tot_sleep_cycles * us_per_cycle,
>>              sleep_iter ? (tot_sleep_cycles * us_per_cycle) / sleep_iter : 
>> 0);
>> +    }
>>      if (rx_packets > 0) {
>>          ds_put_format(str,
>> -            "  Rx packets:         %12"PRIu64"  (%.0f Kpps, %.0f 
>> cycles/pkt)\n"
>> +            "  Rx packets:         %12"PRIu64"  (%.0f Kpps",
>> +            rx_packets, (rx_packets / duration) / 1000);
>> +        if (tot_iter) {
>> +            ds_put_format(str, ", %.0f cycles/pkt",
>> +                1.0 * stats[PMD_CYCLES_ITER_BUSY] / rx_packets);
>> +        }
>> +        ds_put_cstr(str, ")\n");
>> +
>> +        ds_put_format(str,
>>              "  Datapath passes:    %12"PRIu64"  (%.2f passes/pkt)\n"
>>              "  - PHWOL hits:       %12"PRIu64"  (%5.1f %%)\n"
>>              "  - MFEX Opt hits:    %12"PRIu64"  (%5.1f %%)\n"
>> @@ -262,11 +272,7 @@ pmd_perf_format_overall_stats(struct ds *str, struct 
>> pmd_perf_stats *s,
>>              "  - EMC hits:         %12"PRIu64"  (%5.1f %%)\n"
>>              "  - SMC hits:         %12"PRIu64"  (%5.1f %%)\n"
>>              "  - Megaflow hits:    %12"PRIu64"  (%5.1f %%, %.2f "
>> -                                                 "subtbl lookups/hit)\n"
>> -            "  - Upcalls:          %12"PRIu64"  (%5.1f %%, %.1f 
>> us/upcall)\n"
>> -            "  - Lost upcalls:     %12"PRIu64"  (%5.1f %%)\n",
>> -            rx_packets, (rx_packets / duration) / 1000,
>> -            1.0 * stats[PMD_CYCLES_ITER_BUSY] / rx_packets,
>> +                                                 "subtbl lookups/hit)\n",
>>              passes, 1.0 * passes / rx_packets,
>>              stats[PMD_STAT_PHWOL_HIT],
>>              100.0 * stats[PMD_STAT_PHWOL_HIT] / passes,
>> @@ -282,11 +288,20 @@ pmd_perf_format_overall_stats(struct ds *str, struct 
>> pmd_perf_stats *s,
>>              100.0 * stats[PMD_STAT_MASKED_HIT] / passes,
>>              stats[PMD_STAT_MASKED_HIT]
>>              ? 1.0 * stats[PMD_STAT_MASKED_LOOKUP] / 
>> stats[PMD_STAT_MASKED_HIT]
>> -            : 0,
>> -            upcalls, 100.0 * upcalls / passes,
>> -            upcalls ? (upcall_cycles * us_per_cycle) / upcalls : 0,
>> -            stats[PMD_STAT_LOST],
>> -            100.0 * stats[PMD_STAT_LOST] / passes);
>> +            : 0);
>> +
>> +        ds_put_format(str,
>> +            "  - Upcalls:          %12"PRIu64"  (%5.1f %%",
>> +            upcalls, 100.0 * upcalls / passes);
>> +        if (tot_iter) {
>> +            ds_put_format(str, ", %.1f us/upcall",
>> +                upcalls ? (upcall_cycles * us_per_cycle) / upcalls : 0);
>> +        }
>> +        ds_put_cstr(str, ")\n");
>> +
>> +        ds_put_format(str,
>> +            "  - Lost upcalls:     %12"PRIu64"  (%5.1f %%)\n",
>> +            stats[PMD_STAT_LOST], 100.0 * stats[PMD_STAT_LOST] / passes);
>>      } else {
>>          ds_put_format(str,
>>              "  Rx packets:         %12d\n", 0);
>> diff --git a/lib/dpif-netdev-perf.h b/lib/dpif-netdev-perf.h
>> index 84beced15..8a41afa8a 100644
>> --- a/lib/dpif-netdev-perf.h
>> +++ b/lib/dpif-netdev-perf.h
>> @@ -317,7 +317,7 @@ void pmd_perf_read_counters(struct pmd_perf_stats *s,
>>   * NON-PMD they might be updated from multiple threads, but we can live
>>   * with losing a rare update as 100% accuracy is not required.
>>   * However, as counters are read for display from outside the PMD thread
>> - * with e.g. pmd-stats-show, we make sure that the 64-bit read and store
>> + * with e.g. pmd-perf-show, we make sure that the 64-bit read and store
>>   * operations are atomic also on 32-bit systems so that readers cannot
>>   * not read garbage. On 64-bit systems this incurs no overhead. */
>>  
>> diff --git a/lib/dpif-netdev-unixctl.man b/lib/dpif-netdev-unixctl.man
>> index 8cd847416..3d5ab437c 100644
>> --- a/lib/dpif-netdev-unixctl.man
>> +++ b/lib/dpif-netdev-unixctl.man
>> @@ -6,44 +6,22 @@ argument can be omitted. By default the commands present 
>> data for all pmd
>>  threads in the datapath. By specifying the "-pmd Core" option one can filter
>>  the output for a single pmd in the datapath.
>>  .
>> -.IP "\fBdpif-netdev/pmd-stats-show\fR [\fB-pmd\fR \fIcore\fR] [\fIdp\fR]"
>> -Shows performance statistics for one or all pmd threads of the datapath
>> -\fIdp\fR. The special thread "main" sums up the statistics of every non pmd
>> -thread.
>> -
>> -The sum of "phwol hits", "simple match hits", "emc hits", "smc hits",
>> -"megaflow hits" and "miss" is the number of packet lookups performed by the
>> -datapath. Beware that a recirculated packet experiences one additional 
>> lookup
>> -per recirculation, so there may be more lookups than forwarded packets in 
>> the
>> -datapath.
>> -
>> -The MFEX Opt hits displays the number of packets that are processed by the
>> -optimized miniflow extract implementations.
>> -
>> -Cycles are counted using the TSC or similar facilities (when available on
>> -the platform). The duration of one cycle depends on the processing platform.
>> -
>> -"idle cycles" refers to cycles spent in PMD iterations not forwarding any
>> -any packets. "processing cycles" refers to cycles spent in PMD iterations
>> -forwarding at least one packet, including the cost for polling, processing 
>> and
>> -transmitting said packets.
>> -
>> -To reset these counters use \fBdpif-netdev/pmd-stats-clear\fR.
>> -.
>>  .IP "\fBdpif-netdev/pmd-stats-clear\fR [\fIdp\fR]"
>>  Resets to zero the per pmd thread performance numbers shown by the
>> -\fBdpif-netdev/pmd-stats-show\fR and \fBdpif-netdev/pmd-perf-show\fR 
>> commands.
>> -It will NOT reset datapath or bridge statistics, only the values shown by
>> -the above commands.
>> +\fBdpif-netdev/pmd-perf-show\fR command.  It will NOT reset datapath or 
>> bridge
>> +statistics, only the values shown by the above command.
>>  .
>>  .IP "\fBdpif-netdev/pmd-perf-show\fR [\fB-nh\fR] [\fB-it\fR \fIiter_len\fR] 
>> \
>>  [\fB-ms\fR \fIms_len\fR] [\fB-pmd\fR \fIcore\fR] [\fIdp\fR]"
>>  Shows detailed performance metrics for one or all pmds threads of the
>> -user space datapath.
>> +user space datapath.  The special thread "main" sums up the statistics of 
>> every
>> +non pmd thread.
>>  
>> -The collection of detailed statistics can be controlled by a new
>> -configuration parameter "other_config:pmd-perf-metrics". By default it
>> -is disabled. The run-time overhead, when enabled, is in the order of 1%.
>> +The collection of additional detailed statistics can be controlled by a
>> +configuration parameter \fBother-config:pmd-perf-metrics\fR.  By default it 
>> is
>> +disabled.  The run-time overhead, when enabled, is in the order of 1%.
>> +
>> +Collected statistics include:
>>  
>>  .RS
>>  .IP
>> @@ -153,8 +131,26 @@ pmd thread numa_id 0 core_id 1:
>>  .RE
>>  .IP
>>  Here "Rx packets" actually reflects the number of packets forwarded by the
>> -datapath. "Datapath passes" matches the number of packet lookups as
>> -reported by the \fBdpif-netdev/pmd-stats-show\fR command.
>> +datapath.
>> +
>> +The sum of "PHWOL hits", "Simple Match hits", "EMC hits", "SMC hits",
>> +"Megaflow hits" and "Upcalls" is the number of packet lookups performed by 
>> the
>> +datapath and it is reported as "Datapath passes".  Beware that a 
>> recirculated
>> +packet experiences one additional lookup per recirculation, so there may be
>> +more lookups than forwarded packets in the datapath.
>> +
>> +The "MFEX Opt hits" displays the number of packets that are processed by the
>> +optimized miniflow extract implementations.
>> +
>> +Cycles are counted using the TSC or similar facilities (when available on
>> +the platform).  The duration of one cycle depends on the processing 
>> platform.
>> +Statistics based on cycles are not reported for the "main" thread, since the
>> +accurate accounting of CPU cycles is not possible in this case.
>> +
>> +"idle iterations" refers to PMD iterations that didn't not result in 
>> processing
> 
> typo, "didn't not"

Yep.  Thanks!

Best regards, Ilya Maximets.
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to