]> granicus.if.org Git - sysstat/blobdiff - xml_stats.c
Merge branch 'scop-grep-E'
[sysstat] / xml_stats.c
index f41d520d744999f341aff825577f58d5c37b103e..8d16ed7f94cd287e7ba7c1c32ea1a2ea3d8f44d6 100644 (file)
@@ -1,6 +1,6 @@
 /*
- * xml_stats.c: Funtions used by sadf to display statistics in XML.
- * (C) 1999-2012 by Sebastien GODARD (sysstat <at> orange.fr)
+ * xml_stats.c: Functions used by sadf to display statistics in XML.
+ * (C) 1999-2021 by Sebastien GODARD (sysstat <at> orange.fr)
  *
  ***************************************************************************
  * This program is free software; you can redistribute it and/or modify it *
@@ -15,7 +15,7 @@
  *                                                                         *
  * You should have received a copy of the GNU General Public License along *
  * with this program; if not, write to the Free Software Foundation, Inc., *
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA                   *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA              *
  ***************************************************************************
  */
 
@@ -24,7 +24,6 @@
 #include <stdarg.h>
 
 #include "sa.h"
-#include "sadf.h"
 #include "ioconf.h"
 #include "xml_stats.h"
 
@@ -36,8 +35,7 @@
 #define _(string) (string)
 #endif
 
