Skip to content

Commit

Permalink
sar: A_NET_SOFT: Fix how average backlog length is calculated
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
sysstat committed Mar 27, 2022
1 parent 690afe9 commit d653467
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 5 deletions.
2 changes: 1 addition & 1 deletion activity.c
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
75 changes: 71 additions & 4 deletions pr_stats.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);

Expand Down Expand Up @@ -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);
}

/*
Expand Down
2 changes: 2 additions & 0 deletions pr_stats.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit d653467

Please sign in to comment.