]> granicus.if.org Git - sysstat/commitdiff
sar: A_NET_SOFT: Fix how average backlog length is calculated
authorSebastien GODARD <sysstat@users.noreply.github.com>
Sun, 27 Mar 2022 13:38:10 +0000 (15:38 +0200)
committerSebastien GODARD <sysstat@users.noreply.github.com>
Sun, 27 Mar 2022 13:38:10 +0000 (15:38 +0200)
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 <sysstat@users.noreply.github.com>
activity.c
pr_stats.c
pr_stats.h

index 0053987a3b1b5a90dcc588c3eb0afc6573e56f1a..b531b5cc33c171c6a23492e1e5c28b84c82e86f8 100644 (file)
@@ -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",
index 6d4de973296e99f759249bb0ea6b9eec71f144c0..9e5ec88a797c20c140f13de645c3a31b3def45b0 100644 (file)
@@ -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);
 }
 
 /*
index bdb1317f2f32716431d5a670911fb5bd73259fff..50503e9f6665fddebb1650c07f9146662cc44925 100644 (file)
@@ -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