New field added to sar -r output: kbdirty.
authorseb <seb@kluane.home>
Sun, 30 Sep 2012 13:17:12 +0000 (15:17 +0200)
committerseb <seb@kluane.home>
Sun, 30 Sep 2012 13:17:12 +0000 (15:17 +0200)
sar -r now tracks the amount of dirty memory (memory waiting to
get written back to disk).
DTD and XSD documents updated.
Sar manual page updated.

Mail from Michael Blakeley (mike@blakeley.com) 28/09/2012:

I've been thinking about patching the sa collectors to track the "Dirty" metric from /proc/meminfo, and sar to report on it. This would be useful for applications where latency is important: having historical data on dirty writeback pages can help trace the kind of problems that can be addressed by tuning vm.dirty_bytes and friends.

In the 10.1 code I see that a few functions and structs already make use of meminfo. What's your philosophy on this? Should dirty-kB be a new struct, or perhaps merge with the existing meminfo_huge struct?

Similarly for reporting, should I focus on a new option ("-D" perhaps?) or try to piggyback on an existing one?

CHANGES
activity.c
json_stats.c
man/sar.in
pr_stats.c
rd_stats.c
rd_stats.h
rndr_stats.c
xml/sysstat.dtd
xml/sysstat.xsd
xml_stats.c

diff --git a/CHANGES b/CHANGES
index 05f57a06fd50609fbd865559844c93ef34873aaa..f678f2313fa56fa69c235f85a7e8c4c8b54fda88 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -3,6 +3,8 @@ Changes:
 xxxx/xx/xx: Version 10.1.2 - Sebastien Godard (sysstat <at> orange.fr)
        * New field added to sar -u and mpstat: %gnice (time spent
          running a niced guest).
+       * New field added to sar -r: kbdirty (amount of memory waiting
+         to get written back to disk).
        * [Peter Schiffer]: systemd support added.
        * [Peter Schiffer]: Sysstat init script updated to make it
          more conforming to LSB.
index 65770d7e91f5e76dd71e4377db8fbc735997b036..2cbadb6bd78c4605f2c32ada9ce2c9eab83ff163 100644 (file)
@@ -274,7 +274,7 @@ struct activity memory_act = {
        .f_xml_print    = xml_print_memory_stats,
        .f_json_print   = json_print_memory_stats,
        .hdr_line       = "frmpg/s;bufpg/s;campg/s|"
-                         "kbmemfree;kbmemused;%memused;kbbuffers;kbcached;kbcommit;%commit;kbactive;kbinact|"
+                         "kbmemfree;kbmemused;%memused;kbbuffers;kbcached;kbcommit;%commit;kbactive;kbinact;kbdirty|"
                          "kbswpfree;kbswpused;%swpused;kbswpcad;%swpcad",
        .name           = "A_MEMORY",
 #endif
index 47360e6cc8ae70fecd21ffc428aa67cc0d092241..a75b4221222a69f9753d8cd42a0717eacdb93f73 100644 (file)
@@ -479,7 +479,8 @@ __print_funct_t json_print_memory_stats(struct activity *a, int curr, int tab,
                       "\"commit\": %lu, "
                       "\"commit-percent\": %.2f, "
                       "\"active\": %lu, "
-                      "\"inactive\": %lu",
+                      "\"inactive\": %lu, "
+                      "\"dirty\": %lu",
                       smc->frmkb,
                       smc->tlmkb - smc->frmkb,
                       smc->tlmkb ?
@@ -492,7 +493,8 @@ __print_funct_t json_print_memory_stats(struct activity *a, int curr, int tab,
                       SP_VALUE(0, smc->comkb, smc->tlmkb + smc->tlskb) :
                       0.0,
                       smc->activekb,
-                      smc->inactkb);
+                      smc->inactkb,
+                      smc->dirtykb);
        }
 
        if (DISPLAY_SWAP(a->opt_flags)) {
index 81a4dd7bf70dbd98f936403c13b985ad26353a33..b34ed8cb16c401ffcab03eefa556dd7503125546 100644 (file)
@@ -1783,6 +1783,11 @@ and usually not reclaimed unless absolutely necessary).
 Amount of inactive memory in kilobytes (memory which has been less recently
 used. It is more eligible to be reclaimed for other purposes).
 .RE