-extern unsigned int flags;
-extern unsigned int dm_major;
+extern uint64_t flags;
 
 /*
  ***************************************************************************
@@ -93,6 +91,33 @@ void xml_markup_power_management(int tab, int action)
        }
 }
 
+/*
+ ***************************************************************************
+ * Open or close <psi> markup.
+ *
+ * IN:
+ * @tab                Number of tabulations.
+ * @action     Open or close action.
+ ***************************************************************************
+ */
+void xml_markup_psi(int tab, int action)
+{
+       static int markup_state = CLOSE_XML_MARKUP;
+
+       if (action == markup_state)
+               return;
+       markup_state = action;
+
+       if (action == OPEN_XML_MARKUP) {
+               /* Open markup */
+               xprintf(tab, "<psi per=\"second\">");
+       }
+       else {
+               /* Close markup */
+               xprintf(tab, "</psi>");
+       }
+}
+
 /*
  ***************************************************************************
  * Display CPU statistics in XML.
@@ -101,162 +126,157 @@ void xml_markup_power_management(int tab, int action)
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @g_itv      Interval of time in jiffies mutliplied by the number of
- *             processors.
+ * @itv                Interval of time in 1/100th of a second (independent of the
+ *             number of processors). Unused here.
  ***************************************************************************
  */
 __print_funct_t xml_print_cpu_stats(struct activity *a, int curr, int tab,
-                                   unsigned long long g_itv)
+                                   unsigned long long itv)
 {
-       int i, cpu_offline;
+       int i;
+       unsigned long long deltot_jiffies = 1;
        struct stats_cpu *scc, *scp;
-       char cpuno[8];
+       unsigned char offline_cpu_bitmap[BITMAP_SIZE(NR_CPUS)] = {0};
+       char cpuno[16];
+
+       xprintf(tab++, "<cpu-load>");
 
-       if (DISPLAY_CPU_DEF(a->opt_flags)) {
-               xprintf(tab++, "<cpu-load>");
+       /* @nr[curr] cannot normally be greater than @nr_ini */
+       if (a->nr[curr] > a->nr_ini) {
+               a->nr_ini = a->nr[curr];
        }
-       else if (DISPLAY_CPU_ALL(a->opt_flags)) {
-               xprintf(tab++, "<cpu-load-all>");
+
+       /*
+        * Compute CPU "all" as sum of all individual CPU (on SMP machines)
+        * and look for offline CPU.
+        */
+       if (a->nr_ini > 1) {
+               deltot_jiffies = get_global_cpu_statistics(a, !curr, curr,
+                                                          flags, offline_cpu_bitmap);
        }
 
-       for (i = 0; (i < a->nr) && (i < a->bitmap->b_size + 1); i++) {
+       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)))
+                       /* Don't display CPU */
+                       continue;
 
                scc = (struct stats_cpu *) ((char *) a->buf[curr]  + i * a->msize);
                scp = (struct stats_cpu *) ((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))) {
-
-                       /* Yes: Display it */
-                       if (!i) {
-                               /* This is CPU "all" */
-                               strcpy(cpuno, "all");
-                       }
-                       else {
-                               sprintf(cpuno, "%d", i - 1);
+               if (i == 0) {
+                       /* This is CPU "all" */
+                       strcpy(cpuno, "all");
 
+                       if (a->nr_ini == 1) {
                                /*
-                                * If the CPU is offline then it is omited from /proc/stat:
-                                * All the fields couldn't have been read and the sum of them is zero.
-                                * (Remember that guest/guest_nice times are already included in
-                                * user/nice modes.)
+                                * This is a UP machine. In this case
+                                * interval has still not been calculated.
                                 */
-                               if ((scc->cpu_user + scc->cpu_nice + scc->cpu_sys +
-                                    scc->cpu_iowait + scc->cpu_idle + scc->cpu_steal +
-                                    scc->cpu_hardirq + scc->cpu_softirq) == 0) {
-                                       /*
-                                        * Set current struct fields (which have been set to zero)
-                                        * to values from previous iteration. Hence their values won't
-                                        * jump from zero when the CPU comes back online.
-                                        */
-                                       *scc = *scp;
-
-                                       g_itv = 0;
-                                       cpu_offline = TRUE;
-                               }
-                               else {
-                                       /*
-                                        * Recalculate interval for current proc.
-                                        * If result is 0 then current CPU is a tickless one.
-                                        */
-                                       g_itv = get_per_cpu_interval(scc, scp);
-                                       cpu_offline = FALSE;
+                               deltot_jiffies = get_per_cpu_interval(scc, scp);
+                       }
+                       if (!deltot_jiffies) {
+                               /* CPU "all" cannot be tickless */
+                               deltot_jiffies = 1;
+                       }
+               }
+               else {
+                       sprintf(cpuno, "%d", i - 1);
+
+                       /*
+                        * Recalculate interval for current proc.
+                        * If result is 0 then current CPU is a tickless one.
+                        */
+                       deltot_jiffies = get_per_cpu_interval(scc, scp);
+
+                       if (!deltot_jiffies) {
+                               /* Current CPU is tickless */
+                               if (DISPLAY_CPU_DEF(a->opt_flags)) {
+                                       xprintf(tab, "<cpu number=\"%d\" "
+                                               "user=\"%.2f\" "
+                                               "nice=\"%.2f\" "
+                                               "system=\"%.2f\" "
+                                               "iowait=\"%.2f\" "
+                                               "steal=\"%.2f\" "
+                                               "idle=\"%.2f\"/>",
+                                               i - 1, 0.0, 0.0, 0.0, 0.0, 0.0, 100.0);
                                }
-
-                               if (!g_itv) {
-                                       /* Current CPU is offline or tickless */
-                                       if (DISPLAY_CPU_DEF(a->opt_flags)) {
-                                               xprintf(tab, "<cpu number=\"%d\" "
-                                                       "user=\"%.2f\" "
-                                                       "nice=\"%.2f\" "
-                                                       "system=\"%.2f\" "
-                                                       "iowait=\"%.2f\" "
-                                                       "steal=\"%.2f\" "
-                                                       "idle=\"%.2f\"/>",
-                                                       i - 1, 0.0, 0.0, 0.0, 0.0, 0.0,
-                                                       cpu_offline ? 0.0 : 100.0);
-                                       }
-                                       else if (DISPLAY_CPU_ALL(a->opt_flags)) {
-                                               xprintf(tab, "<cpu number=\"%d\" "
-                                                       "usr=\"%.2f\" "
-                                                       "nice=\"%.2f\" "
-                                                       "sys=\"%.2f\" "
-                                                       "iowait=\"%.2f\" "
-                                                       "steal=\"%.2f\" "
-                                                       "irq=\"%.2f\" "
-                                                       "soft=\"%.2f\" "
-                                                       "guest=\"%.2f\" "
-                                                       "gnice=\"%.2f\" "
-                                                       "idle=\"%.2f\"/>",
-                                                       i - 1, 0.0, 0.0, 0.0, 0.0,
-                                                       0.0, 0.0, 0.0, 0.0, 0.0,
-                                                       cpu_offline ? 0.0 : 100.0);
-                                       }
-                                       continue;
+                               else if (DISPLAY_CPU_ALL(a->opt_flags)) {
+                                       xprintf(tab, "<cpu number=\"%d\" "
+                                               "usr=\"%.2f\" "
+                                               "nice=\"%.2f\" "
+                                               "sys=\"%.2f\" "
+                                               "iowait=\"%.2f\" "
+                                               "steal=\"%.2f\" "
+                                               "irq=\"%.2f\" "
+                                               "soft=\"%.2f\" "
+                                               "guest=\"%.2f\" "
+                                               "gnice=\"%.2f\" "
+                                               "idle=\"%.2f\"/>",
+                                               i - 1, 0.0, 0.0, 0.0, 0.0,
+                                               0.0, 0.0, 0.0, 0.0, 0.0, 100.0);
                                }
+                               continue;
                        }
+               }
 
-                       if (DISPLAY_CPU_DEF(a->opt_flags)) {
-                               xprintf(tab, "<cpu number=\"%s\" "
-                                       "user=\"%.2f\" "
-                                       "nice=\"%.2f\" "
-                                       "system=\"%.2f\" "
-                                       "iowait=\"%.2f\" "
-                                       "steal=\"%.2f\" "
-                                       "idle=\"%.2f\"/>",
-                                       cpuno,
-                                       ll_sp_value(scp->cpu_user,   scc->cpu_user,   g_itv),
-                                       ll_sp_value(scp->cpu_nice,   scc->cpu_nice,   g_itv),
-                                       ll_sp_value(scp->cpu_sys + scp->cpu_hardirq + scp->cpu_softirq,
-                                                   scc->cpu_sys + scc->cpu_hardirq + scc->cpu_softirq,
-                                                   g_itv),
-                                       ll_sp_value(scp->cpu_iowait, scc->cpu_iowait, g_itv),
-                                       ll_sp_value(scp->cpu_steal,  scc->cpu_steal,  g_itv),
-                                       scc->cpu_idle < scp->cpu_idle ?
-                                       0.0 :
-                                       ll_sp_value(scp->cpu_idle,   scc->cpu_idle,   g_itv));
-                       }
-                       else if (DISPLAY_CPU_ALL(a->opt_flags)) {
-                               xprintf(tab, "<cpu number=\"%s\" "
-                                       "usr=\"%.2f\" "
-                                       "nice=\"%.2f\" "
-                                       "sys=\"%.2f\" "
-                                       "iowait=\"%.2f\" "
-                                       "steal=\"%.2f\" "
-                                       "irq=\"%.2f\" "
-                                       "soft=\"%.2f\" "
-                                       "guest=\"%.2f\" "
-                                       "gnice=\"%.2f\" "
-                                       "idle=\"%.2f\"/>",
-                                       cpuno,
-                                       (scc->cpu_user - scc->cpu_guest) < (scp->cpu_user - scp->cpu_guest) ?
-                                       0.0 :
-                                       ll_sp_value(scp->cpu_user - scp->cpu_guest,
-                                                   scc->cpu_user - scc->cpu_guest, g_itv),
-                                       (scc->cpu_nice - scc->cpu_guest_nice) < (scp->cpu_nice - scp->cpu_guest_nice) ?
-                                       0.0 :
-                                       ll_sp_value(scp->cpu_nice - scp->cpu_guest_nice,
-                                                   scc->cpu_nice - scc->cpu_guest_nice, g_itv),
-                                       ll_sp_value(scp->cpu_sys, scc->cpu_sys, g_itv),
-                                       ll_sp_value(scp->cpu_iowait, scc->cpu_iowait, g_itv),
-                                       ll_sp_value(scp->cpu_steal, scc->cpu_steal, g_itv),
-                                       ll_sp_value(scp->cpu_hardirq, scc->cpu_hardirq, g_itv),
-                                       ll_sp_value(scp->cpu_softirq, scc->cpu_softirq, g_itv),
-                                       ll_sp_value(scp->cpu_guest, scc->cpu_guest, g_itv),
-                                       ll_sp_value(scp->cpu_guest_nice, scc->cpu_guest_nice, g_itv),
-                                       scc->cpu_idle < scp->cpu_idle ?
-                                       0.0 :
-                                       ll_sp_value(scp->cpu_idle, scc->cpu_idle, g_itv));
-                       }
+               if (DISPLAY_CPU_DEF(a->opt_flags)) {
+                       xprintf(tab, "<cpu number=\"%s\" "
+                               "user=\"%.2f\" "
+                               "nice=\"%.2f\" "
+                               "system=\"%.2f\" "
+                               "iowait=\"%.2f\" "
+                               "steal=\"%.2f\" "
+                               "idle=\"%.2f\"/>",
+                               cpuno,
+                               ll_sp_value(scp->cpu_user, scc->cpu_user, deltot_jiffies),
+                               ll_sp_value(scp->cpu_nice, scc->cpu_nice, deltot_jiffies),
+                               ll_sp_value(scp->cpu_sys + scp->cpu_hardirq + scp->cpu_softirq,
+                                           scc->cpu_sys + scc->cpu_hardirq + scc->cpu_softirq,
+                                           deltot_jiffies),
+                               ll_sp_value(scp->cpu_iowait, scc->cpu_iowait, deltot_jiffies),
+                               ll_sp_value(scp->cpu_steal,  scc->cpu_steal, deltot_jiffies),
+                               scc->cpu_idle < scp->cpu_idle ?
+                               0.0 :
+                               ll_sp_value(scp->cpu_idle, scc->cpu_idle, deltot_jiffies));
+               }
+               else if (DISPLAY_CPU_ALL(a->opt_flags)) {
+                       xprintf(tab, "<cpu number=\"%s\" "
+                               "usr=\"%.2f\" "
+                               "nice=\"%.2f\" "
+                               "sys=\"%.2f\" "
+                               "iowait=\"%.2f\" "
+                               "steal=\"%.2f\" "
+                               "irq=\"%.2f\" "
+                               "soft=\"%.2f\" "
+                               "guest=\"%.2f\" "
+                               "gnice=\"%.2f\" "
+                               "idle=\"%.2f\"/>",
+                               cpuno,
+                               (scc->cpu_user - scc->cpu_guest) < (scp->cpu_user - scp->cpu_guest) ?
+                               0.0 :
+                               ll_sp_value(scp->cpu_user - scp->cpu_guest,
+                                           scc->cpu_user - scc->cpu_guest, deltot_jiffies),
+                               (scc->cpu_nice - scc->cpu_guest_nice) < (scp->cpu_nice - scp->cpu_guest_nice) ?
+                               0.0 :
+                               ll_sp_value(scp->cpu_nice - scp->cpu_guest_nice,
+                                           scc->cpu_nice - scc->cpu_guest_nice, deltot_jiffies),
+                               ll_sp_value(scp->cpu_sys, scc->cpu_sys, deltot_jiffies),
+                               ll_sp_value(scp->cpu_iowait, scc->cpu_iowait, deltot_jiffies),
+                               ll_sp_value(scp->cpu_steal, scc->cpu_steal, deltot_jiffies),
+                               ll_sp_value(scp->cpu_hardirq, scc->cpu_hardirq, deltot_jiffies),
+                               ll_sp_value(scp->cpu_softirq, scc->cpu_softirq, deltot_jiffies),
+                               ll_sp_value(scp->cpu_guest, scc->cpu_guest, deltot_jiffies),
+                               ll_sp_value(scp->cpu_guest_nice, scc->cpu_guest_nice, deltot_jiffies),
+                               scc->cpu_idle < scp->cpu_idle ?
+                               0.0 :
+                               ll_sp_value(scp->cpu_idle, scc->cpu_idle, deltot_jiffies));
                }
        }
 
-       if (DISPLAY_CPU_DEF(a->opt_flags)) {
-               xprintf(--tab, "</cpu-load>");
-       }
-       else if (DISPLAY_CPU_ALL(a->opt_flags)) {
-               xprintf(--tab, "</cpu-load-all>");
-       }
+       xprintf(--tab, "</cpu-load>");
 }
 
 /*
@@ -267,7 +287,7 @@ __print_funct_t xml_print_cpu_stats(struct activity *a, int curr, int tab,
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_pcsw_stats(struct activity *a, int curr, int tab,
@@ -282,7 +302,7 @@ __print_funct_t xml_print_pcsw_stats(struct activity *a, int curr, int tab,
                "proc=\"%.2f\" "
                "cswch=\"%.2f\"/>",
                S_VALUE(spp->processes, spc->processes, itv),
-               ll_s_value(spp->context_switch, spc->context_switch, itv));
+               S_VALUE(spp->context_switch, spc->context_switch, itv));
 }
 
 /*
@@ -293,7 +313,7 @@ __print_funct_t xml_print_pcsw_stats(struct activity *a, int curr, int tab,
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_irq_stats(struct activity *a, int curr, int tab,
@@ -301,16 +321,16 @@ __print_funct_t xml_print_irq_stats(struct activity *a, int curr, int tab,
 {
        int i;
        struct stats_irq *sic, *sip;
-       char irqno[8];
+       char irqno[16];
 
        xprintf(tab++, "<interrupts>");
        xprintf(tab++, "<int-global per=\"second\">");
 
-       for (i = 0; (i < a->nr) && (i < a->bitmap->b_size + 1); i++) {
+       for (i = 0; (i < a->nr[curr]) && (i < a->bitmap->b_size + 1); i++) {
 
                sic = (struct stats_irq *) ((char *) a->buf[curr]  + i * a->msize);
                sip = (struct stats_irq *) ((char *) a->buf[!curr] + i * a->msize);
-               
+
                /* Should current interrupt (including int "sum") be displayed? */
                if (a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))) {
 
@@ -324,7 +344,7 @@ __print_funct_t xml_print_irq_stats(struct activity *a, int curr, int tab,
                        }
 
                        xprintf(tab, "<irq intr=\"%s\" value=\"%.2f\"/>", irqno,
-                               ll_s_value(sip->irq_nr, sic->irq_nr, itv));
+                               S_VALUE(sip->irq_nr, sic->irq_nr, itv));
                }
        }
 
