From: Sebastien GODARD Date: Sun, 27 Mar 2022 13:38:10 +0000 (+0200) Subject: sar: A_NET_SOFT: Fix how average backlog length is calculated X-Git-Tag: v12.6.0~8 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d65346735a6595dbd461815643b579ebd6e97125;p=sysstat sar: A_NET_SOFT: Fix how average backlog length is calculated Backlog length is an instantaneous value, not a value calculated over the time interval. Its average value should be calculated in a specific way. Signed-off-by: Sebastien GODARD --- diff --git a/activity.c b/activity.c index 0053987..b531b5c 100644 --- a/activity.c +++ b/activity.c @@ -1834,7 +1834,7 @@ struct activity softnet_act = { #endif #ifdef SOURCE_SAR .f_print = print_softnet_stats, - .f_print_avg = print_softnet_stats, + .f_print_avg = print_avg_softnet_stats, #endif #if defined(SOURCE_SAR) || defined(SOURCE_SADF) .hdr_line = "CPU;total/s;dropd/s;squeezd/s;rx_rps/s;flw_lim/s;blg_len", diff --git a/pr_stats.c b/pr_stats.c index 6d4de97..9e5ec88 100644 --- a/pr_stats.c +++ b/pr_stats.c @@ -3007,16 +3007,19 @@ __print_funct_t print_fchost_stats(struct activity *a, int prev, int curr, * @prev Index in array where stats used as reference are. * @curr Index in array for current sample statistics. * @itv Interval of time in 1/100th of a second. + * @dispavg True if displaying average statistics. *************************************************************************** */ -__print_funct_t print_softnet_stats(struct activity *a, int prev, int curr, - unsigned long long itv) +__print_funct_t stub_print_softnet_stats(struct activity *a, int prev, int curr, + unsigned long long itv, int dispavg) { int i; struct stats_softnet *ssnc = (struct stats_softnet *) a->buf[curr], *ssnp = (struct stats_softnet *) a->buf[prev]; unsigned char offline_cpu_bitmap[BITMAP_SIZE(NR_CPUS)] = {0}; + static __nr_t nr_alloc = 0; + static unsigned long long *avg_blg_len = NULL; if (dish || DISPLAY_ZERO_OMIT(flags)) { print_hdr_line(timestamp[!curr], a, FIRST, 7, 9, NULL); @@ -3033,6 +3036,18 @@ __print_funct_t print_softnet_stats(struct activity *a, int prev, int curr, a->nr_ini = a->nr[curr]; } + /* Allocate array for CPU backlog lengths */ + if (!avg_blg_len || (a->nr_ini > nr_alloc)) { + SREALLOC(avg_blg_len, unsigned long long, sizeof(unsigned long long) * a->nr_ini); + + if (a->nr_ini > nr_alloc) { + /* Init additional space allocated */ + memset(avg_blg_len + nr_alloc, 0, + sizeof(unsigned long long) * (a->nr_ini - nr_alloc)); + } + nr_alloc = a->nr_ini; + } + /* Compute statistics for CPU "all" */ get_global_soft_statistics(a, prev, curr, flags, offline_cpu_bitmap); @@ -3078,10 +3093,62 @@ __print_funct_t print_softnet_stats(struct activity *a, int prev, int curr, S_VALUE(ssnp->time_squeeze, ssnc->time_squeeze, itv), S_VALUE(ssnp->received_rps, ssnc->received_rps, itv), S_VALUE(ssnp->flow_limit, ssnc->flow_limit, itv)); - cprintf_u64(NO_UNIT, 1, 9, - (unsigned long long) ssnc->backlog_len); + if (!dispavg) { + /* Display instantaneous value */ + cprintf_u64(NO_UNIT, 1, 9, + (unsigned long long) ssnc->backlog_len); + + /* Used to compute average value */ + avg_blg_len[i] += (unsigned long long ) ssnc->backlog_len; + } + else { + /* Display average value */ + cprintf_f(NO_UNIT, 1, 9, 0, + (double) avg_blg_len[i] / avg_count); + } + printf("\n"); } + + if (dispavg && avg_blg_len) { + free(avg_blg_len); + avg_blg_len = NULL; + nr_alloc = 0; + } +} + +/* + *************************************************************************** + * Display softnet statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_softnet_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + stub_print_softnet_stats(a, prev, curr, itv, FALSE); +} + +/* + *************************************************************************** + * Display average softnet statistics. + * + * IN: + * @a Activity structure with statistics. + * @prev Index in array where stats used as reference are. + * @curr Index in array for current sample statistics. + * @itv Interval of time in 1/100th of a second. + *************************************************************************** + */ +__print_funct_t print_avg_softnet_stats(struct activity *a, int prev, int curr, + unsigned long long itv) +{ + stub_print_softnet_stats(a, prev, curr, itv, TRUE); } /* diff --git a/pr_stats.h b/pr_stats.h index bdb1317..50503e9 100644 --- a/pr_stats.h +++ b/pr_stats.h @@ -126,6 +126,8 @@ __print_funct_t print_avg_pwr_usb_stats (struct activity *, int, int, unsigned long long); __print_funct_t print_avg_filesystem_stats (struct activity *, int, int, unsigned long long); +__print_funct_t print_avg_softnet_stats + (struct activity *, int, int, unsigned long long); __print_funct_t print_avg_psicpu_stats (struct activity *, int, int, unsigned long long); __print_funct_t print_avg_psiio_stats