+
+.B kbdirty
+.RS
+Amount of memory in kilobytes waiting to get written back to the disk.
+.RE
 .RE
 .IP -S
 Report swap space utilization statistics.
index 02a3b7d984c8362c7e16cb0b24489e04b25eff64..ab1b8417f97173a99c95f4c8f9e213c5a07d9977 100644 (file)
@@ -410,7 +410,8 @@ void stub_print_memory_stats(struct activity *a, int prev, int curr,
                avg_camkb    = 0,
                avg_comkb    = 0,
                avg_activekb = 0,
-               avg_inactkb  = 0;
+               avg_inactkb  = 0,
+               avg_dirtykb  = 0;
        static unsigned long long
                avg_frskb = 0,
                avg_tlskb = 0,
@@ -431,12 +432,12 @@ void stub_print_memory_stats(struct activity *a, int prev, int curr,
        if (DISPLAY_MEM_AMT(a->opt_flags)) {
                if (dis) {
                        printf("\n%-11s kbmemfree kbmemused  %%memused kbbuffers  kbcached"
-                              "  kbcommit   %%commit  kbactive   kbinact\n", timestamp[!curr]);
+                              "  kbcommit   %%commit  kbactive   kbinact   kbdirty\n", timestamp[!curr]);
                }
 
                if (!dispavg) {
                        /* Display instantaneous values */
-                       printf("%-11s %9lu %9lu    %6.2f %9lu %9lu %9lu   %7.2f %9lu %9lu\n",
+                       printf("%-11s %9lu %9lu    %6.2f %9lu %9lu %9lu   %7.2f %9lu %9lu %9lu\n",
                               timestamp[curr],
                               smc->frmkb,
                               smc->tlmkb - smc->frmkb,
@@ -448,7 +449,8 @@ void stub_print_memory_stats(struct activity *a, int prev, int curr,
                               (smc->tlmkb + smc->tlskb) ?
                               SP_VALUE(0, smc->comkb, smc->tlmkb + smc->tlskb) : 0.0,
                               smc->activekb,
-                              smc->inactkb);
+                              smc->inactkb,
+                              smc->dirtykb);
 
                        /*
                         * Will be used to compute the average.
@@ -461,10 +463,11 @@ void stub_print_memory_stats(struct activity *a, int prev, int curr,
                        avg_comkb    += smc->comkb;
                        avg_activekb += smc->activekb;
                        avg_inactkb  += smc->inactkb;
+                       avg_dirtykb  += smc->dirtykb;
                }
                else {
                        /* Display average values */
-                       printf("%-11s %9.0f %9.0f    %6.2f %9.0f %9.0f %9.0f   %7.2f %9.0f %9.0f\n",
+                       printf("%-11s %9.0f %9.0f    %6.2f %9.0f %9.0f %9.0f   %7.2f %9.0f %9.0f %9.0f\n",
                               timestamp[curr],
                               (double) avg_frmkb / avg_count,
                               (double) smc->tlmkb - ((double) avg_frmkb / avg_count),
@@ -479,11 +482,12 @@ void stub_print_memory_stats(struct activity *a, int prev, int curr,
                               SP_VALUE(0.0, (double) (avg_comkb / avg_count),
                                        smc->tlmkb + smc->tlskb) : 0.0,
                               (double) avg_activekb / avg_count,
-                              (double) avg_inactkb / avg_count);
+                              (double) avg_inactkb / avg_count,
+                              (double) avg_dirtykb / avg_count);
                        
                        /* Reset average counters */
                        avg_frmkb = avg_bufkb = avg_camkb = avg_comkb = 0;
-                       avg_activekb = avg_inactkb = 0;
+                       avg_activekb = avg_inactkb = avg_dirtykb = 0;
                }
        }
        
index d43688d9bf4eb9c0bd89bfec7348dde4d4f2a361..721807c058dff69e26316cfbb2bce411e88c6408 100644 (file)
@@ -350,6 +350,10 @@ void read_meminfo(struct stats_memory *st_memory)
                        /* Read the amount of free swap memory in kB */
                        sscanf(line + 9, "%lu", &st_memory->frskb);
                }
+               else if (!strncmp(line, "Dirty:", 6)) {
+                       /* Read the amount of dirty memory in kB */
+                       sscanf(line + 6, "%lu", &st_memory->dirtykb);
+               }
                else if (!strncmp(line, "Committed_AS:", 13)) {
                        /* Read the amount of commited memory in kB */
                        sscanf(line + 13, "%lu", &st_memory->comkb);
index 13c9078325df6be962f6db20a668eedd1233b0b5..ee89b5ab7a8afbcb1464f16fe39668541279a3b0 100644 (file)
@@ -159,6 +159,7 @@ struct stats_memory {
        unsigned long comkb     __attribute__ ((aligned (8)));
        unsigned long activekb  __attribute__ ((aligned (8)));
        unsigned long inactkb   __attribute__ ((aligned (8)));
+       unsigned long dirtykb   __attribute__ ((aligned (8)));
 };
 
 #define STATS_MEMORY_SIZE      (sizeof(struct stats_memory))
index 46ba97f4dc3470c9afa128007e26ede050feb7e1..73c0f6b0e5067ffc16800bdd4ba633b334df4a25 100644 (file)
@@ -789,9 +789,13 @@ __print_funct_t render_memory_stats(struct activity *a, int isdb, char *pre,
                       "-\tkbactive", NULL, NULL,
                       smc->activekb, DNOVAL, NULL);
 
-               render(isdb, pre, PT_USEINT | pt_newlin,
+               render(isdb, pre, PT_USEINT,
                       "-\tkbinact", NULL, NULL,
                       smc->inactkb, DNOVAL, NULL);
+
+               render(isdb, pre, PT_USEINT | pt_newlin,
+                      "-\tkbdirty", NULL, NULL,
+                      smc->dirtykb, DNOVAL, NULL);
        }
        
        if (DISPLAY_SWAP(a->opt_flags)) {
index 8215451e1466eaaccac94e2f601a915417712186..a9086d625b055819e0710d7d23ed1e695943f512 100644 (file)
        bwrtn CDATA #REQUIRED
 >
 
-<!ELEMENT memory (memfree, memused, memused-percent, buffers, cached, commit, commit-percent, active, inactive, swpfree, swpused, swpused-percent, swpcad, swpcad-percent, frmpg, bufpg, campg)>
+<!ELEMENT memory (memfree, memused, memused-percent, buffers, cached, commit, commit-percent, active, inactive, dirty, swpfree, swpused, swpused-percent, swpcad, swpcad-percent, frmpg, bufpg, campg)>
 <!ATTLIST memory
        per CDATA #REQUIRED
        unit CDATA #REQUIRED
 
 <!ELEMENT inactive (#PCDATA)>
 
+<!ELEMENT dirty (#PCDATA)>
+
 <!ELEMENT swpfree (#PCDATA)>
 
 <!ELEMENT swpused (#PCDATA)>
index c6edd7f6031c01ffc74e29b23763a99b36bce529..5769d4c283c4e805d386269d708136065283363a 100644 (file)
                <xs:element name="commit-percent" type="hundredth-type"></xs:element>
                <xs:element name="active" type="xs:nonNegativeInteger"></xs:element>
                <xs:element name="inactive" type="xs:nonNegativeInteger"></xs:element>
+               <xs:element name="dirty" type="xs:nonNegativeInteger"></xs:element>
                <xs:element name="swpfree" type="xs:nonNegativeInteger"></xs:element>
                <xs:element name="swpused" type="xs:nonNegativeInteger"></xs:element>
                <xs:element name="swpused-percent" type="hundredth-type"></xs:element>
index b8fb2ab91fbcfff30d42e3fad8f077a02434e026..66a685000ee549481b2b45d67e7d86b1ee257d23 100644 (file)
@@ -484,8 +484,11 @@ __print_funct_t xml_print_memory_stats(struct activity *a, int curr, int tab,
                xprintf(tab, "<active>%lu</active>",
                        smc->activekb);
 
-               xprintf(tab--, "<inactive>%lu</inactive>",
+               xprintf(tab, "<inactive>%lu</inactive>",
                        smc->inactkb);
+               
+               xprintf(tab--, "<dirty>%lu</dirty>",
+                       smc->dirtykb);
        }
 
        if (DISPLAY_SWAP(a->opt_flags)) {