@@ -340,7 +360,7 @@ __print_funct_t xml_print_irq_stats(struct activity *a, int curr, int tab,
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_swap_stats(struct activity *a, int curr, int tab,
@@ -349,7 +369,7 @@ __print_funct_t xml_print_swap_stats(struct activity *a, int curr, int tab,
        struct stats_swap
                *ssc = (struct stats_swap *) a->buf[curr],
                *ssp = (struct stats_swap *) a->buf[!curr];
-       
+
        xprintf(tab, "<swap-pages per=\"second\" "
                "pswpin=\"%.2f\" "
                "pswpout=\"%.2f\"/>",
@@ -365,7 +385,7 @@ __print_funct_t xml_print_swap_stats(struct activity *a, int curr, int tab,
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_paging_stats(struct activity *a, int curr, int tab,
@@ -408,7 +428,7 @@ __print_funct_t xml_print_paging_stats(struct activity *a, int curr, int tab,
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_io_stats(struct activity *a, int curr, int tab,
@@ -420,17 +440,34 @@ __print_funct_t xml_print_io_stats(struct activity *a, int curr, int tab,
 
        xprintf(tab, "<io per=\"second\">");
 
+       /*
+        * If we get negative values, this is probably because
+        * one or more devices/filesystems have been unmounted.
+        * We display 0.0 in this case though we should rather tell
+        * the user that the value cannot be calculated here.
+        */
        xprintf(++tab, "<tps>%.2f</tps>",
+               sic->dk_drive < sip->dk_drive ? 0.0 :
                S_VALUE(sip->dk_drive, sic->dk_drive, itv));
 
        xprintf(tab, "<io-reads rtps=\"%.2f\" bread=\"%.2f\"/>",
-               S_VALUE(sip->dk_drive_rio,  sic->dk_drive_rio,  itv),
+               sic->dk_drive_rio < sip->dk_drive_rio ? 0.0 :
+               S_VALUE(sip->dk_drive_rio, sic->dk_drive_rio, itv),
+               sic->dk_drive_rblk < sip->dk_drive_rblk ? 0.0 :
                S_VALUE(sip->dk_drive_rblk, sic->dk_drive_rblk, itv));
 
        xprintf(tab, "<io-writes wtps=\"%.2f\" bwrtn=\"%.2f\"/>",
-               S_VALUE(sip->dk_drive_wio,  sic->dk_drive_wio,  itv),
+               sic->dk_drive_wio < sip->dk_drive_wio ? 0.0 :
+               S_VALUE(sip->dk_drive_wio, sic->dk_drive_wio, itv),
+               sic->dk_drive_wblk < sip->dk_drive_wblk ? 0.0 :
                S_VALUE(sip->dk_drive_wblk, sic->dk_drive_wblk, itv));
 
+       xprintf(tab, "<io-discard dtps=\"%.2f\" bdscd=\"%.2f\"/>",
+               sic->dk_drive_dio < sip->dk_drive_dio ? 0.0 :
+               S_VALUE(sip->dk_drive_dio, sic->dk_drive_dio, itv),
+               sic->dk_drive_dblk < sip->dk_drive_dblk ? 0.0 :
+               S_VALUE(sip->dk_drive_dblk, sic->dk_drive_dblk, itv));
+
        xprintf(--tab, "</io>");
 }
 
@@ -442,38 +479,46 @@ __print_funct_t xml_print_io_stats(struct activity *a, int curr, int tab,
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_memory_stats(struct activity *a, int curr, int tab,
                                       unsigned long long itv)
 {
        struct stats_memory
-               *smc = (struct stats_memory *) a->buf[curr],
-               *smp = (struct stats_memory *) a->buf[!curr];
+               *smc = (struct stats_memory *) a->buf[curr];
+       unsigned long long nousedmem;
+
+       xprintf(tab, "<memory unit=\"kB\">");
 
-       xprintf(tab, "<memory per=\"second\" unit=\"kB\">");
+       if (DISPLAY_MEMORY(a->opt_flags)) {
 
-       if (DISPLAY_MEM_AMT(a->opt_flags)) {
+               nousedmem = smc->frmkb + smc->bufkb + smc->camkb + smc->slabkb;
+               if (nousedmem > smc->tlmkb) {
+                       nousedmem = smc->tlmkb;
+               }
 
-               xprintf(++tab, "<memfree>%lu</memfree>",
+               xprintf(++tab, "<memfree>%llu</memfree>",
                        smc->frmkb);
 
-               xprintf(tab, "<memused>%lu</memused>",
-                       smc->tlmkb - smc->frmkb);
+               xprintf(tab, "<avail>%llu</avail>",
+                       smc->availablekb);
+
+               xprintf(tab, "<memused>%llu</memused>",
+                       smc->tlmkb - nousedmem);
 
                xprintf(tab, "<memused-percent>%.2f</memused-percent>",
                        smc->tlmkb ?
-                       SP_VALUE(smc->frmkb, smc->tlmkb, smc->tlmkb) :
+                       SP_VALUE(nousedmem, smc->tlmkb, smc->tlmkb) :
                        0.0);
 
-               xprintf(tab, "<buffers>%lu</buffers>",
+               xprintf(tab, "<buffers>%llu</buffers>",
                        smc->bufkb);
 
-               xprintf(tab, "<cached>%lu</cached>",
+               xprintf(tab, "<cached>%llu</cached>",
                        smc->camkb);
 
-               xprintf(tab, "<commit>%lu</commit>",
+               xprintf(tab, "<commit>%llu</commit>",
                        smc->comkb);
 
                xprintf(tab, "<commit-percent>%.2f</commit-percent>",
@@ -481,22 +526,39 @@ __print_funct_t xml_print_memory_stats(struct activity *a, int curr, int tab,
                        SP_VALUE(0, smc->comkb, smc->tlmkb + smc->tlskb) :
                        0.0);
 
-               xprintf(tab, "<active>%lu</active>",
+               xprintf(tab, "<active>%llu</active>",
                        smc->activekb);
 
-               xprintf(tab, "<inactive>%lu</inactive>",
+               xprintf(tab, "<inactive>%llu</inactive>",
                        smc->inactkb);
-               
-               xprintf(tab--, "<dirty>%lu</dirty>",
+
+               xprintf(tab--, "<dirty>%llu</dirty>",
                        smc->dirtykb);
+
+               if (DISPLAY_MEM_ALL(a->opt_flags)) {
+                       xprintf(++tab, "<anonpg>%llu</anonpg>",
+                               smc->anonpgkb);
+
+                       xprintf(tab, "<slab>%llu</slab>",
+                               smc->slabkb);
+
+                       xprintf(tab, "<kstack>%llu</kstack>",
+                               smc->kstackkb);
+
+                       xprintf(tab, "<pgtbl>%llu</pgtbl>",
+                               smc->pgtblkb);
+
+                       xprintf(tab--, "<vmused>%llu</vmused>",
+                               smc->vmusedkb);
+               }
        }
 
        if (DISPLAY_SWAP(a->opt_flags)) {
 
-               xprintf(++tab, "<swpfree>%lu</swpfree>",
+               xprintf(++tab, "<swpfree>%llu</swpfree>",
                        smc->frskb);
 
-               xprintf(tab, "<swpused>%lu</swpused>",
+               xprintf(tab, "<swpused>%llu</swpused>",
                        smc->tlskb - smc->frskb);
 
                xprintf(tab, "<swpused-percent>%.2f</swpused-percent>",
@@ -504,7 +566,7 @@ __print_funct_t xml_print_memory_stats(struct activity *a, int curr, int tab,
                        SP_VALUE(smc->frskb, smc->tlskb, smc->tlskb) :
                        0.0);
 
-               xprintf(tab, "<swpcad>%lu</swpcad>",
+               xprintf(tab, "<swpcad>%llu</swpcad>",
                        smc->caskb);
 
                xprintf(tab--, "<swpcad-percent>%.2f</swpcad-percent>",
@@ -513,21 +575,6 @@ __print_funct_t xml_print_memory_stats(struct activity *a, int curr, int tab,
                        0.0);
        }
 
-       if (DISPLAY_MEMORY(a->opt_flags)) {
-
-               xprintf(++tab, "<frmpg>%.2f</frmpg>",
-                       S_VALUE((double) KB_TO_PG(smp->frmkb),
-                               (double) KB_TO_PG(smc->frmkb), itv));
-
-               xprintf(tab, "<bufpg>%.2f</bufpg>",
-                       S_VALUE((double) KB_TO_PG(smp->bufkb),
-                               (double) KB_TO_PG(smc->bufkb), itv));
-
-               xprintf(tab--, "<campg>%.2f</campg>",
-                       S_VALUE((double) KB_TO_PG(smp->camkb),
-                               (double) KB_TO_PG(smc->camkb), itv));
-       }
-
        xprintf(tab, "</memory>");
 }
 
@@ -539,7 +586,7 @@ __print_funct_t xml_print_memory_stats(struct activity *a, int curr, int tab,
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_ktables_stats(struct activity *a, int curr, int tab,
@@ -547,12 +594,12 @@ __print_funct_t xml_print_ktables_stats(struct activity *a, int curr, int tab,
 {
        struct stats_ktables
                *skc = (struct stats_ktables *) a->buf[curr];
-       
+
        xprintf(tab, "<kernel "
-               "dentunusd=\"%u\" "
-               "file-nr=\"%u\" "
-               "inode-nr=\"%u\" "
-               "pty-nr=\"%u\"/>",
+               "dentunusd=\"%llu\" "
+               "file-nr=\"%llu\" "
+               "inode-nr=\"%llu\" "
+               "pty-nr=\"%llu\"/>",
                skc->dentry_stat,
                skc->file_used,
                skc->inode_used,
@@ -567,7 +614,7 @@ __print_funct_t xml_print_ktables_stats(struct activity *a, int curr, int tab,
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_queue_stats(struct activity *a, int curr, int tab,
@@ -575,14 +622,14 @@ __print_funct_t xml_print_queue_stats(struct activity *a, int curr, int tab,
 {
        struct stats_queue
                *sqc = (struct stats_queue *) a->buf[curr];
-       
+
        xprintf(tab, "<queue "
-               "runq-sz=\"%lu\" "
-               "plist-sz=\"%u\" "
+               "runq-sz=\"%llu\" "
+               "plist-sz=\"%llu\" "
                "ldavg-1=\"%.2f\" "
                "ldavg-5=\"%.2f\" "
                "ldavg-15=\"%.2f\" "
-               "blocked=\"%lu\"/>",
+               "blocked=\"%llu\"/>",
                sqc->nr_running,
                sqc->nr_threads,
                (double) sqc->load_avg_1 / 100,
@@ -599,43 +646,63 @@ __print_funct_t xml_print_queue_stats(struct activity *a, int curr, int tab,
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_serial_stats(struct activity *a, int curr, int tab,
                                       unsigned long long itv)
 {
-       int i;
+       int i, j, j0, found;
        struct stats_serial *ssc, *ssp;
 
-       xprintf(tab, "<serial per=\"second\">");
-       tab++;
+       xprintf(tab++, "<serial per=\"second\">");
 
-       for (i = 0; i < a->nr; i++) {
+       for (i = 0; i < a->nr[curr]; i++) {
 
-               ssc = (struct stats_serial *) ((char *) a->buf[curr]  + i * a->msize);
-               ssp = (struct stats_serial *) ((char *) a->buf[!curr] + i * a->msize);
+               found = FALSE;
 
-               if (ssc->line == 0)
-                       continue;
+               if (a->nr[!curr] > 0) {
+                       ssc = (struct stats_serial *) ((char *) a->buf[curr]  + i * a->msize);
 
-               if (ssc->line == ssp->line) {
-
-                       xprintf(tab, "<tty line=\"%d\" "
-                               "rcvin=\"%.2f\" "
-                               "xmtin=\"%.2f\" "
-                               "framerr=\"%.2f\" "
-                               "prtyerr=\"%.2f\" "
-                               "brk=\"%.2f\" "
-                               "ovrun=\"%.2f\"/>",
-                               ssc->line - 1,
-                               S_VALUE(ssp->rx,      ssc->rx,      itv),
-                               S_VALUE(ssp->tx,      ssc->tx,      itv),
-                               S_VALUE(ssp->frame,   ssc->frame,   itv),
-                               S_VALUE(ssp->parity,  ssc->parity,  itv),
-                               S_VALUE(ssp->brk,     ssc->brk,     itv),
-                               S_VALUE(ssp->overrun, ssc->overrun, itv));
+                       /* Look for corresponding serial line in previous iteration */
+                       j = i;
+
+                       if (j >= a->nr[!curr]) {
+                               j = a->nr[!curr] - 1;
+                       }
+
+                       j0 = j;
+
+                       do {
+                               ssp = (struct stats_serial *) ((char *) a->buf[!curr] + j * a->msize);
+                               if (ssc->line == ssp->line) {
+                                       found = TRUE;
+                                       break;
+                               }
+                               if (++j >= a->nr[!curr]) {
+                                       j = 0;
+                               }
+                       }
+                       while (j != j0);
                }
+
+               if (!found)
+                       continue;
+
+               xprintf(tab, "<tty line=\"%d\" "
+                       "rcvin=\"%.2f\" "
+                       "xmtin=\"%.2f\" "
+                       "framerr=\"%.2f\" "
+                       "prtyerr=\"%.2f\" "
+                       "brk=\"%.2f\" "
+                       "ovrun=\"%.2f\"/>",
+                       ssc->line,
+                       S_VALUE(ssp->rx,      ssc->rx,      itv),
+                       S_VALUE(ssp->tx,      ssc->tx,      itv),
+                       S_VALUE(ssp->frame,   ssc->frame,   itv),
+                       S_VALUE(ssp->parity,  ssc->parity,  itv),
+                       S_VALUE(ssp->brk,     ssc->brk,     itv),
+                       S_VALUE(ssp->overrun, ssc->overrun, itv));
        }
 
        xprintf(--tab, "</serial>");
@@ -649,73 +716,78 @@ __print_funct_t xml_print_serial_stats(struct activity *a, int curr, int tab,
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_disk_stats(struct activity *a, int curr, int tab,
                                     unsigned long long itv)
 {
        int i, j;
-       struct stats_disk *sdc, *sdp;
+       struct stats_disk *sdc, *sdp, sdpzero;
        struct ext_disk_stats xds;
-       char *dev_name, *persist_dev_name;
+       char *dev_name;
 
-       xprintf(tab, "<disk per=\"second\">");
-       tab++;
+       memset(&sdpzero, 0, STATS_DISK_SIZE);
 
-       for (i = 0; i < a->nr; i++) {
+       xprintf(tab++, "<disk per=\"second\">");
 
-               sdc = (struct stats_disk *) ((char *) a->buf[curr] + i * a->msize);
+       for (i = 0; i < a->nr[curr]; i++) {
 
-               if (!(sdc->major + sdc->minor))
-                       continue;
+               sdc = (struct stats_disk *) ((char *) a->buf[curr] + i * a->msize);
 
                j = check_disk_reg(a, curr, !curr, i);
-               sdp = (struct stats_disk *) ((char *) a->buf[!curr] + j * a->msize);
-
-               /* Compute extended statistics values */
-               compute_ext_disk_stats(sdc, sdp, itv, &xds);
-
-               dev_name = NULL;
-               persist_dev_name = NULL;
-
-               if (DISPLAY_PERSIST_NAME_S(flags)) {
-                       persist_dev_name = get_persistent_name_from_pretty(get_devname(sdc->major, sdc->minor, TRUE));
-               }
-               
-               if (persist_dev_name) {
-                       dev_name = persist_dev_name;
+               if (j < 0) {
+                       /* This is a newly registered interface. Previous stats are zero */
+                       sdp = &sdpzero;
                }
                else {
-                       if ((USE_PRETTY_OPTION(flags)) && (sdc->major == dm_major)) {
-                               dev_name = transform_devmapname(sdc->major, sdc->minor);
-                       }
+                       sdp = (struct stats_disk *) ((char *) a->buf[!curr] + j * a->msize);
+               }
 
-                       if (!dev_name) {
-                               dev_name = get_devname(sdc->major, sdc->minor,
-                                                      USE_PRETTY_OPTION(flags));
-                       }
+               /* Get device name */
+               dev_name = get_device_name(sdc->major, sdc->minor, sdc->wwn, sdc->part_nr,
+                                          DISPLAY_PRETTY(flags), DISPLAY_PERSIST_NAME_S(flags),
+                                          USE_STABLE_ID(flags), NULL);
+
+               if (a->item_list != NULL) {
+                       /* A list of devices has been entered on the command line */
+                       if (!search_list_item(a->item_list, dev_name))
+                               /* Device not found */
+                               continue;
                }
 
+               /* Compute extended statistics values */
+               compute_ext_disk_stats(sdc, sdp, itv, &xds);
+
                xprintf(tab, "<disk-device dev=\"%s\" "
                        "tps=\"%.2f\" "
                        "rd_sec=\"%.2f\" "
                        "wr_sec=\"%.2f\" "
+                       "dc_sec=\"%.2f\" "
+                       "rkB=\"%.2f\" "
+                       "wkB=\"%.2f\" "
+                       "dkB=\"%.2f\" "
                        "avgrq-sz=\"%.2f\" "
+                       "areq-sz=\"%.2f\" "
                        "avgqu-sz=\"%.2f\" "
+                       "aqu-sz=\"%.2f\" "
                        "await=\"%.2f\" "
-                       "svctm=\"%.2f\" "
                        "util-percent=\"%.2f\"/>",
                        /* Confusion possible here between index and minor numbers */
                        dev_name,
                        S_VALUE(sdp->nr_ios, sdc->nr_ios, itv),
-                       ll_s_value(sdp->rd_sect, sdc->rd_sect, itv),
-                       ll_s_value(sdp->wr_sect, sdc->wr_sect, itv),
+                       S_VALUE(sdp->rd_sect, sdc->rd_sect, itv), /* Unit = sectors (for backward compatibility) */
+                       S_VALUE(sdp->wr_sect, sdc->wr_sect, itv),
+                       S_VALUE(sdp->dc_sect, sdc->dc_sect, itv),
+                       S_VALUE(sdp->rd_sect, sdc->rd_sect, itv) / 2,
+                       S_VALUE(sdp->wr_sect, sdc->wr_sect, itv) / 2,
+                       S_VALUE(sdp->dc_sect, sdc->dc_sect, itv) / 2,
                        /* See iostat for explanations */
-                       xds.arqsz,
+                       xds.arqsz,      /* Unit = sectors (for backward compatibility) */
+                       xds.arqsz / 2,
+                       S_VALUE(sdp->rq_ticks, sdc->rq_ticks, itv) / 1000.0,    /* For backward compatibility */
                        S_VALUE(sdp->rq_ticks, sdc->rq_ticks, itv) / 1000.0,
                        xds.await,
-                       xds.svctm,
                        xds.util / 10.0);
        }
 
@@ -730,30 +802,47 @@ __print_funct_t xml_print_disk_stats(struct activity *a, int curr, int tab,
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_net_dev_stats(struct activity *a, int curr, int tab,
                                        unsigned long long itv)
 {
        int i, j;
-       struct stats_net_dev *sndc, *sndp;
+       struct stats_net_dev *sndc, *sndp, sndzero;
+       double rxkb, txkb, ifutil;
 
-       if (!IS_SELECTED(a->options) || (a->nr <= 0))
+       if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
                goto close_xml_markup;
 
+       memset(&sndzero, 0, STATS_NET_DEV_SIZE);
+
        xml_markup_network(tab, OPEN_XML_MARKUP);
        tab++;
 
-       for (i = 0; i < a->nr; i++) {
+       for (i = 0; i < a->nr[curr]; i++) {
 
                sndc = (struct stats_net_dev *) ((char *) a->buf[curr] + i * a->msize);
 
-               if (!strcmp(sndc->interface, ""))
-                       continue;
+               if (a->item_list != NULL) {
+                       /* A list of devices has been entered on the command line */
+                       if (!search_list_item(a->item_list, sndc->interface))
+                               /* Device not found */
+                               continue;
+               }
 
                j = check_net_dev_reg(a, curr, !curr, i);
-               sndp = (struct stats_net_dev *) ((char *) a->buf[!curr] + j * a->msize);
+               if (j < 0) {
+                       /* This is a newly registered interface. Previous stats are zero */
+                       sndp = &sndzero;
+               }
+               else {
+                       sndp = (struct stats_net_dev *) ((char *) a->buf[!curr] + j * a->msize);
+               }
+
+               rxkb = S_VALUE(sndp->rx_bytes, sndc->rx_bytes, itv);
+               txkb = S_VALUE(sndp->tx_bytes, sndc->tx_bytes, itv);
+               ifutil = compute_ifutil(sndc, rxkb, txkb);
 
                xprintf(tab, "<net-dev iface=\"%s\" "
                        "rxpck=\"%.2f\" "
@@ -762,15 +851,17 @@ __print_funct_t xml_print_net_dev_stats(struct activity *a, int curr, int tab,
                        "txkB=\"%.2f\" "
                        "rxcmp=\"%.2f\" "
                        "txcmp=\"%.2f\" "
-                       "rxmcst=\"%.2f\"/>",
+                       "rxmcst=\"%.2f\" "
+                       "ifutil-percent=\"%.2f\"/>",
                        sndc->interface,
                        S_VALUE(sndp->rx_packets,    sndc->rx_packets,    itv),
                        S_VALUE(sndp->tx_packets,    sndc->tx_packets,    itv),
-                       S_VALUE(sndp->rx_bytes,      sndc->rx_bytes,      itv) / 1024,
-                       S_VALUE(sndp->tx_bytes,      sndc->tx_bytes,      itv) / 1024,
+                       rxkb / 1024,
+                       txkb / 1024,
                        S_VALUE(sndp->rx_compressed, sndc->rx_compressed, itv),
                        S_VALUE(sndp->tx_compressed, sndc->tx_compressed, itv),
-                       S_VALUE(sndp->multicast,     sndc->multicast,     itv));
+                       S_VALUE(sndp->multicast,     sndc->multicast,     itv),
+                       ifutil);
        }
        tab--;
 
@@ -782,36 +873,48 @@ close_xml_markup:
 
 /*
  ***************************************************************************
- * Display network interfaces error statistics in XML.
+ * Display network interfaces errors statistics in XML.
  *
  * IN:
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_net_edev_stats(struct activity *a, int curr, int tab,
                                         unsigned long long itv)
 {
        int i, j;
-       struct stats_net_edev *snedc, *snedp;
+       struct stats_net_edev *snedc, *snedp, snedzero;
 
-       if (!IS_SELECTED(a->options) || (a->nr <= 0))
+       if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
                goto close_xml_markup;
 
+       memset(&snedzero, 0, STATS_NET_EDEV_SIZE);
+
        xml_markup_network(tab, OPEN_XML_MARKUP);
        tab++;
 
-       for (i = 0; i < a->nr; i++) {
+       for (i = 0; i < a->nr[curr]; i++) {
 
                snedc = (struct stats_net_edev *) ((char *) a->buf[curr] + i * a->msize);
 
-               if (!strcmp(snedc->interface, ""))
-                       continue;
+               if (a->item_list != NULL) {
+                       /* A list of devices has been entered on the command line */
+                       if (!search_list_item(a->item_list, snedc->interface))
+                               /* Device not found */
+                               continue;
+               }
 
                j = check_net_edev_reg(a, curr, !curr, i);
-               snedp = (struct stats_net_edev *) ((char *) a->buf[!curr] + j * a->msize);
+               if (j < 0) {
+                       /* This is a newly registered interface. Previous stats are zero */
+                       snedp = &snedzero;
+               }
+               else {
+                       snedp = (struct stats_net_edev *) ((char *) a->buf[!curr] + j * a->msize);
+               }
 
                xprintf(tab, "<net-edev iface=\"%s\" "
                        "rxerr=\"%.2f\" "
@@ -850,7 +953,7 @@ close_xml_markup:
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_net_nfs_stats(struct activity *a, int curr, int tab,
@@ -860,7 +963,7 @@ __print_funct_t xml_print_net_nfs_stats(struct activity *a, int curr, int tab,
                *snnc = (struct stats_net_nfs *) a->buf[curr],
                *snnp = (struct stats_net_nfs *) a->buf[!curr];
 
-       if (!IS_SELECTED(a->options) || (a->nr <= 0))
+       if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
                goto close_xml_markup;
 
        xml_markup_network(tab, OPEN_XML_MARKUP);
@@ -895,7 +998,7 @@ close_xml_markup:
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_net_nfsd_stats(struct activity *a, int curr, int tab,
@@ -905,7 +1008,7 @@ __print_funct_t xml_print_net_nfsd_stats(struct activity *a, int curr, int tab,
                *snndc = (struct stats_net_nfsd *) a->buf[curr],
                *snndp = (struct stats_net_nfsd *) a->buf[!curr];
 
-       if (!IS_SELECTED(a->options) || (a->nr <= 0))
+       if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
                goto close_xml_markup;
 
        xml_markup_network(tab, OPEN_XML_MARKUP);
@@ -950,7 +1053,7 @@ close_xml_markup:
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_net_sock_stats(struct activity *a, int curr, int tab,
@@ -959,7 +1062,7 @@ __print_funct_t xml_print_net_sock_stats(struct activity *a, int curr, int tab,
        struct stats_net_sock
                *snsc = (struct stats_net_sock *) a->buf[curr];
 
-       if (!IS_SELECTED(a->options) || (a->nr <= 0))
+       if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
                goto close_xml_markup;
 
        xml_markup_network(tab, OPEN_XML_MARKUP);
@@ -994,7 +1097,7 @@ close_xml_markup:
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_net_ip_stats(struct activity *a, int curr, int tab,
@@ -1004,7 +1107,7 @@ __print_funct_t xml_print_net_ip_stats(struct activity *a, int curr, int tab,
                *snic = (struct stats_net_ip *) a->buf[curr],
                *snip = (struct stats_net_ip *) a->buf[!curr];
 
-       if (!IS_SELECTED(a->options) || (a->nr <= 0))
+       if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
                goto close_xml_markup;
 
        xml_markup_network(tab, OPEN_XML_MARKUP);
@@ -1037,13 +1140,13 @@ close_xml_markup:
 
 /*
  ***************************************************************************
- * Display IP network error statistics in XML.
+ * Display IP network errors statistics in XML.
  *
  * IN:
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_net_eip_stats(struct activity *a, int curr, int tab,
@@ -1053,7 +1156,7 @@ __print_funct_t xml_print_net_eip_stats(struct activity *a, int curr, int tab,
                *sneic = (struct stats_net_eip *) a->buf[curr],
                *sneip = (struct stats_net_eip *) a->buf[!curr];
 
-       if (!IS_SELECTED(a->options) || (a->nr <= 0))
+       if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
                goto close_xml_markup;
 
        xml_markup_network(tab, OPEN_XML_MARKUP);
@@ -1092,7 +1195,7 @@ close_xml_markup:
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_net_icmp_stats(struct activity *a, int curr, int tab,
@@ -1102,7 +1205,7 @@ __print_funct_t xml_print_net_icmp_stats(struct activity *a, int curr, int tab,
                *snic = (struct stats_net_icmp *) a->buf[curr],
                *snip = (struct stats_net_icmp *) a->buf[!curr];
 
-       if (!IS_SELECTED(a->options) || (a->nr <= 0))
+       if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
                goto close_xml_markup;
 
        xml_markup_network(tab, OPEN_XML_MARKUP);
@@ -1147,13 +1250,13 @@ close_xml_markup:
 
 /*
  ***************************************************************************
- * Display ICMP error message statistics in XML.
+ * Display ICMP error messages statistics in XML.
  *
  * IN:
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_net_eicmp_stats(struct activity *a, int curr, int tab,
@@ -1163,7 +1266,7 @@ __print_funct_t xml_print_net_eicmp_stats(struct activity *a, int curr, int tab,
                *sneic = (struct stats_net_eicmp *) a->buf[curr],
                *sneip = (struct stats_net_eicmp *) a->buf[!curr];
 
-       if (!IS_SELECTED(a->options) || (a->nr <= 0))
+       if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
                goto close_xml_markup;
 
        xml_markup_network(tab, OPEN_XML_MARKUP);
@@ -1210,7 +1313,7 @@ close_xml_markup:
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_net_tcp_stats(struct activity *a, int curr, int tab,
@@ -1220,7 +1323,7 @@ __print_funct_t xml_print_net_tcp_stats(struct activity *a, int curr, int tab,
                *sntc = (struct stats_net_tcp *) a->buf[curr],
                *sntp = (struct stats_net_tcp *) a->buf[!curr];
 
-       if (!IS_SELECTED(a->options) || (a->nr <= 0))
+       if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
                goto close_xml_markup;
 
        xml_markup_network(tab, OPEN_XML_MARKUP);
@@ -1245,13 +1348,13 @@ close_xml_markup:
 
 /*
  ***************************************************************************
- * Display TCP network error statistics in XML.
+ * Display TCP network errors statistics in XML.
  *
  * IN:
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_net_etcp_stats(struct activity *a, int curr, int tab,
@@ -1260,8 +1363,8 @@ __print_funct_t xml_print_net_etcp_stats(struct activity *a, int curr, int tab,
        struct stats_net_etcp
                *snetc = (struct stats_net_etcp *) a->buf[curr],
                *snetp = (struct stats_net_etcp *) a->buf[!curr];
-       
-       if (!IS_SELECTED(a->options) || (a->nr <= 0))
+
+       if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
                goto close_xml_markup;
 
        xml_markup_network(tab, OPEN_XML_MARKUP);
@@ -1294,7 +1397,7 @@ close_xml_markup:
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_net_udp_stats(struct activity *a, int curr, int tab,
@@ -1303,8 +1406,8 @@ __print_funct_t xml_print_net_udp_stats(struct activity *a, int curr, int tab,
        struct stats_net_udp
                *snuc = (struct stats_net_udp *) a->buf[curr],
                *snup = (struct stats_net_udp *) a->buf[!curr];
-       
-       if (!IS_SELECTED(a->options) || (a->nr <= 0))
+
+       if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
                goto close_xml_markup;
 
        xml_markup_network(tab, OPEN_XML_MARKUP);
@@ -1335,7 +1438,7 @@ close_xml_markup:
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_net_sock6_stats(struct activity *a, int curr, int tab,
@@ -1343,8 +1446,8 @@ __print_funct_t xml_print_net_sock6_stats(struct activity *a, int curr, int tab,
 {
        struct stats_net_sock6
                *snsc = (struct stats_net_sock6 *) a->buf[curr];
-       
-       if (!IS_SELECTED(a->options) || (a->nr <= 0))
+
+       if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
                goto close_xml_markup;
 
        xml_markup_network(tab, OPEN_XML_MARKUP);
@@ -1375,7 +1478,7 @@ close_xml_markup:
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_net_ip6_stats(struct activity *a, int curr, int tab,
@@ -1385,7 +1488,7 @@ __print_funct_t xml_print_net_ip6_stats(struct activity *a, int curr, int tab,
                *snic = (struct stats_net_ip6 *) a->buf[curr],
                *snip = (struct stats_net_ip6 *) a->buf[!curr];
 
-       if (!IS_SELECTED(a->options) || (a->nr <= 0))
+       if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
                goto close_xml_markup;
 
        xml_markup_network(tab, OPEN_XML_MARKUP);
@@ -1422,13 +1525,13 @@ close_xml_markup:
 
 /*
  ***************************************************************************
- * Display IPv6 network error statistics in XML.
+ * Display IPv6 network errors statistics in XML.
  *
  * IN:
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_net_eip6_stats(struct activity *a, int curr, int tab,
@@ -1438,7 +1541,7 @@ __print_funct_t xml_print_net_eip6_stats(struct activity *a, int curr, int tab,
                *sneic = (struct stats_net_eip6 *) a->buf[curr],
                *sneip = (struct stats_net_eip6 *) a->buf[!curr];
 
-       if (!IS_SELECTED(a->options) || (a->nr <= 0))
+       if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
                goto close_xml_markup;
 
        xml_markup_network(tab, OPEN_XML_MARKUP);
@@ -1483,7 +1586,7 @@ close_xml_markup:
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_net_icmp6_stats(struct activity *a, int curr, int tab,
@@ -1493,7 +1596,7 @@ __print_funct_t xml_print_net_icmp6_stats(struct activity *a, int curr, int tab,
                *snic = (struct stats_net_icmp6 *) a->buf[curr],
                *snip = (struct stats_net_icmp6 *) a->buf[!curr];
 
-       if (!IS_SELECTED(a->options) || (a->nr <= 0))
+       if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
                goto close_xml_markup;
 
        xml_markup_network(tab, OPEN_XML_MARKUP);
@@ -1544,13 +1647,13 @@ close_xml_markup:
 
 /*
  ***************************************************************************
- * Display ICMPv6 error message statistics in XML.
+ * Display ICMPv6 error messages statistics in XML.
  *
  * IN:
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_net_eicmp6_stats(struct activity *a, int curr, int tab,
@@ -1560,7 +1663,7 @@ __print_funct_t xml_print_net_eicmp6_stats(struct activity *a, int curr, int tab
                *sneic = (struct stats_net_eicmp6 *) a->buf[curr],
                *sneip = (struct stats_net_eicmp6 *) a->buf[!curr];
 
-       if (!IS_SELECTED(a->options) || (a->nr <= 0))
+       if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
                goto close_xml_markup;
 
        xml_markup_network(tab, OPEN_XML_MARKUP);
@@ -1605,7 +1708,7 @@ close_xml_markup:
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_net_udp6_stats(struct activity *a, int curr, int tab,
@@ -1615,7 +1718,7 @@ __print_funct_t xml_print_net_udp6_stats(struct activity *a, int curr, int tab,
                *snuc = (struct stats_net_udp6 *) a->buf[curr],
                *snup = (struct stats_net_udp6 *) a->buf[!curr];
 
-       if (!IS_SELECTED(a->options) || (a->nr <= 0))
+       if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
                goto close_xml_markup;
 
        xml_markup_network(tab, OPEN_XML_MARKUP);
@@ -1646,7 +1749,7 @@ close_xml_markup:
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_pwr_cpufreq_stats(struct activity *a, int curr, int tab,
@@ -1654,37 +1757,38 @@ __print_funct_t xml_print_pwr_cpufreq_stats(struct activity *a, int curr, int ta
 {
        int i;
        struct stats_pwr_cpufreq *spc;
-       char cpuno[8];
+       char cpuno[16];
 
-       if (!IS_SELECTED(a->options) || (a->nr <= 0))
+       if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
                goto close_xml_markup;
 
        xml_markup_power_management(tab, OPEN_XML_MARKUP);
        tab++;
 
        xprintf(tab++, "<cpu-frequency unit=\"MHz\">");
-       
-       for (i = 0; (i < a->nr) && (i < a->bitmap->b_size + 1); i++) {
 
-               spc = (struct stats_pwr_cpufreq *) ((char *) a->buf[curr]  + i * a->msize);
+       for (i = 0; (i < a->nr[curr]) && (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))) {
+               spc = (struct stats_pwr_cpufreq *) ((char *) a->buf[curr] + i * a->msize);
 
-                       /* Yes: Display it */
-                       if (!i) {
-                               /* This is CPU "all" */
-                               strcpy(cpuno, "all");
-                       }
-                       else {
-                               sprintf(cpuno, "%d", i - 1);
-                       }
+               /* Should current CPU (including CPU "all") be displayed? */
+               if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))))
+                       /* No */
+                       continue;
 
-                       xprintf(tab, "<cpufreq number=\"%s\" "
-                               "frequency=\"%.2f\"/>",
-                               cpuno,
-                               ((double) spc->cpufreq) / 100);
+               /* Yes: Display it */
+               if (!i) {
+                       /* This is CPU "all" */
+                       strcpy(cpuno, "all");
+               }
+               else {
+                       sprintf(cpuno, "%d", i - 1);
                }
+
+               xprintf(tab, "<cpufreq number=\"%s\" "
+                       "frequency=\"%.2f\"/>",
+                       cpuno,
+                       ((double) spc->cpufreq) / 100);
        }
 
        xprintf(--tab, "</cpu-frequency>");
@@ -1704,7 +1808,7 @@ close_xml_markup:
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_pwr_fan_stats(struct activity *a, int curr, int tab,
@@ -1713,7 +1817,7 @@ __print_funct_t xml_print_pwr_fan_stats(struct activity *a, int curr, int tab,
        int i;
        struct stats_pwr_fan *spc;
 
-       if (!IS_SELECTED(a->options) || (a->nr <= 0))
+       if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
                goto close_xml_markup;
 
        xml_markup_power_management(tab, OPEN_XML_MARKUP);
@@ -1721,8 +1825,8 @@ __print_funct_t xml_print_pwr_fan_stats(struct activity *a, int curr, int tab,
 
        xprintf(tab++, "<fan-speed unit=\"rpm\">");
 
-       for (i = 0; i < a->nr; i++) {
-               spc = (struct stats_pwr_fan *) ((char *) a->buf[curr]  + i * a->msize);
+       for (i = 0; i < a->nr[curr]; i++) {
+               spc = (struct stats_pwr_fan *) ((char *) a->buf[curr] + i * a->msize);
 
                xprintf(tab, "<fan number=\"%d\" rpm=\"%llu\" drpm=\"%llu\" device=\"%s\"/>",
                        i + 1,
@@ -1748,7 +1852,7 @@ close_xml_markup:
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_pwr_temp_stats(struct activity *a, int curr, int tab,
@@ -1757,7 +1861,7 @@ __print_funct_t xml_print_pwr_temp_stats(struct activity *a, int curr, int tab,
        int i;
        struct stats_pwr_temp *spc;
 
-       if (!IS_SELECTED(a->options) || (a->nr <= 0))
+       if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
                goto close_xml_markup;
 
        xml_markup_power_management(tab, OPEN_XML_MARKUP);
@@ -1765,8 +1869,8 @@ __print_funct_t xml_print_pwr_temp_stats(struct activity *a, int curr, int tab,
 
        xprintf(tab++, "<temperature unit=\"degree Celsius\">");
 
-       for (i = 0; i < a->nr; i++) {
-               spc = (struct stats_pwr_temp *) ((char *) a->buf[curr]  + i * a->msize);
+       for (i = 0; i < a->nr[curr]; i++) {
+               spc = (struct stats_pwr_temp *) ((char *) a->buf[curr] + i * a->msize);
 
                xprintf(tab, "<temp number=\"%d\" degC=\"%.2f\" percent-temp=\"%.2f\" device=\"%s\"/>",
                        i + 1,
@@ -1794,7 +1898,7 @@ close_xml_markup:
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_pwr_in_stats(struct activity *a, int curr, int tab,
@@ -1803,7 +1907,7 @@ __print_funct_t xml_print_pwr_in_stats(struct activity *a, int curr, int tab,
        int i;
        struct stats_pwr_in *spc;
 
-       if (!IS_SELECTED(a->options) || (a->nr <= 0))
+       if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
                goto close_xml_markup;
 
        xml_markup_power_management(tab, OPEN_XML_MARKUP);
@@ -1811,8 +1915,8 @@ __print_funct_t xml_print_pwr_in_stats(struct activity *a, int curr, int tab,
 
        xprintf(tab++, "<voltage-input unit=\"V\">");
 
-       for (i = 0; i < a->nr; i++) {
-               spc = (struct stats_pwr_in *) ((char *) a->buf[curr]  + i * a->msize);
+       for (i = 0; i < a->nr[curr]; i++) {
+               spc = (struct stats_pwr_in *) ((char *) a->buf[curr] + i * a->msize);
 
                xprintf(tab, "<in number=\"%d\" inV=\"%.2f\" percent-in=\"%.2f\" device=\"%s\"/>",
                        i,
@@ -1840,7 +1944,7 @@ close_xml_markup:
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_huge_stats(struct activity *a, int curr, int tab,
@@ -1851,17 +1955,23 @@ __print_funct_t xml_print_huge_stats(struct activity *a, int curr, int tab,
 
        xprintf(tab, "<hugepages unit=\"kB\">");
 
-       xprintf(++tab, "<hugfree>%lu</hugfree>",
+       xprintf(++tab, "<hugfree>%llu</hugfree>",
                smc->frhkb);
 
-       xprintf(tab, "<hugused>%lu</hugused>",
+       xprintf(tab, "<hugused>%llu</hugused>",
                smc->tlhkb - smc->frhkb);
 
-       xprintf(tab--, "<hugused-percent>%.2f</hugused-percent>",
+       xprintf(tab, "<hugused-percent>%.2f</hugused-percent>",
                smc->tlhkb ?
                SP_VALUE(smc->frhkb, smc->tlhkb, smc->tlhkb) :
                0.0);
 
+       xprintf(tab, "<hugrsvd>%llu</hugrsvd>",
+               smc->rsvdhkb);
+
+       xprintf(tab--, "<hugsurp>%llu</hugsurp>",
+               smc->surphkb);
+
        xprintf(tab, "</hugepages>");
 }
 
@@ -1873,7 +1983,7 @@ __print_funct_t xml_print_huge_stats(struct activity *a, int curr, int tab,
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_pwr_wghfreq_stats(struct activity *a, int curr, int tab,
@@ -1882,9 +1992,9 @@ __print_funct_t xml_print_pwr_wghfreq_stats(struct activity *a, int curr, int ta
        int i, k;
        struct stats_pwr_wghfreq *spc, *spp, *spc_k, *spp_k;
        unsigned long long tis, tisfreq;
-       char cpuno[8];
+       char cpuno[16];
 
-       if (!IS_SELECTED(a->options) || (a->nr <= 0))
+       if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
                goto close_xml_markup;
 
        xml_markup_power_management(tab, OPEN_XML_MARKUP);
@@ -1892,43 +2002,43 @@ __print_funct_t xml_print_pwr_wghfreq_stats(struct activity *a, int curr, int ta
 
        xprintf(tab++, "<cpu-weighted-frequency unit=\"MHz\">");
 
-       for (i = 0; (i < a->nr) && (i < a->bitmap->b_size + 1); i++) {
+       for (i = 0; (i < a->nr[curr]) && (i < a->bitmap->b_size + 1); i++) {
 
                spc = (struct stats_pwr_wghfreq *) ((char *) a->buf[curr]  + i * a->msize * a->nr2);
                spp = (struct stats_pwr_wghfreq *) ((char *) a->buf[!curr] + i * a->msize * a->nr2);
 
                /* Should current CPU (including CPU "all") be displayed? */
-               if (a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))) {
-
-                       /* Yes... */
-                       tisfreq = 0;
-                       tis = 0;
+               if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))))
+                       /* No */
+                       continue;
 
-                       for (k = 0; k < a->nr2; k++) {
+               tisfreq = 0;
+               tis = 0;
 
-                               spc_k = (struct stats_pwr_wghfreq *) ((char *) spc + k * a->msize);
-                               if (!spc_k->freq)
-                                       break;
-                               spp_k = (struct stats_pwr_wghfreq *) ((char *) spp + k * a->msize);
+               for (k = 0; k < a->nr2; k++) {
 
-                               tisfreq += (spc_k->freq / 1000) *
-                                          (spc_k->time_in_state - spp_k->time_in_state);
-                               tis     += (spc_k->time_in_state - spp_k->time_in_state);
-                       }
+                       spc_k = (struct stats_pwr_wghfreq *) ((char *) spc + k * a->msize);
+                       if (!spc_k->freq)
+                               break;
+                       spp_k = (struct stats_pwr_wghfreq *) ((char *) spp + k * a->msize);
 
-                       if (!i) {
-                               /* This is CPU "all" */
-                               strcpy(cpuno, "all");
-                       }
-                       else {
-                               sprintf(cpuno, "%d", i - 1);
-                       }
+                       tisfreq += (spc_k->freq / 1000) *
+                                  (spc_k->time_in_state - spp_k->time_in_state);
+                       tis     += (spc_k->time_in_state - spp_k->time_in_state);
+               }
 
-                       xprintf(tab, "<cpuwfreq number=\"%s\" "
-                               "weighted-frequency=\"%.2f\"/>",
-                               cpuno,
-                               tis ? ((double) tisfreq) / tis : 0.0);
+               if (!i) {
+                       /* This is CPU "all" */
+                       strcpy(cpuno, "all");
+               }
+               else {
+                       sprintf(cpuno, "%d", i - 1);
                }
+
+               xprintf(tab, "<cpuwfreq number=\"%s\" "
+                       "weighted-frequency=\"%.2f\"/>",
+                       cpuno,
+                       tis ? ((double) tisfreq) / tis : 0.0);
        }
 
        xprintf(--tab, "</cpu-weighted-frequency>");
@@ -1948,7 +2058,7 @@ close_xml_markup:
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_pwr_usb_stats(struct activity *a, int curr, int tab,
@@ -1957,7 +2067,7 @@ __print_funct_t xml_print_pwr_usb_stats(struct activity *a, int curr, int tab,
        int i;
        struct stats_pwr_usb *suc;
 
-       if (!IS_SELECTED(a->options) || (a->nr <= 0))
+       if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
                goto close_xml_markup;
 
        xml_markup_power_management(tab, OPEN_XML_MARKUP);
@@ -1965,12 +2075,8 @@ __print_funct_t xml_print_pwr_usb_stats(struct activity *a, int curr, int tab,
 
        xprintf(tab++, "<usb-devices>");
 
-       for (i = 0; i < a->nr; i++) {
-               suc = (struct stats_pwr_usb *) ((char *) a->buf[curr]  + i * a->msize);
-
-               if (!suc->bus_nr)
-                       /* Bus#0 doesn't exist: We are at the end of the list */
-                       break;
+       for (i = 0; i < a->nr[curr]; i++) {
+               suc = (struct stats_pwr_usb *) ((char *) a->buf[curr] + i * a->msize);
 
                xprintf(tab, "<usb bus_number=\"%d\" idvendor=\"%x\" idprod=\"%x\" "
                             "maxpower=\"%u\" manufact=\"%s\" product=\"%s\"/>",
@@ -1999,7 +2105,7 @@ close_xml_markup:
  * @a          Activity structure with statistics.
  * @curr       Index in array for current sample statistics.
  * @tab                Indentation in XML output.
- * @itv                Interval of time in jiffies.
+ * @itv                Interval of time in 1/100th of a second.
  ***************************************************************************
  */
 __print_funct_t xml_print_filesystem_stats(struct activity *a, int curr, int tab,
@@ -2007,19 +2113,24 @@ __print_funct_t xml_print_filesystem_stats(struct activity *a, int curr, int tab
 {
        int i;
        struct stats_filesystem *sfc;
+       char *dev_name;
 
-       xprintf(tab, "<filesystems>");
-       tab++;
-
-       for (i = 0; i < a->nr; i++) {
+       xprintf(tab++, "<filesystems>");
 
+       for (i = 0; i < a->nr[curr]; i++) {
                sfc = (struct stats_filesystem *) ((char *) a->buf[curr] + i * a->msize);
 
-               if (!sfc->f_blocks)
-                       /* Size of filesystem is null: We are at the end of the list */
-                       break;
+               /* Get name to display (persistent or standard fs name, or mount point) */
+               dev_name = get_fs_name_to_display(a, flags, sfc);
 
-               xprintf(tab, "<filesystem fsname=\"%s\" "
+               if (a->item_list != NULL) {
+                       /* A list of devices has been entered on the command line */
+                       if (!search_list_item(a->item_list, dev_name))
+                               /* Device not found */
+                               continue;
+               }
+
+               xprintf(tab, "<filesystem %s=\"%s\" "
                        "MBfsfree=\"%.0f\" "
                        "MBfsused=\"%.0f\" "
                        "fsused-percent=\"%.2f\" "
@@ -2027,10 +2138,11 @@ __print_funct_t xml_print_filesystem_stats(struct activity *a, int curr, int tab
                        "Ifree=\"%llu\" "
                        "Iused=\"%llu\" "
                        "Iused-percent=\"%.2f\"/>",
-                       sfc->fs_name,
+                       DISPLAY_MOUNT(a->opt_flags) ? "mountp" : "fsname",
+                       dev_name,
                        (double) sfc->f_bfree / 1024 / 1024,
                        (double) (sfc->f_blocks - sfc->f_bfree) / 1024 / 1024,
-                       /* f_blocks is not null. But test it anyway ;-) */
+                       /* f_blocks is not zero. But test it anyway ;-) */
                        sfc->f_blocks ? SP_VALUE(sfc->f_bfree, sfc->f_blocks, sfc->f_blocks)
                                      : 0.0,
                        sfc->f_blocks ? SP_VALUE(sfc->f_bavail, sfc->f_blocks, sfc->f_blocks)
@@ -2043,3 +2155,293 @@ __print_funct_t xml_print_filesystem_stats(struct activity *a, int curr, int tab
 
        xprintf(--tab, "</filesystems>");
 }
+
+/*
+ ***************************************************************************
+ * Display Fibre Channel HBA statistics in XML.
+ *
+ * IN:
+ * @a          Activity structure with statistics.
+ * @curr       Index in array for current sample statistics.
+ * @tab                Indentation in XML output.
+ * @itv                Interval of time in 1/100th of a second.
+ ***************************************************************************
+ */
+__print_funct_t xml_print_fchost_stats(struct activity *a, int curr, int tab,
+                                      unsigned long long itv)
+{
+       int i, j, j0, found;
+       struct stats_fchost *sfcc, *sfcp, sfczero;
+
+       if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
+               goto close_xml_markup;
+
+       memset(&sfczero, 0, sizeof(struct stats_fchost));
+
+       xml_markup_network(tab, OPEN_XML_MARKUP);
+       tab++;
+
+       for (i = 0; i < a->nr[curr]; i++) {
+
+               found = FALSE;
+               sfcc = (struct stats_fchost *) ((char *) a->buf[curr] + i * a->msize);
+
+               if (a->nr[!curr] > 0) {
+                       /* Look for corresponding structure in previous iteration */
+                       j = i;
+
+                       if (j >= a->nr[!curr]) {
+                               j = a->nr[!curr] - 1;
+                       }
+
+                       j0 = j;
+
+                       do {
+                               sfcp = (struct stats_fchost *) ((char *) a->buf[!curr] + j * a->msize);
+                               if (!strcmp(sfcc->fchost_name, sfcp->fchost_name)) {
+                                       found = TRUE;
+                                       break;
+                               }
+                               if (++j >= a->nr[!curr]) {
+                                       j = 0;
+                               }
+                       }
+                       while (j != j0);
+               }
+
+               if (!found) {
+                       /* This is a newly registered host */
+                       sfcp = &sfczero;
+               }
+
+               xprintf(tab, "<fchost name=\"%s\" "
+                       "fch_rxf=\"%.2f\" "
+                       "fch_txf=\"%.2f\" "
+                       "fch_rxw=\"%.2f\" "
+                       "fch_txw=\"%.2f\"/>",
+                       sfcc->fchost_name,
+                       S_VALUE(sfcp->f_rxframes, sfcc->f_rxframes, itv),
+                       S_VALUE(sfcp->f_txframes, sfcc->f_txframes, itv),
+                       S_VALUE(sfcp->f_rxwords,  sfcc->f_rxwords,  itv),
+                       S_VALUE(sfcp->f_txwords,  sfcc->f_txwords,  itv));
+       }
+       tab--;
+
+close_xml_markup:
+       if (CLOSE_MARKUP(a->options)) {
+               xml_markup_network(tab, CLOSE_XML_MARKUP);
+       }
+}
+
+/*
+ ***************************************************************************
+ * Display softnet statistics in XML.
+ *
+ * IN:
+ * @a          Activity structure with statistics.
+ * @curr       Index in array for current sample statistics.
+ * @tab                Indentation in XML output.
+ * @itv                Interval of time in 1/100th of a second.
+ ***************************************************************************
+ */
+__print_funct_t xml_print_softnet_stats(struct activity *a, int curr, int tab,
+                                       unsigned long long itv)
+{
+       int i;
+       struct stats_softnet *ssnc, *ssnp;
+       char cpuno[16];
+       unsigned char offline_cpu_bitmap[BITMAP_SIZE(NR_CPUS)] = {0};
+
+       if (!IS_SELECTED(a->options) || (a->nr[curr] <= 0))
+               goto close_xml_markup;
+
+       xml_markup_network(tab, OPEN_XML_MARKUP);
+       tab++;
+
+       /* @nr[curr] cannot normally be greater than @nr_ini */
+       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);
+
+               /* Yes: Display it */
+               if (!i) {
+                       /* This is CPU "all" */
+                       strcpy(cpuno, "all");
+               }
+               else {
+                       sprintf(cpuno, "%d", i - 1);
+               }
+
+               xprintf(tab, "<softnet cpu=\"%s\" "
+                       "total=\"%.2f\" "
+                       "dropd=\"%.2f\" "
+                       "squeezd=\"%.2f\" "
+                       "rx_rps=\"%.2f\" "
+                       "flw_lim=\"%.2f\"/>",
+                        cpuno,
+                        S_VALUE(ssnp->processed,    ssnc->processed,    itv),
+                        S_VALUE(ssnp->dropped,      ssnc->dropped,      itv),
+                        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));
+       }
+       tab--;
+
+close_xml_markup:
+       if (CLOSE_MARKUP(a->options)) {
+               xml_markup_network(tab, CLOSE_XML_MARKUP);
+       }
+}
+
+/*
+ ***************************************************************************
+ * Display pressure-stall CPU statistics in XML.
+ *
+ * IN:
+ * @a          Activity structure with statistics.
+ * @curr       Index in array for current sample statistics.
+ * @tab                Indentation in XML output.
+ * @itv                Interval of time in 1/100th of a second.
+ ***************************************************************************
+ */
+__print_funct_t xml_print_psicpu_stats(struct activity *a, int curr, int tab,
+                                      unsigned long long itv)
+{
+       struct stats_psi_cpu
+               *psic = (struct stats_psi_cpu *) a->buf[curr],
+               *psip = (struct stats_psi_cpu *) a->buf[!curr];
+
+       if (!IS_SELECTED(a->options))
+               goto close_xml_markup;
+
+       xml_markup_psi(tab, OPEN_XML_MARKUP);
+       tab++;
+
+       xprintf(tab, "<psi-cpu "
+               "some_avg10=\"%.2f\" "
+               "some_avg60=\"%.2f\" "
+               "some_avg300=\"%.2f\" "
+               "some_avg=\"%.2f\"/>",
+               (double) psic->some_acpu_10  / 100,
+               (double) psic->some_acpu_60  / 100,
+               (double) psic->some_acpu_300 / 100,
+               ((double) psic->some_cpu_total - psip->some_cpu_total) / (100 * itv));
+       tab--;
+
+close_xml_markup:
+       if (CLOSE_MARKUP(a->options)) {
+               xml_markup_psi(tab, CLOSE_XML_MARKUP);
+       }
+}
+
+/*
+ ***************************************************************************
+ * Display pressure-stall I/O statistics in XML.
+ *
+ * IN:
+ * @a          Activity structure with statistics.
+ * @curr       Index in array for current sample statistics.
+ * @tab                Indentation in XML output.
+ * @itv                Interval of time in 1/100th of a second.
+ ***************************************************************************
+ */
+__print_funct_t xml_print_psiio_stats(struct activity *a, int curr, int tab,
+                                     unsigned long long itv)
+{
+       struct stats_psi_io
+               *psic = (struct stats_psi_io *) a->buf[curr],
+               *psip = (struct stats_psi_io *) a->buf[!curr];
+
+       if (!IS_SELECTED(a->options))
+               goto close_xml_markup;
+
+       xml_markup_psi(tab, OPEN_XML_MARKUP);
+       tab++;
+
+       xprintf(tab, "<psi-io "
+               "some_avg10=\"%.2f\" "
+               "some_avg60=\"%.2f\" "
+               "some_avg300=\"%.2f\" "
+               "some_avg=\"%.2f\" "
+               "full_avg10=\"%.2f\" "
+               "full_avg60=\"%.2f\" "
+               "full_avg300=\"%.2f\" "
+               "full_avg=\"%.2f\"/>",
+               (double) psic->some_aio_10  / 100,
+               (double) psic->some_aio_60  / 100,
+               (double) psic->some_aio_300 / 100,
+               ((double) psic->some_io_total - psip->some_io_total) / (100 * itv),
+               (double) psic->full_aio_10  / 100,
+               (double) psic->full_aio_60  / 100,
+               (double) psic->full_aio_300 / 100,
+               ((double) psic->full_io_total - psip->full_io_total) / (100 * itv));
+       tab--;
+
+close_xml_markup:
+       if (CLOSE_MARKUP(a->options)) {
+               xml_markup_psi(tab, CLOSE_XML_MARKUP);
+       }
+}
+
+/*
+ ***************************************************************************
+ * Display pressure-stall memory statistics in XML.
+ *
+ * IN:
+ * @a          Activity structure with statistics.
+ * @curr       Index in array for current sample statistics.
+ * @tab                Indentation in XML output.
+ * @itv                Interval of time in 1/100th of a second.
+ ***************************************************************************
+ */
+__print_funct_t xml_print_psimem_stats(struct activity *a, int curr, int tab,
+                                      unsigned long long itv)
+{
+       struct stats_psi_mem
+               *psic = (struct stats_psi_mem *) a->buf[curr],
+               *psip = (struct stats_psi_mem *) a->buf[!curr];
+
+       if (!IS_SELECTED(a->options))
+               goto close_xml_markup;
+
+       xml_markup_psi(tab, OPEN_XML_MARKUP);
+       tab++;
+
+       xprintf(tab, "<psi-mem "
+               "some_avg10=\"%.2f\" "
+               "some_avg60=\"%.2f\" "
+               "some_avg300=\"%.2f\" "
+               "some_avg=\"%.2f\" "
+               "full_avg10=\"%.2f\" "
+               "full_avg60=\"%.2f\" "
+               "full_avg300=\"%.2f\" "
+               "full_avg=\"%.2f\"/>",
+               (double) psic->some_amem_10  / 100,
+               (double) psic->some_amem_60  / 100,
+               (double) psic->some_amem_300 / 100,
+               ((double) psic->some_mem_total - psip->some_mem_total) / (100 * itv),
+               (double) psic->full_amem_10  / 100,
+               (double) psic->full_amem_60  / 100,
+               (double) psic->full_amem_300 / 100,
+               ((double) psic->full_mem_total - psip->full_mem_total) / (100 * itv));
+       tab--;
+
+close_xml_markup:
+       if (CLOSE_MARKUP(a->options)) {
+               xml_markup_psi(tab, CLOSE_XML_MARKUP);
+       }
+}