> On Feb 25, 2015, at 8:43 AM, Daniele Di Proietto <[email protected]>
> wrote:
>
>
(snip)
>
> +enum pmd_info_type {
> + PMD_INFO_SHOW_STATS, /* show how cpu cycles are spent */
> + PMD_INFO_CLEAR_STATS /* set the cycles count to 0 */
> +};
> +
> +static void
> +dpif_netdev_pmd_info(struct unixctl_conn *conn, int argc, const char *argv[],
> + void *aux)
> +{
> + struct ds reply = DS_EMPTY_INITIALIZER;
> + struct dp_netdev_pmd_thread *pmd;
> + struct dp_netdev *dp = NULL;
> + enum pmd_info_type type = (enum pmd_info_type) aux;
> +
> + ovs_mutex_lock(&dp_netdev_mutex);
> +
> + if (argc == 2) {
> + dp = shash_find_data(&dp_netdevs, argv[1]);
> + } else if (shash_count(&dp_netdevs) == 1) {
> + /* There's only one datapath */
> + dp = shash_random_node(&dp_netdevs)->data;
> + }
> +
> + if (!dp) {
> + ovs_mutex_unlock(&dp_netdev_mutex);
> + unixctl_command_reply_error(conn,
> + "please specify an existing datapath");
> + return;
> + }
> +
> + CMAP_FOR_EACH (pmd, node, &dp->poll_threads) {
> + struct dp_netdev_pmd_stats s;
> + struct dp_netdev_pmd_cycles t;
> + unsigned long long total_packets = 0;
> + uint64_t total_cycles = 0;
> + int i;
> +
> + if (type == PMD_INFO_CLEAR_STATS) {
> + /* We cannot write 'stats' and 'cycles' (because they're written
> + * by other threads) and we shouldn't change 'stats' (because
> + * ther're used to count datapath stats, which must not be
> cleared
> + * here).
> + * Insted, we save the current values and subtract them from the
“instead"
> + * values to be displayed in the future */
> + pmd->cycles_zero = pmd->cycles;
> + pmd->stats_zero = pmd->stats;
It seems to me that this access should be protected with a similar mechanism we
use in cmaps, as any concurrent write by the pmd thread may result the “zero”
versions to be inconsistent, a mixture of the old and new. Or is it the case
that this does not matter? I guess that the cycles and stats need not be
consistent with each other, though.
> + continue;
> + }
> + t = pmd->cycles;
> + s = pmd->stats;
> +
> + for (i = 0; i < ARRAY_SIZE(t.n); i++) {
> + t.n[i] -= pmd->cycles_zero.n[i];
> + total_cycles += t.n[i];
> + }
> + for (i = 0; i < ARRAY_SIZE(s.n); i++) {
> + s.n[i] -= pmd->stats_zero.n[i];
> + if (i != DP_STAT_LOST) {
> + total_packets += s.n[i];
> + }
> + }
> +
Similar concern up here.
> + ds_put_cstr(&reply, (pmd->core_id == NON_PMD_CORE_ID)
> + ?"main thread":"pmd thread");
> +
> + if(pmd->numa_id != OVS_NUMA_UNSPEC) {
> + ds_put_format(&reply, " numa_id %d", pmd->numa_id);
> + }
> + if(pmd->core_id != OVS_CORE_UNSPEC) {
> + ds_put_format(&reply, " core_id %d", pmd->core_id);
> + }
> + ds_put_cstr(&reply, ":\n");
> +
> + ds_put_format(&reply,
> + "\temc hits:%llu\n"
> + "\tmasked hits:%llu\n"
> + "\tmiss:%llu\n"
> + "\tlost:%llu\n",
> + s.n[DP_STAT_EXACT_HIT],
> + s.n[DP_STAT_MASKED_HIT],
> + s.n[DP_STAT_MISS],
> + s.n[DP_STAT_LOST]);
> +
> + if (total_cycles == 0) {
> + ds_put_cstr(&reply, "\tcycles counters not supported\n");
> + continue;
> + }
> +
> + ds_put_format(&reply,
> + "\tpolling cycles:%"PRIu64" (%.02f%%)\n"
> + "\tprocessing cycles:%"PRIu64" (%.02f%%)\n"
> + "\tother cycles:%"PRIu64" (%.02f%%)\n",
> + t.n[PMD_CYCLES_POLLING],
> + t.n[PMD_CYCLES_POLLING]/(double)total_cycles*100,
> + t.n[PMD_CYCLES_PROCESSING],
> + t.n[PMD_CYCLES_PROCESSING]/(double)total_cycles*100,
> + t.n[PMD_CYCLES_OTHER],
> + t.n[PMD_CYCLES_OTHER]/(double)total_cycles*100);
> +
> + if (total_packets == 0) {
> + ds_put_cstr(&reply, "\tno packets processed yet\n");
> + continue;
> + }
> + ds_put_format(&reply,
> + "\tavg cycles per packet: %.02f (%"PRIu64"/%llu)\n",
> + total_cycles/(double)total_packets,
> + total_cycles, total_packets);
> +
> + ds_put_format(&reply,
> + "\tavg processing cycles per packet: %.02f
> (%"PRIu64"/%llu)\n",
> + t.n[PMD_CYCLES_PROCESSING]/(double)total_packets,
> + t.n[PMD_CYCLES_PROCESSING], total_packets);
> + }
> +
> + ovs_mutex_unlock(&dp_netdev_mutex);
> +
> + unixctl_command_reply(conn, ds_cstr(&reply));
> + ds_destroy(&reply);
> +}
> +
> +static int
> +dpif_netdev_init(void)
> +{
> + unixctl_command_register("dpif-netdev/pmd-stats-show", "[dp]",
> + 0, 1, dpif_netdev_pmd_info,
> + (void *)PMD_INFO_SHOW_STATS);
> + unixctl_command_register("dpif-netdev/pmd-stats-clear", "[dp]",
> + 0, 1, dpif_netdev_pmd_info,
> + (void *)PMD_INFO_CLEAR_STATS);
> + return 0;
> +}
> +
> static int
> dpif_netdev_enumerate(struct sset *all_dps,
> const struct dpif_class *dpif_class)
> @@ -2260,7 +2399,7 @@ pmd_cycles_counter_diff(struct dp_netdev_pmd_thread
> *pmd)
> {
> uint64_t old_cycles = pmd->last_cycles,
> #ifdef DPDK_NETDEV
> - new_cycles = rte_get_tsc_cycles();
> + new_cycles = rte_get_timer_cycles();
> #else
> new_cycles = 0;
> #endif
> @@ -3332,7 +3471,7 @@ dp_netdev_execute_actions(struct dp_netdev_pmd_thread
> *pmd,
>
> const struct dpif_class dpif_netdev_class = {
> "netdev",
> - NULL, /* init */
> + dpif_netdev_init,
> dpif_netdev_enumerate,
> dpif_netdev_port_open_type,
> dpif_netdev_open,
> diff --git a/vswitchd/ovs-vswitchd.8.in b/vswitchd/ovs-vswitchd.8.in
> index 7f165ea..26b257b 100644
> --- a/vswitchd/ovs-vswitchd.8.in
> +++ b/vswitchd/ovs-vswitchd.8.in
> @@ -239,6 +239,24 @@ type).
> ..
> .so lib/dpctl.man
> .
> +.SS "DPIF-NETDEV COMMANDS"
> +These commands are used to expose internal information (mostly statistics)
> +about the ``dpif-netdev'' userspace datapath. If there is only one datapath
> +(as is often the case, unless \fBdpctl/\fR commands are used), the \fIdp\fR
> +argument can be omitted.
> +.IP "\fBdpif-netdev/pmd-stats-show\fR [\fIdp\fR]"
> +Shows performance statistics for each pmd thread of the datapath \fIdp\fR.
> +The special thread ``main'' sums up the statistics of every other thread.
> +The sum of ``emc hits'', ``masked hits'' and ``miss'' is the number of
> +packets received by the datapath. Cycles are counted using the TSC or similar
> +facilities (when available on the platform). To reset these counters use
> +\fBdpif-netdev/pmd-stats-clear\fR. The duration of one cycle depends on the
> +measuring infrastructure.
> +.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 command. It will NOT reset datapath or
> +bridge statistics, only the values shown by the above command.
> +.
> .so ofproto/ofproto-dpif-unixctl.man
> .so ofproto/ofproto-unixctl.man
> .so lib/vlog-unixctl.man
> --
> 2.1.4
>
> _______________________________________________
> dev mailing list
> [email protected]
> http://openvswitch.org/mailman/listinfo/dev
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev