]> granicus.if.org Git - sysstat/blobdiff - xml_stats.c
sysstat-12.5.3
[sysstat] / xml_stats.c
index 7859afcc4399ef1b1cf2a146ce0d3e83ee6d8e9c..324f984dae8a816e55f5019404f7a275b17ccfaa 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * xml_stats.c: Funtions used by sadf to display statistics in XML.
- * (C) 1999-2016 by Sebastien GODARD (sysstat <at> orange.fr)
+ * (C) 1999-2021 by Sebastien GODARD (sysstat <at> orange.fr)
  *
  ***************************************************************************
  * This program is free software; you can redistribute it and/or modify it *
@@ -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,67 +126,73 @@ 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>");
 
-       for (i = 0; (i < a->nr) && (i < a->bitmap->b_size + 1); i++) {
+       /* @nr[curr] cannot normally be greater than @nr_ini */
+       if (a->nr[curr] > a->nr_ini) {
+               a->nr_ini = a->nr[curr];
+       }
 
-               scc = (struct stats_cpu *) ((char *) a->buf[curr]  + i * a->msize);
-               scp = (struct stats_cpu *) ((char *) a->buf[!curr] + i * a->msize);
+       /*
+        * 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_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))))
-                       /* No */
+               if (!(a->bitmap->b_array[i >> 3] & (1 << (i & 0x07))) ||
+                   offline_cpu_bitmap[i >> 3] & (1 << (i & 0x07)))
+                       /* Don't display CPU */
                        continue;
 
-               /* Yes: Display it */
-               if (!i) {
+               scc = (struct stats_cpu *) ((char *) a->buf[curr]  + i * a->msize);
+               scp = (struct stats_cpu *) ((char *) a->buf[!curr] + i * a->msize);
+
+               if (i == 0) {
                        /* This is CPU "all" */
                        strcpy(cpuno, "all");
+
+                       if (a->nr_ini == 1) {
+                               /*
+                                * This is a UP machine. In this case
+                                * interval has still not been calculated.
+                                */
+                               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);
 
                        /*
-                        * 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.)
+                        * Recalculate interval for current proc.
+                        * If result is 0 then current CPU is a tickless one.
                         */
-                       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 (!g_itv) {
-                               /* Current CPU is offline or tickless */
+                       if (!deltot_jiffies) {
+                               /* Current CPU is tickless */
                                if (DISPLAY_CPU_DEF(a->opt_flags)) {
                                        xprintf(tab, "<cpu number=\"%d\" "
                                                "user=\"%.2f\" "
@@ -170,8 +201,7 @@ __print_funct_t xml_print_cpu_stats(struct activity *a, int curr, int tab,
                                                "iowait=\"%.2f\" "
                                                "steal=\"%.2f\" "
                                                "idle=\"%.2f\"/>",
-                                               i - 1, 0.0, 0.0, 0.0, 0.0, 0.0,
-                                               cpu_offline ? 0.0 : 100.0);
+                                               i - 1, 0.0, 0.0, 0.0, 0.0, 0.0, 100.0);
                                }
                                else if (DISPLAY_CPU_ALL(a->opt_flags)) {
                                        xprintf(tab, "<cpu number=\"%d\" "
@@ -186,8 +216,7 @@ __print_funct_t xml_print_cpu_stats(struct activity *a, int curr, int tab,
                                                "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);
+                                               0.0, 0.0, 0.0, 0.0, 0.0, 100.0);
                                }
                                continue;
                        }
@@ -202,16 +231,16 @@ __print_funct_t xml_print_cpu_stats(struct activity *a, int curr, int tab,
                                "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_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,
-                                           g_itv),
-                               ll_sp_value(scp->cpu_iowait, scc->cpu_iowait, g_itv),
-                               ll_sp_value(scp->cpu_steal,  scc->cpu_steal,  g_itv),
+                                           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,   g_itv));
+                               ll_sp_value(scp->cpu_idle, scc->cpu_idle, deltot_jiffies));
                }
                else if (DISPLAY_CPU_ALL(a->opt_flags)) {
                        xprintf(tab, "<cpu number=\"%s\" "
@@ -229,21 +258,21 @@ __print_funct_t xml_print_cpu_stats(struct activity *a, int curr, int tab,
                                (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_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, 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_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, g_itv));
+                               ll_sp_value(scp->cpu_idle, scc->cpu_idle, deltot_jiffies));
                }
        }
 
@@ -258,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,
@@ -284,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,
@@ -292,12 +321,12 @@ __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);
@@ -331,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,
@@ -356,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,
@@ -399,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,
@@ -433,6 +462,12 @@ __print_funct_t xml_print_io_stats(struct activity *a, int curr, int tab,
                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>");
 }
 
@@ -444,41 +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 per=\"second\" unit=\"kB\">");
+       xprintf(tab, "<memory unit=\"kB\">");
 
-       if (DISPLAY_MEM_AMT(a->opt_flags)) {
+       if (DISPLAY_MEMORY(a->opt_flags)) {
 
-               xprintf(++tab, "<memfree>%lu</memfree>",
+               nousedmem = smc->frmkb + smc->bufkb + smc->camkb + smc->slabkb;
+               if (nousedmem > smc->tlmkb) {
+                       nousedmem = smc->tlmkb;
+               }
+
+               xprintf(++tab, "<memfree>%llu</memfree>",
                        smc->frmkb);
 
-               xprintf(tab, "<avail>%lu</avail>",
+               xprintf(tab, "<avail>%llu</avail>",
                        smc->availablekb);
 
-               xprintf(tab, "<memused>%lu</memused>",
-                       smc->tlmkb - smc->frmkb);
+               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>",
@@ -486,39 +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>%lu</anonpg>",
+                       xprintf(++tab, "<anonpg>%llu</anonpg>",
                                smc->anonpgkb);
 
-                       xprintf(tab, "<slab>%lu</slab>",
+                       xprintf(tab, "<slab>%llu</slab>",
                                smc->slabkb);
 
-                       xprintf(tab, "<kstack>%lu</kstack>",
+                       xprintf(tab, "<kstack>%llu</kstack>",
                                smc->kstackkb);
 
-                       xprintf(tab, "<pgtbl>%lu</pgtbl>",
+                       xprintf(tab, "<pgtbl>%llu</pgtbl>",
                                smc->pgtblkb);
 
-                       xprintf(tab--, "<vmused>%lu</vmused>",
+                       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>",
@@ -526,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>",
@@ -535,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>");
 }
 
@@ -561,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,
@@ -571,10 +596,10 @@ __print_funct_t xml_print_ktables_stats(struct activity *a, int curr, int tab,
                *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,
@@ -589,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,
@@ -599,12 +624,12 @@ __print_funct_t xml_print_queue_stats(struct activity *a, int curr, int tab,
                *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,
@@ -621,42 +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\">");
 
-       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>");
@@ -670,7 +716,7 @@ __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,
@@ -679,19 +725,16 @@ __print_funct_t xml_print_disk_stats(struct activity *a, int curr, int tab,
        int i, j;
        struct stats_disk *sdc, *sdp, sdpzero;
        struct ext_disk_stats xds;
-       char *dev_name, *persist_dev_name;
+       char *dev_name;
 
        memset(&sdpzero, 0, STATS_DISK_SIZE);
 
        xprintf(tab++, "<disk per=\"second\">");
 
-       for (i = 0; i < a->nr; i++) {
+       for (i = 0; i < a->nr[curr]; i++) {
 
                sdc = (struct stats_disk *) ((char *) a->buf[curr] + i * a->msize);
 
-               if (!(sdc->major + sdc->minor))
-                       continue;
-
                j = check_disk_reg(a, curr, !curr, i);
                if (j < 0) {
                        /* This is a newly registered interface. Previous stats are zero */
@@ -701,49 +744,50 @@ __print_funct_t xml_print_disk_stats(struct activity *a, int curr, int tab,
                        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;
+               /* 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 (DISPLAY_PERSIST_NAME_S(flags)) {
-                       persist_dev_name = get_persistent_name_from_pretty(get_devname(sdc->major, sdc->minor, TRUE));
+               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;
                }
 
-               if (persist_dev_name) {
-                       dev_name = persist_dev_name;
-               }
-               else {
-                       if ((USE_PRETTY_OPTION(flags)) && (sdc->major == dm_major)) {
-                               dev_name = transform_devmapname(sdc->major, sdc->minor);
-                       }
-
-                       if (!dev_name) {
-                               dev_name = get_devname(sdc->major, sdc->minor,
-                                                      USE_PRETTY_OPTION(flags));
-                       }
-               }
+               /* 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),
-                       S_VALUE(sdp->rd_sect, sdc->rd_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);
        }
 
@@ -758,7 +802,7 @@ __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,
@@ -768,7 +812,7 @@ __print_funct_t xml_print_net_dev_stats(struct activity *a, int curr, int tab,
        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);
@@ -776,12 +820,16 @@ __print_funct_t xml_print_net_dev_stats(struct activity *a, int curr, int tab,
        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, ""))
-                       break;
+               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);
                if (j < 0) {
@@ -831,7 +879,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_edev_stats(struct activity *a, int curr, int tab,
@@ -840,7 +888,7 @@ __print_funct_t xml_print_net_edev_stats(struct activity *a, int curr, int tab,
        int i, j;
        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);
@@ -848,12 +896,16 @@ __print_funct_t xml_print_net_edev_stats(struct activity *a, int curr, int tab,
        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, ""))
-                       break;
+               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);
                if (j < 0) {
@@ -901,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,
@@ -911,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);
@@ -946,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,
@@ -956,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);
@@ -1001,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,
@@ -1010,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);
@@ -1045,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,
@@ -1055,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);
@@ -1094,7 +1146,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_eip_stats(struct activity *a, int curr, int tab,
@@ -1104,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);
@@ -1143,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,
@@ -1153,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);
@@ -1204,7 +1256,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_eicmp_stats(struct activity *a, int curr, int tab,
@@ -1214,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);
@@ -1261,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,
@@ -1271,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);
@@ -1302,7 +1354,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_etcp_stats(struct activity *a, int curr, int tab,
@@ -1312,7 +1364,7 @@ __print_funct_t xml_print_net_etcp_stats(struct activity *a, int curr, int tab,
                *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);
@@ -1345,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,
@@ -1355,7 +1407,7 @@ __print_funct_t xml_print_net_udp_stats(struct activity *a, int curr, int tab,
                *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);
@@ -1386,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,
@@ -1395,7 +1447,7 @@ __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);
@@ -1426,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,
@@ -1436,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);
@@ -1479,7 +1531,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_eip6_stats(struct activity *a, int curr, int tab,
@@ -1489,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);
@@ -1534,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,
@@ -1544,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);
@@ -1601,7 +1653,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_eicmp6_stats(struct activity *a, int curr, int tab,
@@ -1611,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);
@@ -1656,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,
@@ -1666,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);
@@ -1697,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,
@@ -1705,9 +1757,9 @@ __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);
@@ -1715,27 +1767,28 @@ __print_funct_t xml_print_pwr_cpufreq_stats(struct activity *a, int curr, int ta
 
        xprintf(tab++, "<cpu-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_cpufreq *) ((char *) a->buf[curr]  + i * a->msize);
+               spc = (struct stats_pwr_cpufreq *) ((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 (!(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>");
@@ -1755,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,
@@ -1764,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);
@@ -1772,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,
@@ -1799,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,
@@ -1808,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);
@@ -1816,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,
@@ -1845,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,
@@ -1854,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);
@@ -1862,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,
@@ -1891,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,
@@ -1902,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>");
 }
 
@@ -1924,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,
@@ -1933,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);
@@ -1943,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>");
@@ -1999,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,
@@ -2008,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);
@@ -2016,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\"/>",
@@ -2050,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,
@@ -2058,16 +2113,22 @@ __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>");
 
-       for (i = 0; i < a->nr; i++) {
-
+       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 zero: 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);
+
+               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\" "
@@ -2078,7 +2139,7 @@ __print_funct_t xml_print_filesystem_stats(struct activity *a, int curr, int tab
                        "Iused=\"%llu\" "
                        "Iused-percent=\"%.2f\"/>",
                        DISPLAY_MOUNT(a->opt_flags) ? "mountp" : "fsname",
-                       DISPLAY_MOUNT(a->opt_flags) ? sfc->mountp : sfc->fs_name,
+                       dev_name,
                        (double) sfc->f_bfree / 1024 / 1024,
                        (double) (sfc->f_blocks - sfc->f_bfree) / 1024 / 1024,
                        /* f_blocks is not zero. But test it anyway ;-) */
@@ -2103,29 +2164,55 @@ __print_funct_t xml_print_filesystem_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_fchost_stats(struct activity *a, int curr, int tab,
                                       unsigned long long itv)
 {
-       int i;
-       struct stats_fchost *sfcc, *sfcp;
+       int i, j, j0, found;
+       struct stats_fchost *sfcc, *sfcp, sfczero;
 
-       if (!IS_SELECTED(a->options) || (a->nr <= 0))
+       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; i++) {
+       for (i = 0; i < a->nr[curr]; i++) {
 
+               found = FALSE;
                sfcc = (struct stats_fchost *) ((char *) a->buf[curr] + i * a->msize);
-               sfcp = (struct stats_fchost *) ((char *) a->buf[!curr] + i * a->msize);
 
-               if (!sfcc->fchost_name[0])
-                       /* We are at the end of the list */
-                       break;
+               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\" "
@@ -2136,7 +2223,7 @@ __print_funct_t xml_print_fchost_stats(struct activity *a, int curr, int tab,
                        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_rxwords,  itv));
+                       S_VALUE(sfcp->f_txwords,  sfcc->f_txwords,  itv));
        }
        tab--;
 
@@ -2154,7 +2241,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_softnet_stats(struct activity *a, int curr, int tab,
@@ -2162,24 +2249,34 @@ __print_funct_t xml_print_softnet_stats(struct activity *a, int curr, int tab,
 {
        int i;
        struct stats_softnet *ssnc, *ssnp;
-       char cpuno[8];
+       char cpuno[16];
+       unsigned char offline_cpu_bitmap[BITMAP_SIZE(NR_CPUS)] = {0};
 
-       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);
        tab++;
 
-       for (i = 0; (i < a->nr) && (i < a->bitmap->b_size + 1); i++) {
+       /* @nr[curr] cannot normally be greater than @nr_ini */
+       if (a->nr[curr] > a->nr_ini) {
+               a->nr_ini = a->nr[curr];
+       }
 
-               ssnc = (struct stats_softnet *) ((char *) a->buf[curr]  + i * a->msize);
-               ssnp = (struct stats_softnet *) ((char *) a->buf[!curr] + i * a->msize);
+       /* 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))))
+               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" */
@@ -2209,3 +2306,142 @@ close_xml_markup:
                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);
+       }
+}