From 515995e4e010c1362561ff9bea6f51d712704739 Mon Sep 17 00:00:00 2001 From: Sebastien GODARD Date: Sun, 7 Apr 2019 18:45:35 +0200 Subject: [PATCH] sadf: PCP: Add support for A_NET_SOFT activity Add metrics displayed by "sar -n SOFT" (network softnet statistics) to PCP archive. Signed-off-by: Sebastien GODARD --- activity.c | 1 + pcp_def_metrics.c | 48 +++++++++++++++++++++++++++++- pcp_stats.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++ pcp_stats.h | 2 ++ sadf_misc.c | 1 + 5 files changed, 126 insertions(+), 1 deletion(-) diff --git a/activity.c b/activity.c index 0fc8d6f..7fd095d 100644 --- a/activity.c +++ b/activity.c @@ -1845,6 +1845,7 @@ struct activity softnet_act = { .f_json_print = json_print_softnet_stats, .f_svg_print = svg_print_softnet_stats, .f_raw_print = raw_print_softnet_stats, + .f_pcp_print = pcp_print_softnet_stats, .f_count_new = NULL, .item_list = NULL, .desc = "Software-based network processing statistics", diff --git a/pcp_def_metrics.c b/pcp_def_metrics.c index fd8b89e..0eccdba 100644 --- a/pcp_def_metrics.c +++ b/pcp_def_metrics.c @@ -31,7 +31,7 @@ /* *************************************************************************** - * Define PCP metrics for CPU statistics. + * Define PCP metrics for CPU related statistics. * * IN: * @a Activity structure with statistics. @@ -105,6 +105,29 @@ void pcp_def_cpu_metrics(struct activity *a) PM_IN_NULL, PM_TYPE_FLOAT, PM_INDOM_NULL, PM_SEM_INSTANT, pmiUnits(0, 0, 0, 0, 0, 0)); } + + else if (a->id == A_NET_SOFT) { + /* Create metrics for a_NET_SOFT */ + pmiAddMetric("network.all.soft.processed", + PM_IN_NULL, PM_TYPE_FLOAT, PM_INDOM_NULL, PM_SEM_INSTANT, + pmiUnits(0, -1, 1, 0, PM_TIME_SEC, PM_COUNT_ONE)); + + pmiAddMetric("network.all.soft.dropped", + PM_IN_NULL, PM_TYPE_FLOAT, PM_INDOM_NULL, PM_SEM_INSTANT, + pmiUnits(0, -1, 1, 0, PM_TIME_SEC, PM_COUNT_ONE)); + + pmiAddMetric("network.all.soft.time_squeeze", + PM_IN_NULL, PM_TYPE_FLOAT, PM_INDOM_NULL, PM_SEM_INSTANT, + pmiUnits(0, -1, 1, 0, PM_TIME_SEC, PM_COUNT_ONE)); + + pmiAddMetric("network.all.soft.received_rps", + PM_IN_NULL, PM_TYPE_FLOAT, PM_INDOM_NULL, PM_SEM_INSTANT, + pmiUnits(0, -1, 1, 0, PM_TIME_SEC, PM_COUNT_ONE)); + + pmiAddMetric("network.all.soft.flow_limit", + PM_IN_NULL, PM_TYPE_FLOAT, PM_INDOM_NULL, PM_SEM_INSTANT, + pmiUnits(0, -1, 1, 0, PM_TIME_SEC, PM_COUNT_ONE)); + } } else { /* This is not CPU "all" */ @@ -169,6 +192,29 @@ void pcp_def_cpu_metrics(struct activity *a) PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT, pmiUnits(0, 0, 0, 0, 0, 0)); } + + else if (a->id == A_NET_SOFT) { + /* Create metrics for a_NET_SOFT */ + pmiAddMetric("network.percpu.soft.processed", + PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT, + pmiUnits(0, -1, 1, 0, PM_TIME_SEC, PM_COUNT_ONE)); + + pmiAddMetric("network.percpu.soft.dropped", + PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT, + pmiUnits(0, -1, 1, 0, PM_TIME_SEC, PM_COUNT_ONE)); + + pmiAddMetric("network.percpu.soft.time_squeeze", + PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT, + pmiUnits(0, -1, 1, 0, PM_TIME_SEC, PM_COUNT_ONE)); + + pmiAddMetric("network.percpu.soft.received_rps", + PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT, + pmiUnits(0, -1, 1, 0, PM_TIME_SEC, PM_COUNT_ONE)); + + pmiAddMetric("network.percpu.soft.flow_limit", + PM_IN_NULL, PM_TYPE_FLOAT, indom, PM_SEM_INSTANT, + pmiUnits(0, -1, 1, 0, PM_TIME_SEC, PM_COUNT_ONE)); + } first = FALSE; } } diff --git a/pcp_stats.c b/pcp_stats.c index cc6a3ce..b894ecf 100644 --- a/pcp_stats.c +++ b/pcp_stats.c @@ -1735,3 +1735,78 @@ __print_funct_t pcp_print_pwr_cpufreq_stats(struct activity *a, int curr, unsign } #endif /* HAVE_PCP */ } + +/* + *************************************************************************** + * Display softnet 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_softnet_stats(struct activity *a, int curr, unsigned long long itv, + struct record_header *record_hdr) +{ +#ifdef HAVE_PCP + int i; + struct stats_softnet *ssnc, *ssnp; + char buf[64], cpuno[64]; + unsigned char offline_cpu_bitmap[BITMAP_SIZE(NR_CPUS)] = {0}; + char *str; + + /* + * @nr[curr] cannot normally be greater than @nr_ini. + * Yet we have created PCP metrics only for @nr_ini CPU. + */ + if (a->nr[curr] > a->nr_ini) { + a->nr_ini = a->nr[curr]; + } + + /* Compute statistics for CPU "all" */ + get_global_soft_statistics(a, !curr, curr, flags, offline_cpu_bitmap); + + for (i = 0; (i < a->nr_ini) && (i < a->bitmap->b_size + 1); i++) { + + /* Should current CPU (including CPU "all") be displayed? */ + if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))) || + offline_cpu_bitmap[i >> 3] & (1 << (i & 0x07))) + /* No */ + continue; + + ssnc = (struct stats_softnet *) ((char *) a->buf[curr] + i * a->msize); + ssnp = (struct stats_softnet *) ((char *) a->buf[!curr] + i * a->msize); + + if (!i) { + /* This is CPU "all" */ + str = NULL; + } + else { + sprintf(cpuno, "cpu%d", i - 1); + str = cpuno; + } + + snprintf(buf, sizeof(buf), "%f", + S_VALUE(ssnp->processed, ssnc->processed, itv)); + pmiPutValue(i ? "network.percpu.soft.processed" : "network.all.soft.processed", str, buf); + + snprintf(buf, sizeof(buf), "%f", + S_VALUE(ssnp->dropped, ssnc->dropped, itv)); + pmiPutValue(i ? "network.percpu.soft.dropped" : "network.all.soft.dropped", str, buf); + + snprintf(buf, sizeof(buf), "%f", + S_VALUE(ssnp->time_squeeze, ssnc->time_squeeze, itv)); + pmiPutValue(i ? "network.percpu.soft.time_squeeze" : "network.all.soft.time_squeeze", str, buf); + + snprintf(buf, sizeof(buf), "%f", + S_VALUE(ssnp->received_rps, ssnc->received_rps, itv)); + pmiPutValue(i ? "network.percpu.soft.received_rps" : "network.all.soft.received_rps", str, buf); + + snprintf(buf, sizeof(buf), "%f", + S_VALUE(ssnp->flow_limit, ssnc->flow_limit, itv)); + pmiPutValue(i ? "network.percpu.soft.flow_limit" : "network.all.soft.flow_limit", str, buf); + } +#endif /* HAVE_PCP */ +} diff --git a/pcp_stats.h b/pcp_stats.h index 17e378c..24b88de 100644 --- a/pcp_stats.h +++ b/pcp_stats.h @@ -71,5 +71,7 @@ __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 *); +__print_funct_t pcp_print_softnet_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 9211f2b..8d07038 100644 --- a/sadf_misc.c +++ b/sadf_misc.c @@ -502,6 +502,7 @@ __printf_funct_t print_pcp_statistics(int *tab, int action, struct activity *act case A_CPU: case A_PWR_CPU: + case A_NET_SOFT: pcp_def_cpu_metrics(act[p]); break; -- 2.40.0