From 8deb1e1fe5c4fe3bc772e4d6fad31e36dfbbe5f9 Mon Sep 17 00:00:00 2001 From: Sebastien GODARD Date: Sat, 6 Apr 2019 17:14:31 +0200 Subject: [PATCH] sadf: PCP: Add support for A_PWR_CPU activity Add metrics displayed by "sar -m CPU" (CPU frequency statistics) to PCP archive. Signed-off-by: Sebastien GODARD --- activity.c | 1 + pcp_def_metrics.c | 155 +++++++++++++++++++++++++++------------------- pcp_stats.c | 44 +++++++++++++ pcp_stats.h | 2 + sadf_misc.c | 1 + 5 files changed, 139 insertions(+), 64 deletions(-) diff --git a/activity.c b/activity.c index bafa38e..0fc8d6f 100644 --- a/activity.c +++ b/activity.c @@ -1437,6 +1437,7 @@ struct activity pwr_cpufreq_act = { .f_json_print = json_print_pwr_cpufreq_stats, .f_svg_print = svg_print_pwr_cpufreq_stats, .f_raw_print = raw_print_pwr_cpufreq_stats, + .f_pcp_print = pcp_print_pwr_cpufreq_stats, .f_count_new = NULL, .item_list = NULL, .desc = "CPU clock frequency", diff --git a/pcp_def_metrics.c b/pcp_def_metrics.c index 04a0e36..fd8b89e 100644 --- a/pcp_def_metrics.c +++ b/pcp_def_metrics.c @@ -40,9 +40,9 @@ void pcp_def_cpu_metrics(struct activity *a) { #ifdef HAVE_PCP - int i, first = TRUE; + int i, first = TRUE, create = FALSE; char buf[64]; - pmInDom indom; + static pmInDom indom = PM_INDOM_NULL; for (i = 0; (i < a->nr_ini) && (i < a->bitmap->b_size + 1); i++) { @@ -56,94 +56,121 @@ void pcp_def_cpu_metrics(struct activity *a) continue; if (!i) { - /* This is CPU "all" */ - pmiAddMetric("kernel.all.cpu.user", + if (a->id == A_CPU) { + /* This is CPU "all" */ + pmiAddMetric("kernel.all.cpu.user", PM_IN_NULL, PM_TYPE_FLOAT, PM_INDOM_NULL, PM_SEM_INSTANT, pmiUnits(0, 0, 0, 0, 0, 0)); - pmiAddMetric("kernel.all.cpu.nice", - PM_IN_NULL, PM_TYPE_FLOAT, PM_INDOM_NULL, PM_SEM_INSTANT, - pmiUnits(0, 0, 0, 0, 0, 0)); + pmiAddMetric("kernel.all.cpu.nice", + PM_IN_NULL, PM_TYPE_FLOAT, PM_INDOM_NULL, PM_SEM_INSTANT, + pmiUnits(0, 0, 0, 0, 0, 0)); - pmiAddMetric("kernel.all.cpu.sys", - PM_IN_NULL, PM_TYPE_FLOAT, PM_INDOM_NULL, PM_SEM_INSTANT, - pmiUnits(0, 0, 0, 0, 0, 0)); + pmiAddMetric("kernel.all.cpu.sys", + PM_IN_NULL, PM_TYPE_FLOAT, PM_INDOM_NULL, PM_SEM_INSTANT, + pmiUnits(0, 0, 0, 0, 0, 0)); - pmiAddMetric("kernel.all.cpu.idle", - PM_IN_NULL, PM_TYPE_FLOAT, PM_INDOM_NULL, PM_SEM_INSTANT, - pmiUnits(0, 0, 0, 0, 0, 0)); + pmiAddMetric("kernel.all.cpu.idle", + PM_IN_NULL, PM_TYPE_FLOAT, PM_INDOM_NULL, PM_SEM_INSTANT, + pmiUnits(0, 0, 0, 0, 0, 0)); - pmiAddMetric("kernel.all.cpu.iowait", - PM_IN_NULL, PM_TYPE_FLOAT, PM_INDOM_NULL, PM_SEM_INSTANT, - pmiUnits(0, 0, 0, 0, 0, 0)); + pmiAddMetric("kernel.all.cpu.iowait", + PM_IN_NULL, PM_TYPE_FLOAT, PM_INDOM_NULL, PM_SEM_INSTANT, + pmiUnits(0, 0, 0, 0, 0, 0)); - pmiAddMetric("kernel.all.cpu.steal", - PM_IN_NULL, PM_TYPE_FLOAT, PM_INDOM_NULL, PM_SEM_INSTANT, - pmiUnits(0, 0, 0, 0, 0, 0)); + pmiAddMetric("kernel.all.cpu.steal", + PM_IN_NULL, PM_TYPE_FLOAT, PM_INDOM_NULL, PM_SEM_INSTANT, + pmiUnits(0, 0, 0, 0, 0, 0)); - pmiAddMetric("kernel.all.cpu.hardirq", - PM_IN_NULL, PM_TYPE_FLOAT, PM_INDOM_NULL, PM_SEM_INSTANT, - pmiUnits(0, 0, 0, 0, 0, 0)); + pmiAddMetric("kernel.all.cpu.hardirq", + PM_IN_NULL, PM_TYPE_FLOAT, PM_INDOM_NULL, PM_SEM_INSTANT, + pmiUnits(0, 0, 0, 0, 0, 0)); - pmiAddMetric("kernel.all.cpu.softirq", - PM_IN_NULL, PM_TYPE_FLOAT, PM_INDOM_NULL, PM_SEM_INSTANT, - pmiUnits(0, 0, 0, 0, 0, 0)); + pmiAddMetric("kernel.all.cpu.softirq", + PM_IN_NULL, PM_TYPE_FLOAT, PM_INDOM_NULL, PM_SEM_INSTANT, + pmiUnits(0, 0, 0, 0, 0, 0)); - pmiAddMetric("kernel.all.cpu.guest", - PM_IN_NULL, PM_TYPE_FLOAT, PM_INDOM_NULL, PM_SEM_INSTANT, - pmiUnits(0, 0, 0, 0, 0, 0)); + pmiAddMetric("kernel.all.cpu.guest", + PM_IN_NULL, PM_TYPE_FLOAT, PM_INDOM_NULL, PM_SEM_INSTANT, + pmiUnits(0, 0, 0, 0, 0, 0)); - pmiAddMetric("kernel.all.cpu.guest_nice", - PM_IN_NULL, PM_TYPE_FLOAT, PM_INDOM_NULL, PM_SEM_INSTANT, - pmiUnits(0, 0, 0, 0, 0, 0)); + pmiAddMetric("kernel.all.cpu.guest_nice", + PM_IN_NULL, PM_TYPE_FLOAT, PM_INDOM_NULL, PM_SEM_INSTANT, + pmiUnits(0, 0, 0, 0, 0, 0)); + } + + else if (a->id == A_PWR_CPU) { + /* Create metric for A_PWR_CPU */ + pmiAddMetric("kernel.all.cpu.freqMHz", + PM_IN_NULL, PM_TYPE_FLOAT, PM_INDOM_NULL, PM_SEM_INSTANT, + pmiUnits(0, 0, 0, 0, 0, 0)); + } } else { - if (first) { + /* This is not CPU "all" */ + if (indom == PM_INDOM_NULL) { + /* Create domain */ indom = pmInDom_build(0, PM_INDOM_CPU); + create = TRUE; + } + if (create) { + /* Create instance for current CPU */ + sprintf(buf, "cpu%d", i - 1); + pmiAddInstance(indom, buf, i - 1); + } - pmiAddMetric("kernel.percpu.cpu.user", - PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT, - pmiUnits(0, 0, 0, 0, 0, 0)); + if (first) { + if (a->id == A_CPU) { + /* Create metrics for A_CPU */ + pmiAddMetric("kernel.percpu.cpu.user", + PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT, + pmiUnits(0, 0, 0, 0, 0, 0)); - pmiAddMetric("kernel.percpu.cpu.nice", - PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT, - pmiUnits(0, 0, 0, 0, 0, 0)); + pmiAddMetric("kernel.percpu.cpu.nice", + PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT, + pmiUnits(0, 0, 0, 0, 0, 0)); - pmiAddMetric("kernel.percpu.cpu.sys", - PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT, - pmiUnits(0, 0, 0, 0, 0, 0)); + pmiAddMetric("kernel.percpu.cpu.sys", + PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT, + pmiUnits(0, 0, 0, 0, 0, 0)); - pmiAddMetric("kernel.percpu.cpu.idle", - PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT, - pmiUnits(0, 0, 0, 0, 0, 0)); + pmiAddMetric("kernel.percpu.cpu.idle", + PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT, + pmiUnits(0, 0, 0, 0, 0, 0)); - pmiAddMetric("kernel.percpu.cpu.iowait", - PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT, - pmiUnits(0, 0, 0, 0, 0, 0)); + pmiAddMetric("kernel.percpu.cpu.iowait", + PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT, + pmiUnits(0, 0, 0, 0, 0, 0)); - pmiAddMetric("kernel.percpu.cpu.steal", - PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT, - pmiUnits(0, 0, 0, 0, 0, 0)); + pmiAddMetric("kernel.percpu.cpu.steal", + PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT, + pmiUnits(0, 0, 0, 0, 0, 0)); - pmiAddMetric("kernel.percpu.cpu.hardirq", - PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT, - pmiUnits(0, 0, 0, 0, 0, 0)); + pmiAddMetric("kernel.percpu.cpu.hardirq", + PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT, + pmiUnits(0, 0, 0, 0, 0, 0)); - pmiAddMetric("kernel.percpu.cpu.softirq", - PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT, - pmiUnits(0, 0, 0, 0, 0, 0)); + pmiAddMetric("kernel.percpu.cpu.softirq", + PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT, + pmiUnits(0, 0, 0, 0, 0, 0)); - pmiAddMetric("kernel.percpu.cpu.guest", - PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT, - pmiUnits(0, 0, 0, 0, 0, 0)); + pmiAddMetric("kernel.percpu.cpu.guest", + PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT, + pmiUnits(0, 0, 0, 0, 0, 0)); - pmiAddMetric("kernel.percpu.cpu.guest_nice", - PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT, - pmiUnits(0, 0, 0, 0, 0, 0)); + pmiAddMetric("kernel.percpu.cpu.guest_nice", + PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT, + pmiUnits(0, 0, 0, 0, 0, 0)); + } + + else if (a->id == A_PWR_CPU) { + /* Create metric for A_PWR_CPU */ + pmiAddMetric("kernel.percpu.cpu.freqMHz", + PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT, + pmiUnits(0, 0, 0, 0, 0, 0)); + } first = FALSE; } - sprintf(buf, "cpu%d", i - 1); - pmiAddInstance(indom, buf, i - 1); } } #endif /* HAVE_PCP */ diff --git a/pcp_stats.c b/pcp_stats.c index 653a041..cc6a3ce 100644 --- a/pcp_stats.c +++ b/pcp_stats.c @@ -1691,3 +1691,47 @@ __print_funct_t pcp_print_net_udp6_stats(struct activity *a, int curr, unsigned pmiPutValue("network.snmp.udp6.udpInErrors", NULL, buf); #endif /* HAVE_PCP */ } + +/* + *************************************************************************** + * Display CPU frequency statistics in PCP format. + * + * IN: + * @a Activity structure with statistics. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + * @record_hdr Record header for current sample. + *************************************************************************** + */ +__print_funct_t pcp_print_pwr_cpufreq_stats(struct activity *a, int curr, unsigned long long itv, + struct record_header *record_hdr) +{ +#ifdef HAVE_PCP + int i; + struct stats_pwr_cpufreq *spc; + char buf[64], cpuno[64]; + char *str; + + for (i = 0; (i < a->nr[curr]) && (i < a->bitmap->b_size + 1); i++) { + + spc = (struct stats_pwr_cpufreq *) ((char *) a->buf[curr] + i * a->msize); + + /* Should current CPU (including CPU "all") be displayed? */ + if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07)))) + /* No */ + continue; + + if (!i) { + /* This is CPU "all" */ + str = NULL; + } + else { + sprintf(cpuno, "cpu%d", i - 1); + str = cpuno; + } + + snprintf(buf, sizeof(buf), "%f", ((double) spc->cpufreq) / 100); + pmiPutValue(i ? "kernel.percpu.cpu.freqMHz" : "kernel.all.cpu.freqMHz", str, buf); + } +#endif /* HAVE_PCP */ +} diff --git a/pcp_stats.h b/pcp_stats.h index 7634e8c..17e378c 100644 --- a/pcp_stats.h +++ b/pcp_stats.h @@ -69,5 +69,7 @@ __print_funct_t pcp_print_net_eicmp6_stats (struct activity *, int, unsigned long long, struct record_header *); __print_funct_t pcp_print_net_udp6_stats (struct activity *, int, unsigned long long, struct record_header *); +__print_funct_t pcp_print_pwr_cpufreq_stats + (struct activity *, int, unsigned long long, struct record_header *); #endif /* _PCP_STATS_H */ diff --git a/sadf_misc.c b/sadf_misc.c index c98b03c..30f924b 100644 --- a/sadf_misc.c +++ b/sadf_misc.c @@ -501,6 +501,7 @@ __printf_funct_t print_pcp_statistics(int *tab, int action, struct activity *act switch (act[p]->id) { case A_CPU: + case A_PWR_CPU: pcp_def_cpu_metrics(act[p]); break; -- 2.40.0