public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [RFC][PATCH 0/8] introduce slabinfo extended mode
@ 2015-10-15 11:14 Sergey Senozhatsky
  2015-10-15 11:14 ` [PATCH 1/8] tools/vm/slabinfo: use getopt no_argument/optional_argument Sergey Senozhatsky
                   ` (9 more replies)
  0 siblings, 10 replies; 12+ messages in thread
From: Sergey Senozhatsky @ 2015-10-15 11:14 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, Sergey Senozhatsky, Sergey Senozhatsky

Hi,

Add 'extended' slabinfo mode that provides additional information:
 -- totals summary
 -- slabs sorted by size
 -- slabs sorted by loss (waste)

The patches also introduces several new slabinfo options to limit the
number of slabs reported, sort slabs by loss (waste); and some fixes.


Extended output example (slabinfo -X -N 2):

 Slabcache Totals
 ----------------
 Slabcaches :              91   Aliases  :         119->69   Active:     63
 Memory used:       199798784   # Loss   :        10689376   MRatio:     5%
 # Objects  :          324301   # PartObj:           18151   ORatio:     5%
    
 Per Cache         Average              Min              Max            Total
 ----------------------------------------------------------------------------
 #Objects             5147                1            89068           324301
 #Slabs                199                1             3886            12537
 #PartSlab              12                0              240              778
 %PartSlab             32%               0%             100%               6%
 PartObjs                5                0             4569            18151
 % PartObj             26%               0%             100%               5%
 Memory            3171409             8192        127336448        199798784
 Used              3001736              160        121429728        189109408
 Loss               169672                0          5906720         10689376
    
 Per Object        Average              Min              Max
 -----------------------------------------------------------
 Memory                585                8             8192
 User                  583                8             8192
 Loss                    2                0               64
    
 Slabs sorted by size
 --------------------
 Name                   Objects Objsize           Space Slabs/Part/Cpu  O/S O %Fr %Ef Flg
 ext4_inode_cache         69948    1736       127336448      3871/0/15   18 3   0  95 a
 dentry                   89068     288        26058752      3164/0/17   28 1   0  98 a
    
 Slabs sorted by loss
 --------------------
 Name                   Objects Objsize            Loss Slabs/Part/Cpu  O/S O %Fr %Ef Flg
 ext4_inode_cache         69948    1736         5906720      3871/0/15   18 3   0  95 a
 inode_cache              11628     864          537472        642/0/4   18 2   0  94 a



The last patch in the series addresses Linus' comment from
http://marc.info/?l=linux-mm&m=144148518703321&w=2

(well, it's been some time. sorry.)


gnuplot script takes the slabinfo records file, where every record is a `slabinfo -X'
output. So the basic workflow is, for example, as follows:

	while [ 1 ]; do slabinfo -X -N 2 >> stats; sleep 1; done
	^C
	slabinfo-gnuplot.sh stats

The last command will produce 3 png files (and 3 stats files)
-- graph of slabinfo totals
-- graph of slabs by size
-- graph of slabs by loss


It's also possible to select a range of records for plotting (a range of collected
slabinfo outputs) via `-r 10,100` (for example); and compare totals from several
measurements (to visially compare slabs behaviour (10,50 range)) using
pre-parsed totals files:
	slabinfo-gnuplot.sh -r 10,50 -t stats-totals1 .. stats-totals2



Examples of graphs will be attached in a follow up letter.


This also, technically, supports ktest. Upload new slabinfo to target,
collect the stats and give the resulting stats file to slabinfo-gnuplot


Sergey Senozhatsky (8):
  tools/vm/slabinfo: use getopt no_argument/optional_argument
  tools/vm/slabinfo: limit the number of reported slabs
  tools/vm/slabinfo: sort slabs by loss
  tools/vm/slabinfo: fix alternate opts names
  tools/vm/slabinfo: introduce extended totals mode
  tools/vm/slabinfo: output sizes in bytes
  tools/vm/slabinfo: cosmetic globals cleanup
  tools/vm/slabinfo: gnuplot slabifo extended stat

 tools/vm/slabinfo-gnuplot.sh | 275 +++++++++++++++++++++++++++++++++++++++++++
 tools/vm/slabinfo.c          | 255 +++++++++++++++++++++++++--------------
 2 files changed, 442 insertions(+), 88 deletions(-)
 create mode 100755 tools/vm/slabinfo-gnuplot.sh

-- 
2.6.1.134.g4b1fd35


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/8] tools/vm/slabinfo: use getopt no_argument/optional_argument
  2015-10-15 11:14 [RFC][PATCH 0/8] introduce slabinfo extended mode Sergey Senozhatsky
@ 2015-10-15 11:14 ` Sergey Senozhatsky
  2015-10-15 11:14 ` [PATCH 2/8] tools/vm/slabinfo: limit the number of reported slabs Sergey Senozhatsky
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Sergey Senozhatsky @ 2015-10-15 11:14 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, Sergey Senozhatsky, Sergey Senozhatsky

Use getopt constants in `struct option' ->has_arg instead
of numerical representations.

Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
---
 tools/vm/slabinfo.c | 34 +++++++++++++++++-----------------
 1 file changed, 17 insertions(+), 17 deletions(-)

diff --git a/tools/vm/slabinfo.c b/tools/vm/slabinfo.c
index 808d5a9..258ed01 100644
--- a/tools/vm/slabinfo.c
+++ b/tools/vm/slabinfo.c
@@ -1268,23 +1268,23 @@ static void output_slabs(void)
 }
 
 struct option opts[] = {
-	{ "aliases", 0, NULL, 'a' },
-	{ "activity", 0, NULL, 'A' },
-	{ "debug", 2, NULL, 'd' },
-	{ "display-activity", 0, NULL, 'D' },
-	{ "empty", 0, NULL, 'e' },
-	{ "first-alias", 0, NULL, 'f' },
-	{ "help", 0, NULL, 'h' },
-	{ "inverted", 0, NULL, 'i'},
-	{ "numa", 0, NULL, 'n' },
-	{ "ops", 0, NULL, 'o' },
-	{ "report", 0, NULL, 'r' },
-	{ "shrink", 0, NULL, 's' },
-	{ "slabs", 0, NULL, 'l' },
-	{ "track", 0, NULL, 't'},
-	{ "validate", 0, NULL, 'v' },
-	{ "zero", 0, NULL, 'z' },
-	{ "1ref", 0, NULL, '1'},
+	{ "aliases", no_argument, NULL, 'a' },
+	{ "activity", no_argument, NULL, 'A' },
+	{ "debug", optional_argument, NULL, 'd' },
+	{ "display-activity", no_argument, NULL, 'D' },
+	{ "empty", no_argument, NULL, 'e' },
+	{ "first-alias", no_argument, NULL, 'f' },
+	{ "help", no_argument, NULL, 'h' },
+	{ "inverted", no_argument, NULL, 'i'},
+	{ "numa", no_argument, NULL, 'n' },
+	{ "ops", no_argument, NULL, 'o' },
+	{ "report", no_argument, NULL, 'r' },
+	{ "shrink", no_argument, NULL, 's' },
+	{ "slabs", no_argument, NULL, 'l' },
+	{ "track", no_argument, NULL, 't'},
+	{ "validate", no_argument, NULL, 'v' },
+	{ "zero", no_argument, NULL, 'z' },
+	{ "1ref", no_argument, NULL, '1'},
 	{ NULL, 0, NULL, 0 }
 };
 
-- 
2.6.1.134.g4b1fd35


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/8] tools/vm/slabinfo: limit the number of reported slabs
  2015-10-15 11:14 [RFC][PATCH 0/8] introduce slabinfo extended mode Sergey Senozhatsky
  2015-10-15 11:14 ` [PATCH 1/8] tools/vm/slabinfo: use getopt no_argument/optional_argument Sergey Senozhatsky
@ 2015-10-15 11:14 ` Sergey Senozhatsky
  2015-10-15 11:14 ` [PATCH 3/8] tools/vm/slabinfo: sort slabs by loss Sergey Senozhatsky
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Sergey Senozhatsky @ 2015-10-15 11:14 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, Sergey Senozhatsky, Sergey Senozhatsky

Introduce opt "-N|--lines=K" to limit the number of slabs
being reported in output_slabs().

Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
---
 tools/vm/slabinfo.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/tools/vm/slabinfo.c b/tools/vm/slabinfo.c
index 258ed01..2ef7f0c 100644
--- a/tools/vm/slabinfo.c
+++ b/tools/vm/slabinfo.c
@@ -79,6 +79,7 @@ int sort_active = 0;
 int set_debug = 0;
 int show_ops = 0;
 int show_activity = 0;
+int output_lines = -1;
 
 /* Debug options */
 int sanity = 0;
@@ -124,6 +125,7 @@ static void usage(void)
 		"-v|--validate          Validate slabs\n"
 		"-z|--zero              Include empty slabs\n"
 		"-1|--1ref              Single reference\n"
+		"-N|--lines=K           Show the first K slabs\n"
 		"\nValid debug options (FZPUT may be combined)\n"
 		"a / A          Switch on all debug options (=FZUP)\n"
 		"-              Switch off all debug options\n"
@@ -1242,11 +1244,14 @@ static void output_slabs(void)
 {
 	struct slabinfo *slab;
 
-	for (slab = slabinfo; slab < slabinfo + slabs; slab++) {
+	for (slab = slabinfo; (slab < slabinfo + slabs) &&
+			output_lines != 0; slab++) {
 
 		if (slab->alias)
 			continue;
 
+		if (output_lines != -1)
+			output_lines--;
 
 		if (show_numa)
 			slab_numa(slab, 0);
@@ -1285,6 +1290,7 @@ struct option opts[] = {
 	{ "validate", no_argument, NULL, 'v' },
 	{ "zero", no_argument, NULL, 'z' },
 	{ "1ref", no_argument, NULL, '1'},
+	{ "lines", required_argument, NULL, 'N'},
 	{ NULL, 0, NULL, 0 }
 };
 
@@ -1296,7 +1302,7 @@ int main(int argc, char *argv[])
 
 	page_size = getpagesize();
 
-	while ((c = getopt_long(argc, argv, "aAd::Defhil1noprstvzTS",
+	while ((c = getopt_long(argc, argv, "aAd::Defhil1noprstvzTSN:",
 						opts, NULL)) != -1)
 		switch (c) {
 		case '1':
@@ -1358,7 +1364,13 @@ int main(int argc, char *argv[])
 		case 'S':
 			sort_size = 1;
 			break;
-
+		case 'N':
+			if (optarg) {
+				output_lines = atoi(optarg);
+				if (output_lines < 1)
+					output_lines = 1;
+			}
+			break;
 		default:
 			fatal("%s: Invalid option '%c'\n", argv[0], optopt);
 
-- 
2.6.1.134.g4b1fd35


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 3/8] tools/vm/slabinfo: sort slabs by loss
  2015-10-15 11:14 [RFC][PATCH 0/8] introduce slabinfo extended mode Sergey Senozhatsky
  2015-10-15 11:14 ` [PATCH 1/8] tools/vm/slabinfo: use getopt no_argument/optional_argument Sergey Senozhatsky
  2015-10-15 11:14 ` [PATCH 2/8] tools/vm/slabinfo: limit the number of reported slabs Sergey Senozhatsky
@ 2015-10-15 11:14 ` Sergey Senozhatsky
  2015-10-15 11:14 ` [PATCH 4/8] tools/vm/slabinfo: fix alternate opts names Sergey Senozhatsky
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Sergey Senozhatsky @ 2015-10-15 11:14 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, Sergey Senozhatsky, Sergey Senozhatsky

Introduce opt "-L|--sort-loss" to sort and output slabs by
loss (waste) in slabcache().

Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
---
 tools/vm/slabinfo.c | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/tools/vm/slabinfo.c b/tools/vm/slabinfo.c
index 2ef7f0c..2e154f1 100644
--- a/tools/vm/slabinfo.c
+++ b/tools/vm/slabinfo.c
@@ -80,6 +80,7 @@ int set_debug = 0;
 int show_ops = 0;
 int show_activity = 0;
 int output_lines = -1;
+int sort_loss;
 
 /* Debug options */
 int sanity = 0;
@@ -126,6 +127,7 @@ static void usage(void)
 		"-z|--zero              Include empty slabs\n"
 		"-1|--1ref              Single reference\n"
 		"-N|--lines=K           Show the first K slabs\n"
+		"-L|--Loss              Sort by loss\n"
 		"\nValid debug options (FZPUT may be combined)\n"
 		"a / A          Switch on all debug options (=FZUP)\n"
 		"-              Switch off all debug options\n"
@@ -301,8 +303,9 @@ static void first_line(void)
 	if (show_activity)
 		printf("Name                   Objects      Alloc       Free   %%Fast Fallb O CmpX   UL\n");
 	else
-		printf("Name                   Objects Objsize    Space "
-			"Slabs/Part/Cpu  O/S O %%Fr %%Ef Flg\n");
+		printf("Name                   Objects Objsize    %s "
+			"Slabs/Part/Cpu  O/S O %%Fr %%Ef Flg\n",
+			sort_loss ? "Loss" : "Space");
 }
 
 /*
@@ -335,6 +338,11 @@ static unsigned long slab_activity(struct slabinfo *s)
 		s->alloc_slowpath + s->free_slowpath;
 }
 
+static unsigned long slab_waste(struct slabinfo *s)
+{
+	return	slab_size(s) - s->objects * s->object_size;
+}
+
 static void slab_numa(struct slabinfo *s, int mode)
 {
 	int node;
@@ -563,7 +571,10 @@ static void slabcache(struct slabinfo *s)
 	if (show_empty && s->slabs)
 		return;
 
-	store_size(size_str, slab_size(s));
+	if (sort_loss == 0)
+		store_size(size_str, slab_size(s));
+	else
+		store_size(size_str, slab_waste(s));
 	snprintf(dist_str, 40, "%lu/%lu/%d", s->slabs - s->cpu_slabs,
 						s->partial, s->cpu_slabs);
 
@@ -1013,6 +1024,8 @@ static void sort_slabs(void)
 				result = slab_size(s1) < slab_size(s2);
 			else if (sort_active)
 				result = slab_activity(s1) < slab_activity(s2);
+			else if (sort_loss)
+				result = slab_waste(s1) < slab_waste(s2);
 			else
 				result = strcasecmp(s1->name, s2->name);
 
@@ -1291,6 +1304,7 @@ struct option opts[] = {
 	{ "zero", no_argument, NULL, 'z' },
 	{ "1ref", no_argument, NULL, '1'},
 	{ "lines", required_argument, NULL, 'N'},
+	{ "Loss", no_argument, NULL, 'L'},
 	{ NULL, 0, NULL, 0 }
 };
 
@@ -1302,7 +1316,7 @@ int main(int argc, char *argv[])
 
 	page_size = getpagesize();
 
-	while ((c = getopt_long(argc, argv, "aAd::Defhil1noprstvzTSN:",
+	while ((c = getopt_long(argc, argv, "aAd::Defhil1noprstvzTSN:L",
 						opts, NULL)) != -1)
 		switch (c) {
 		case '1':
@@ -1371,6 +1385,9 @@ int main(int argc, char *argv[])
 					output_lines = 1;
 			}
 			break;
+		case 'L':
+			sort_loss = 1;
+			break;
 		default:
 			fatal("%s: Invalid option '%c'\n", argv[0], optopt);
 
-- 
2.6.1.134.g4b1fd35


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 4/8] tools/vm/slabinfo: fix alternate opts names
  2015-10-15 11:14 [RFC][PATCH 0/8] introduce slabinfo extended mode Sergey Senozhatsky
                   ` (2 preceding siblings ...)
  2015-10-15 11:14 ` [PATCH 3/8] tools/vm/slabinfo: sort slabs by loss Sergey Senozhatsky
@ 2015-10-15 11:14 ` Sergey Senozhatsky
  2015-10-15 11:14 ` [PATCH 5/8] tools/vm/slabinfo: introduce extended totals mode Sergey Senozhatsky
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Sergey Senozhatsky @ 2015-10-15 11:14 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, Sergey Senozhatsky, Sergey Senozhatsky

Fix mismatches between usage() output and real opts[] options.
Add missing alternative opt names, e.g., '-S' had no '--Size'
opts[] entry, etc.

Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
---
 tools/vm/slabinfo.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/tools/vm/slabinfo.c b/tools/vm/slabinfo.c
index 2e154f1..de4974d 100644
--- a/tools/vm/slabinfo.c
+++ b/tools/vm/slabinfo.c
@@ -1294,12 +1294,14 @@ struct option opts[] = {
 	{ "first-alias", no_argument, NULL, 'f' },
 	{ "help", no_argument, NULL, 'h' },
 	{ "inverted", no_argument, NULL, 'i'},
+	{ "slabs", no_argument, NULL, 'l' },
 	{ "numa", no_argument, NULL, 'n' },
 	{ "ops", no_argument, NULL, 'o' },
-	{ "report", no_argument, NULL, 'r' },
 	{ "shrink", no_argument, NULL, 's' },
-	{ "slabs", no_argument, NULL, 'l' },
-	{ "track", no_argument, NULL, 't'},
+	{ "report", no_argument, NULL, 'r' },
+	{ "Size", no_argument, NULL, 'S'},
+	{ "tracking", no_argument, NULL, 't'},
+	{ "Totals", no_argument, NULL, 'T'},
 	{ "validate", no_argument, NULL, 'v' },
 	{ "zero", no_argument, NULL, 'z' },
 	{ "1ref", no_argument, NULL, '1'},
-- 
2.6.1.134.g4b1fd35


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 5/8] tools/vm/slabinfo: introduce extended totals mode
  2015-10-15 11:14 [RFC][PATCH 0/8] introduce slabinfo extended mode Sergey Senozhatsky
                   ` (3 preceding siblings ...)
  2015-10-15 11:14 ` [PATCH 4/8] tools/vm/slabinfo: fix alternate opts names Sergey Senozhatsky
@ 2015-10-15 11:14 ` Sergey Senozhatsky
  2015-10-15 11:14 ` [PATCH 6/8] tools/vm/slabinfo: output sizes in bytes Sergey Senozhatsky
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Sergey Senozhatsky @ 2015-10-15 11:14 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, Sergey Senozhatsky, Sergey Senozhatsky

Add "-X|--Xtotals" opt to output extended totals summary,
which includes:
-- totals summary
-- slabs sorted by size
-- slabs sorted by loss (waste)

Example:
=======

slabinfo --X -N 1
  Slabcache Totals
  ----------------
  Slabcaches :  91      Aliases  : 120->69  Active:  65
  Memory used: 568.3M   # Loss   :  30.4M   MRatio:     5%
  # Objects  : 920.1K   # PartObj: 161.2K   ORatio:    17%

  Per Cache    Average         Min         Max       Total
  ---------------------------------------------------------
  #Objects       14.1K           1      227.8K      920.1K
  #Slabs           533           1       11.7K       34.7K
  #PartSlab         86           0        4.3K        5.6K
  %PartSlab        24%          0%        100%         16%
  PartObjs          17           0      129.3K      161.2K
  % PartObj        17%          0%        100%         17%
  Memory          8.7M        8.1K      384.7M      568.3M
  Used            8.2M         160      366.5M      537.9M
  Loss          468.8K           0       18.2M       30.4M

  Per Object   Average         Min         Max
  ---------------------------------------------
  Memory           587           8        8.1K
  User             584           8        8.1K
  Loss               2           0          64

  Slabs sorted by size
  ----------------------
  Name                   Objects Objsize    Space Slabs/Part/Cpu  O/S O %Fr %Ef Flg
  ext4_inode_cache        211142    1736   384.7M    11732/40/10   18 3   0  95 a

  Slabs sorted by loss
  ----------------------
  Name                   Objects Objsize    Loss Slabs/Part/Cpu  O/S O %Fr %Ef Flg
  ext4_inode_cache        211142    1736    18.2M    11732/40/10   18 3   0  95 a

Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
---
 tools/vm/slabinfo.c | 54 +++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 44 insertions(+), 10 deletions(-)

diff --git a/tools/vm/slabinfo.c b/tools/vm/slabinfo.c
index de4974d..44b83ce 100644
--- a/tools/vm/slabinfo.c
+++ b/tools/vm/slabinfo.c
@@ -81,6 +81,7 @@ int show_ops = 0;
 int show_activity = 0;
 int output_lines = -1;
 int sort_loss;
+int extended_totals;
 
 /* Debug options */
 int sanity = 0;
@@ -128,6 +129,7 @@ static void usage(void)
 		"-1|--1ref              Single reference\n"
 		"-N|--lines=K           Show the first K slabs\n"
 		"-L|--Loss              Sort by loss\n"
+		"-X|--Xtotals           Show extended summary information\n"
 		"\nValid debug options (FZPUT may be combined)\n"
 		"a / A          Switch on all debug options (=FZUP)\n"
 		"-              Switch off all debug options\n"
@@ -615,8 +617,7 @@ static void slabcache(struct slabinfo *s)
 			total_free ? (s->free_fastpath * 100 / total_free) : 0,
 			s->order_fallback, s->order, s->cmpxchg_double_fail,
 			s->cmpxchg_double_cpu_fail);
-	}
-	else
+	} else {
 		printf("%-21s %8ld %7d %8s %14s %4d %1d %3ld %3ld %s\n",
 			s->name, s->objects, s->object_size, size_str, dist_str,
 			s->objs_per_slab, s->order,
@@ -624,6 +625,7 @@ static void slabcache(struct slabinfo *s)
 			s->slabs ? (s->objects * s->object_size * 100) /
 				(s->slabs * (page_size << s->order)) : 100,
 			flags);
+	}
 }
 
 /*
@@ -1256,15 +1258,16 @@ static void read_slab_dir(void)
 static void output_slabs(void)
 {
 	struct slabinfo *slab;
+	int lines = output_lines;
 
 	for (slab = slabinfo; (slab < slabinfo + slabs) &&
-			output_lines != 0; slab++) {
+			lines != 0; slab++) {
 
 		if (slab->alias)
 			continue;
 
-		if (output_lines != -1)
-			output_lines--;
+		if (lines != -1)
+			lines--;
 
 		if (show_numa)
 			slab_numa(slab, 0);
@@ -1285,6 +1288,30 @@ static void output_slabs(void)
 	}
 }
 
+static void xtotals(void)
+{
+	totals();
+
+	link_slabs();
+	rename_slabs();
+
+	printf("\nSlabs sorted by size\n");
+	printf("----------------------\n");
+	sort_loss = 0;
+	sort_size = 1;
+	sort_slabs();
+	output_slabs();
+
+	printf("\nSlabs sorted by loss\n");
+	printf("----------------------\n");
+	line = 0;
+	sort_loss = 1;
+	sort_size = 0;
+	sort_slabs();
+	output_slabs();
+	printf("\n");
+}
+
 struct option opts[] = {
 	{ "aliases", no_argument, NULL, 'a' },
 	{ "activity", no_argument, NULL, 'A' },
@@ -1307,6 +1334,7 @@ struct option opts[] = {
 	{ "1ref", no_argument, NULL, '1'},
 	{ "lines", required_argument, NULL, 'N'},
 	{ "Loss", no_argument, NULL, 'L'},
+	{ "Xtotals", no_argument, NULL, 'X'},
 	{ NULL, 0, NULL, 0 }
 };
 
@@ -1318,7 +1346,7 @@ int main(int argc, char *argv[])
 
 	page_size = getpagesize();
 
-	while ((c = getopt_long(argc, argv, "aAd::Defhil1noprstvzTSN:L",
+	while ((c = getopt_long(argc, argv, "aAd::Defhil1noprstvzTSN:LX",
 						opts, NULL)) != -1)
 		switch (c) {
 		case '1':
@@ -1390,6 +1418,11 @@ int main(int argc, char *argv[])
 		case 'L':
 			sort_loss = 1;
 			break;
+		case 'X':
+			if (output_lines == -1)
+				output_lines = 1;
+			extended_totals = 1;
+			break;
 		default:
 			fatal("%s: Invalid option '%c'\n", argv[0], optopt);
 
@@ -1409,12 +1442,13 @@ int main(int argc, char *argv[])
 		fatal("%s: Invalid pattern '%s' code %d\n",
 			argv[0], pattern_source, err);
 	read_slab_dir();
-	if (show_alias)
+	if (show_alias) {
 		alias();
-	else
-	if (show_totals)
+	} else if (extended_totals) {
+		xtotals();
+	} else if (show_totals) {
 		totals();
-	else {
+	} else {
 		link_slabs();
 		rename_slabs();
 		sort_slabs();
-- 
2.6.1.134.g4b1fd35


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 6/8] tools/vm/slabinfo: output sizes in bytes
  2015-10-15 11:14 [RFC][PATCH 0/8] introduce slabinfo extended mode Sergey Senozhatsky
                   ` (4 preceding siblings ...)
  2015-10-15 11:14 ` [PATCH 5/8] tools/vm/slabinfo: introduce extended totals mode Sergey Senozhatsky
@ 2015-10-15 11:14 ` Sergey Senozhatsky
  2015-10-15 11:14 ` [PATCH 7/8] tools/vm/slabinfo: cosmetic globals cleanup Sergey Senozhatsky
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Sergey Senozhatsky @ 2015-10-15 11:14 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, Sergey Senozhatsky, Sergey Senozhatsky

Introduce "-B|--Bytes" opt to disable store_size() dynamic
size scaling and report size in bytes instead.

This `expands' the interface a bit, it's impossible to use
printf("%6s") anymore to output sizes.

Example:

slabinfo -X -N 2
 Slabcache Totals
 ----------------
 Slabcaches :              91   Aliases  :         119->69   Active:     63
 Memory used:       199798784   # Loss   :        10689376   MRatio:     5%
 # Objects  :          324301   # PartObj:           18151   ORatio:     5%

 Per Cache         Average              Min              Max            Total
 ----------------------------------------------------------------------------
 #Objects             5147                1            89068           324301
 #Slabs                199                1             3886            12537
 #PartSlab              12                0              240              778
 %PartSlab             32%               0%             100%               6%
 PartObjs                5                0             4569            18151
 % PartObj             26%               0%             100%               5%
 Memory            3171409             8192        127336448        199798784
 Used              3001736              160        121429728        189109408
 Loss               169672                0          5906720         10689376

 Per Object        Average              Min              Max
 -----------------------------------------------------------
 Memory                585                8             8192
 User                  583                8             8192
 Loss                    2                0               64

 Slabs sorted by size
 --------------------
 Name                   Objects Objsize           Space Slabs/Part/Cpu  O/S O %Fr %Ef Flg
 ext4_inode_cache         69948    1736       127336448      3871/0/15   18 3   0  95 a
 dentry                   89068     288        26058752      3164/0/17   28 1   0  98 a

 Slabs sorted by loss
 --------------------
 Name                   Objects Objsize            Loss Slabs/Part/Cpu  O/S O %Fr %Ef Flg
 ext4_inode_cache         69948    1736         5906720      3871/0/15   18 3   0  95 a
 inode_cache              11628     864          537472        642/0/4   18 2   0  94 a

Besides, store_size() does not use powers of two for G/M/K

    if (value > 1000000000UL) {
            divisor = 100000000UL;
            trailer = 'G';
    } else if (value > 1000000UL) {
            divisor = 100000UL;
            trailer = 'M';
    } else if (value > 1000UL) {
            divisor = 100;
            trailer = 'K';
    }

Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
---
 tools/vm/slabinfo.c | 88 +++++++++++++++++++++++++++++++----------------------
 1 file changed, 51 insertions(+), 37 deletions(-)

diff --git a/tools/vm/slabinfo.c b/tools/vm/slabinfo.c
index 44b83ce..60beb91 100644
--- a/tools/vm/slabinfo.c
+++ b/tools/vm/slabinfo.c
@@ -82,6 +82,7 @@ int show_activity = 0;
 int output_lines = -1;
 int sort_loss;
 int extended_totals;
+int show_bytes;
 
 /* Debug options */
 int sanity = 0;
@@ -130,6 +131,7 @@ static void usage(void)
 		"-N|--lines=K           Show the first K slabs\n"
 		"-L|--Loss              Sort by loss\n"
 		"-X|--Xtotals           Show extended summary information\n"
+		"-B|--Bytes             Show size in bytes\n"
 		"\nValid debug options (FZPUT may be combined)\n"
 		"a / A          Switch on all debug options (=FZUP)\n"
 		"-              Switch off all debug options\n"
@@ -231,15 +233,17 @@ static int store_size(char *buffer, unsigned long value)
 	char trailer = 0;
 	int n;
 
-	if (value > 1000000000UL) {
-		divisor = 100000000UL;
-		trailer = 'G';
-	} else if (value > 1000000UL) {
-		divisor = 100000UL;
-		trailer = 'M';
-	} else if (value > 1000UL) {
-		divisor = 100;
-		trailer = 'K';
+	if (!show_bytes) {
+		if (value > 1000000000UL) {
+			divisor = 100000000UL;
+			trailer = 'G';
+		} else if (value > 1000000UL) {
+			divisor = 100000UL;
+			trailer = 'M';
+		} else if (value > 1000UL) {
+			divisor = 100;
+			trailer = 'K';
+		}
 	}
 
 	value /= divisor;
@@ -303,11 +307,12 @@ int line = 0;
 static void first_line(void)
 {
 	if (show_activity)
-		printf("Name                   Objects      Alloc       Free   %%Fast Fallb O CmpX   UL\n");
+		printf("Name                   Objects      Alloc       Free"
+			"   %%Fast Fallb O CmpX   UL\n");
 	else
-		printf("Name                   Objects Objsize    %s "
+		printf("Name                   Objects Objsize           %s "
 			"Slabs/Part/Cpu  O/S O %%Fr %%Ef Flg\n",
-			sort_loss ? "Loss" : "Space");
+			sort_loss ? " Loss" : "Space");
 }
 
 /*
@@ -516,7 +521,7 @@ static void report(struct slabinfo *s)
 	if (strcmp(s->name, "*") == 0)
 		return;
 
-	printf("\nSlabcache: %-20s  Aliases: %2d Order : %2d Objects: %lu\n",
+	printf("\nSlabcache: %-15s  Aliases: %2d Order : %2d Objects: %lu\n",
 		s->name, s->aliases, s->order, s->objects);
 	if (s->hwcache_align)
 		printf("** Hardware cacheline aligned\n");
@@ -618,7 +623,7 @@ static void slabcache(struct slabinfo *s)
 			s->order_fallback, s->order, s->cmpxchg_double_fail,
 			s->cmpxchg_double_cpu_fail);
 	} else {
-		printf("%-21s %8ld %7d %8s %14s %4d %1d %3ld %3ld %s\n",
+		printf("%-21s %8ld %7d %15s %14s %4d %1d %3ld %3ld %s\n",
 			s->name, s->objects, s->object_size, size_str, dist_str,
 			s->objs_per_slab, s->order,
 			s->slabs ? (s->partial * 100) / s->slabs : 100,
@@ -933,84 +938,88 @@ static void totals(void)
 
 	printf("Slabcache Totals\n");
 	printf("----------------\n");
-	printf("Slabcaches : %3d      Aliases  : %3d->%-3d Active: %3d\n",
+	printf("Slabcaches : %15d   Aliases  : %11d->%-3d  Active:    %3d\n",
 			slabs, aliases, alias_targets, used_slabs);
 
 	store_size(b1, total_size);store_size(b2, total_waste);
 	store_size(b3, total_waste * 100 / total_used);
-	printf("Memory used: %6s   # Loss   : %6s   MRatio:%6s%%\n", b1, b2, b3);
+	printf("Memory used: %15s   # Loss   : %15s   MRatio:%6s%%\n", b1, b2, b3);
 
 	store_size(b1, total_objects);store_size(b2, total_partobj);
 	store_size(b3, total_partobj * 100 / total_objects);
-	printf("# Objects  : %6s   # PartObj: %6s   ORatio:%6s%%\n", b1, b2, b3);
+	printf("# Objects  : %15s   # PartObj: %15s   ORatio:%6s%%\n", b1, b2, b3);
 
 	printf("\n");
-	printf("Per Cache    Average         Min         Max       Total\n");
-	printf("---------------------------------------------------------\n");
+	printf("Per Cache         Average              "
+		"Min              Max            Total\n");
+	printf("---------------------------------------"
+		"-------------------------------------\n");
 
 	store_size(b1, avg_objects);store_size(b2, min_objects);
 	store_size(b3, max_objects);store_size(b4, total_objects);
-	printf("#Objects  %10s  %10s  %10s  %10s\n",
+	printf("#Objects  %15s  %15s  %15s  %15s\n",
 			b1,	b2,	b3,	b4);
 
 	store_size(b1, avg_slabs);store_size(b2, min_slabs);
 	store_size(b3, max_slabs);store_size(b4, total_slabs);
-	printf("#Slabs    %10s  %10s  %10s  %10s\n",
+	printf("#Slabs    %15s  %15s  %15s  %15s\n",
 			b1,	b2,	b3,	b4);
 
 	store_size(b1, avg_partial);store_size(b2, min_partial);
 	store_size(b3, max_partial);store_size(b4, total_partial);
-	printf("#PartSlab %10s  %10s  %10s  %10s\n",
+	printf("#PartSlab %15s  %15s  %15s  %15s\n",
 			b1,	b2,	b3,	b4);
 	store_size(b1, avg_ppart);store_size(b2, min_ppart);
 	store_size(b3, max_ppart);
 	store_size(b4, total_partial * 100  / total_slabs);
-	printf("%%PartSlab%10s%% %10s%% %10s%% %10s%%\n",
+	printf("%%PartSlab%15s%% %15s%% %15s%% %15s%%\n",
 			b1,	b2,	b3,	b4);
 
 	store_size(b1, avg_partobj);store_size(b2, min_partobj);
 	store_size(b3, max_partobj);
 	store_size(b4, total_partobj);
-	printf("PartObjs  %10s  %10s  %10s  %10s\n",
+	printf("PartObjs  %15s  %15s  %15s  %15s\n",
 			b1,	b2,	b3,	b4);
 
 	store_size(b1, avg_ppartobj);store_size(b2, min_ppartobj);
 	store_size(b3, max_ppartobj);
 	store_size(b4, total_partobj * 100 / total_objects);
-	printf("%% PartObj%10s%% %10s%% %10s%% %10s%%\n",
+	printf("%% PartObj%15s%% %15s%% %15s%% %15s%%\n",
 			b1,	b2,	b3,	b4);
 
 	store_size(b1, avg_size);store_size(b2, min_size);
 	store_size(b3, max_size);store_size(b4, total_size);
-	printf("Memory    %10s  %10s  %10s  %10s\n",
+	printf("Memory    %15s  %15s  %15s  %15s\n",
 			b1,	b2,	b3,	b4);
 
 	store_size(b1, avg_used);store_size(b2, min_used);
 	store_size(b3, max_used);store_size(b4, total_used);
-	printf("Used      %10s  %10s  %10s  %10s\n",
+	printf("Used      %15s  %15s  %15s  %15s\n",
 			b1,	b2,	b3,	b4);
 
 	store_size(b1, avg_waste);store_size(b2, min_waste);
 	store_size(b3, max_waste);store_size(b4, total_waste);
-	printf("Loss      %10s  %10s  %10s  %10s\n",
+	printf("Loss      %15s  %15s  %15s  %15s\n",
 			b1,	b2,	b3,	b4);
 
 	printf("\n");
-	printf("Per Object   Average         Min         Max\n");
-	printf("---------------------------------------------\n");
+	printf("Per Object        Average              "
+		"Min              Max\n");
+	printf("---------------------------------------"
+		"--------------------\n");
 
 	store_size(b1, avg_memobj);store_size(b2, min_memobj);
 	store_size(b3, max_memobj);
-	printf("Memory    %10s  %10s  %10s\n",
+	printf("Memory    %15s  %15s  %15s\n",
 			b1,	b2,	b3);
 	store_size(b1, avg_objsize);store_size(b2, min_objsize);
 	store_size(b3, max_objsize);
-	printf("User      %10s  %10s  %10s\n",
+	printf("User      %15s  %15s  %15s\n",
 			b1,	b2,	b3);
 
 	store_size(b1, avg_objwaste);store_size(b2, min_objwaste);
 	store_size(b3, max_objwaste);
-	printf("Loss      %10s  %10s  %10s\n",
+	printf("Loss      %15s  %15s  %15s\n",
 			b1,	b2,	b3);
 }
 
@@ -1112,7 +1121,7 @@ static void alias(void)
 			active = a->slab->name;
 		}
 		else
-			printf("%-20s -> %s\n", a->name, a->slab->name);
+			printf("%-15s -> %s\n", a->name, a->slab->name);
 	}
 	if (active)
 		printf("\n");
@@ -1296,14 +1305,14 @@ static void xtotals(void)
 	rename_slabs();
 
 	printf("\nSlabs sorted by size\n");
-	printf("----------------------\n");
+	printf("--------------------\n");
 	sort_loss = 0;
 	sort_size = 1;
 	sort_slabs();
 	output_slabs();
 
 	printf("\nSlabs sorted by loss\n");
-	printf("----------------------\n");
+	printf("--------------------\n");
 	line = 0;
 	sort_loss = 1;
 	sort_size = 0;
@@ -1335,6 +1344,7 @@ struct option opts[] = {
 	{ "lines", required_argument, NULL, 'N'},
 	{ "Loss", no_argument, NULL, 'L'},
 	{ "Xtotals", no_argument, NULL, 'X'},
+	{ "Bytes", no_argument, NULL, 'B'},
 	{ NULL, 0, NULL, 0 }
 };
 
@@ -1346,7 +1356,7 @@ int main(int argc, char *argv[])
 
 	page_size = getpagesize();
 
-	while ((c = getopt_long(argc, argv, "aAd::Defhil1noprstvzTSN:LX",
+	while ((c = getopt_long(argc, argv, "aAd::Defhil1noprstvzTSN:LXB",
 						opts, NULL)) != -1)
 		switch (c) {
 		case '1':
@@ -1422,6 +1432,10 @@ int main(int argc, char *argv[])
 			if (output_lines == -1)
 				output_lines = 1;
 			extended_totals = 1;
+			show_bytes = 1;
+			break;
+		case 'B':
+			show_bytes = 1;
 			break;
 		default:
 			fatal("%s: Invalid option '%c'\n", argv[0], optopt);
-- 
2.6.1.134.g4b1fd35


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 7/8] tools/vm/slabinfo: cosmetic globals cleanup
  2015-10-15 11:14 [RFC][PATCH 0/8] introduce slabinfo extended mode Sergey Senozhatsky
                   ` (5 preceding siblings ...)
  2015-10-15 11:14 ` [PATCH 6/8] tools/vm/slabinfo: output sizes in bytes Sergey Senozhatsky
@ 2015-10-15 11:14 ` Sergey Senozhatsky
  2015-10-15 11:14 ` [PATCH 8/8] tools/vm/slabinfo: gnuplot slabifo extended stat Sergey Senozhatsky
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 12+ messages in thread
From: Sergey Senozhatsky @ 2015-10-15 11:14 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, Sergey Senozhatsky, Sergey Senozhatsky

checkpatch.pl complains about globals being explicitly zeroed
out: "ERROR: do not initialise globals to 0 or NULL".

New globals, introduced in this patch set, have no explicit 0
initialization; clean up the old ones to make it less hairy.

Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
---
 tools/vm/slabinfo.c | 54 ++++++++++++++++++++++++++---------------------------
 1 file changed, 27 insertions(+), 27 deletions(-)

diff --git a/tools/vm/slabinfo.c b/tools/vm/slabinfo.c
index 60beb91..86e698d0 100644
--- a/tools/vm/slabinfo.c
+++ b/tools/vm/slabinfo.c
@@ -53,43 +53,43 @@ struct aliasinfo {
 	struct slabinfo *slab;
 } aliasinfo[MAX_ALIASES];
 
-int slabs = 0;
-int actual_slabs = 0;
-int aliases = 0;
-int alias_targets = 0;
-int highest_node = 0;
+int slabs;
+int actual_slabs;
+int aliases;
+int alias_targets;
+int highest_node;
 
 char buffer[4096];
 
-int show_empty = 0;
-int show_report = 0;
-int show_alias = 0;
-int show_slab = 0;
+int show_empty;
+int show_report;
+int show_alias;
+int show_slab;
 int skip_zero = 1;
-int show_numa = 0;
-int show_track = 0;
-int show_first_alias = 0;
-int validate = 0;
-int shrink = 0;
-int show_inverted = 0;
-int show_single_ref = 0;
-int show_totals = 0;
-int sort_size = 0;
-int sort_active = 0;
-int set_debug = 0;
-int show_ops = 0;
-int show_activity = 0;
+int show_numa;
+int show_track;
+int show_first_alias;
+int validate;
+int shrink;
+int show_inverted;
+int show_single_ref;
+int show_totals;
+int sort_size;
+int sort_active;
+int set_debug;
+int show_ops;
+int show_activity;
 int output_lines = -1;
 int sort_loss;
 int extended_totals;
 int show_bytes;
 
 /* Debug options */
-int sanity = 0;
-int redzone = 0;
-int poison = 0;
-int tracking = 0;
-int tracing = 0;
+int sanity;
+int redzone;
+int poison;
+int tracking;
+int tracing;
 
 int page_size;
 
-- 
2.6.1.134.g4b1fd35


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 8/8] tools/vm/slabinfo: gnuplot slabifo extended stat
  2015-10-15 11:14 [RFC][PATCH 0/8] introduce slabinfo extended mode Sergey Senozhatsky
                   ` (6 preceding siblings ...)
  2015-10-15 11:14 ` [PATCH 7/8] tools/vm/slabinfo: cosmetic globals cleanup Sergey Senozhatsky
@ 2015-10-15 11:14 ` Sergey Senozhatsky
  2015-10-15 11:33 ` [RFC][PATCH 0/8] introduce slabinfo extended mode Sergey Senozhatsky
  2015-10-16 22:35 ` Andrew Morton
  9 siblings, 0 replies; 12+ messages in thread
From: Sergey Senozhatsky @ 2015-10-15 11:14 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, Sergey Senozhatsky, Sergey Senozhatsky

GNUplot `slabinfo -X' stats, collected, for example, using the
following command:
  while [ 1 ]; do slabinfo -X >> stats; sleep 1; done

`slabinfo-gnuplot.sh stats' pre-processes collected records
and generate graphs (totals, slabs sorted by size, slabs
sorted by size).

Graphs can be [individually] regenerate with different samples
range and graph width-heigh (-r %d,%d and -s %d,%d options).

To visually compare N `totals' graphs:
  slabinfo-gnuplot.sh -t FILE1-totals FILE2-totals ... FILEN-totals

Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
---
 tools/vm/slabinfo-gnuplot.sh | 275 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 275 insertions(+)
 create mode 100755 tools/vm/slabinfo-gnuplot.sh

diff --git a/tools/vm/slabinfo-gnuplot.sh b/tools/vm/slabinfo-gnuplot.sh
new file mode 100755
index 0000000..35b0398
--- /dev/null
+++ b/tools/vm/slabinfo-gnuplot.sh
@@ -0,0 +1,275 @@
+#!/bin/sh
+
+# Sergey Senozhatsky, 2015
+# sergey.senozhatsky.work@gmail.com
+#
+# This software is licensed under the terms of the GNU General Public
+# License version 2, as published by the Free Software Foundation, and
+# may be copied, distributed, and modified under those terms.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+
+# This program is intended to plot a `slabinfo -X' stats, collected,
+# for example, using the following command:
+#   while [ 1 ]; do slabinfo -X >> stats; sleep 1; done
+#
+# Use `slabinfo-gnuplot.sh stats' to pre-process collected records
+# and generate graphs (totals, slabs sorted by size, slabs sorted
+# by size).
+#
+# Graphs can be [individually] regenerate with different ranges and
+# size (-r %d,%d and -s %d,%d options).
+#
+# To visually compare N `totals' graphs, do
+# slabinfo-gnuplot.sh -t FILE1-totals FILE2-totals ... FILEN-totals
+#
+
+min_slab_name_size=11
+xmin=0
+xmax=0
+width=1500
+height=700
+mode=preprocess
+
+usage()
+{
+	echo "Usage: [-s W,H] [-r MIN,MAX] [-t|-l] FILE1 [FILE2 ..]"
+	echo "FILEs must contain 'slabinfo -X' samples"
+	echo "-t 			- plot totals for FILE(s)"
+	echo "-l 			- plot slabs stats for FILE(s)"
+	echo "-s %d,%d		- set image width and height"
+	echo "-r %d,%d		- use data samples from a given range"
+}
+
+check_file_exist()
+{
+	if [ ! -f "$1" ]; then
+		echo "File '$1' does not exist"
+		exit 1
+	fi
+}
+
+do_slabs_plotting()
+{
+	local file=$1
+	local out_file
+	local range="every ::$xmin"
+	local xtic=""
+	local xtic_rotate="norotate"
+	local lines=2000000
+	local wc_lines
+
+	check_file_exist "$file"
+
+	out_file=`basename "$file"`
+	if [ $xmax -ne 0 ]; then
+		range="$range::$xmax"
+		lines=$((xmax-xmin))
+	fi
+
+	wc_lines=`cat "$file" | wc -l`
+	if [ $? -ne 0 ] || [ "$wc_lines" -eq 0 ] ; then
+		wc_lines=$lines
+	fi
+
+	if [ "$wc_lines" -lt "$lines" ]; then
+		lines=$wc_lines
+	fi
+
+	if [ $((width / lines)) -gt $min_slab_name_size ]; then
+		xtic=":xtic(1)"
+		xtic_rotate=90
+	fi
+
+gnuplot -p << EOF
+#!/usr/bin/env gnuplot
+
+set terminal png enhanced size $width,$height large
+set output '$out_file.png'
+set autoscale xy
+set xlabel 'samples'
+set ylabel 'bytes'
+set style histogram columnstacked title textcolor lt -1
+set style fill solid 0.15
+set xtics rotate $xtic_rotate
+set key left above Left title reverse
+
+plot "$file" $range u 2$xtic title 'SIZE' with boxes,\
+	'' $range u 3 title 'LOSS' with boxes
+EOF
+
+	if [ $? -eq 0 ]; then
+		echo "$out_file.png"
+	fi
+}
+
+do_totals_plotting()
+{
+	local gnuplot_cmd=""
+	local range="every ::$xmin"
+	local file=""
+
+	if [ $xmax -ne 0 ]; then
+		range="$range::$xmax"
+	fi
+
+	for i in "${t_files[@]}"; do
+		check_file_exist "$i"
+
+		file="$file"`basename "$i"`
+		gnuplot_cmd="$gnuplot_cmd '$i' $range using 1 title\
+			'$i Memory usage' with lines,"
+		gnuplot_cmd="$gnuplot_cmd '' $range using 2 title \
+			'$i Loss' with lines,"
+	done
+
+gnuplot -p << EOF
+#!/usr/bin/env gnuplot
+
+set terminal png enhanced size $width,$height large
+set autoscale xy
+set output '$file.png'
+set xlabel 'samples'
+set ylabel 'bytes'
+set key left above Left title reverse
+
+plot $gnuplot_cmd
+EOF
+
+	if [ $? -eq 0 ]; then
+		echo "$file.png"
+	fi
+}
+
+do_preprocess()
+{
+	local out
+	local lines
+	local in=$1
+
+	check_file_exist "$in"
+
+	# use only 'TOP' slab (biggest memory usage or loss)
+	let lines=3
+	out=`basename "$in"`"-slabs-by-loss"
+	`cat "$in" | grep -A "$lines" 'Slabs sorted by loss' |\
+		egrep -iv '\-\-|Name|Slabs'\
+		| awk '{print $1" "$4+$2*$3" "$4}' > "$out"`
+	if [ $? -eq 0 ]; then
+		do_slabs_plotting "$out"
+	fi
+
+	let lines=3
+	out=`basename "$in"`"-slabs-by-size"
+	`cat "$in" | grep -A "$lines" 'Slabs sorted by size' |\
+		egrep -iv '\-\-|Name|Slabs'\
+		| awk '{print $1" "$4" "$4-$2*$3}' > "$out"`
+	if [ $? -eq 0 ]; then
+		do_slabs_plotting "$out"
+	fi
+
+	out=`basename "$in"`"-totals"
+	`cat "$in" | grep "Memory used" |\
+		awk '{print $3" "$7}' > "$out"`
+	if [ $? -eq 0 ]; then
+		t_files[0]=$out
+		do_totals_plotting
+	fi
+}
+
+parse_opts()
+{
+	local opt
+
+	while getopts "tlr::s::h" opt; do
+		case $opt in
+			t)
+				mode=totals
+				;;
+			l)
+				mode=slabs
+				;;
+			s)
+				array=(${OPTARG//,/ })
+				width=${array[0]}
+				height=${array[1]}
+				;;
+			r)
+				array=(${OPTARG//,/ })
+				xmin=${array[0]}
+				xmax=${array[1]}
+				;;
+			h)
+				usage
+				exit 0
+				;;
+			\?)
+				echo "Invalid option: -$OPTARG" >&2
+				exit 1
+				;;
+			:)
+				echo "-$OPTARG requires an argument." >&2
+				exit 1
+				;;
+		esac
+	done
+
+	return $OPTIND
+}
+
+parse_args()
+{
+	local idx=0
+	local p
+
+	for p in "$@"; do
+		case $mode in
+			preprocess)
+				files[$idx]=$p
+				idx=$idx+1
+				;;
+			totals)
+				t_files[$idx]=$p
+				idx=$idx+1
+				;;
+			slabs)
+				files[$idx]=$p
+				idx=$idx+1
+				;;
+		esac
+	done
+}
+
+parse_opts "$@"
+argstart=$?
+parse_args "${@:$argstart}"
+
+if [ ${#files[@]} -eq 0 ] && [ ${#t_files[@]} -eq 0 ]; then
+	usage
+	exit 1
+fi
+
+case $mode in
+	preprocess)
+		for i in "${files[@]}"; do
+			do_preprocess "$i"
+		done
+		;;
+	totals)
+		do_totals_plotting
+		;;
+	slabs)
+		for i in "${files[@]}"; do
+			do_slabs_plotting "$i"
+		done
+		;;
+	*)
+		echo "Unknown mode $mode" >&2
+		usage
+		exit 1
+	;;
+esac
-- 
2.6.1.134.g4b1fd35


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [RFC][PATCH 0/8] introduce slabinfo extended mode
  2015-10-15 11:14 [RFC][PATCH 0/8] introduce slabinfo extended mode Sergey Senozhatsky
                   ` (7 preceding siblings ...)
  2015-10-15 11:14 ` [PATCH 8/8] tools/vm/slabinfo: gnuplot slabifo extended stat Sergey Senozhatsky
@ 2015-10-15 11:33 ` Sergey Senozhatsky
  2015-10-16 22:35 ` Andrew Morton
  9 siblings, 0 replies; 12+ messages in thread
From: Sergey Senozhatsky @ 2015-10-15 11:33 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel, Sergey Senozhatsky, Sergey Senozhatsky

[-- Attachment #1: Type: text/plain, Size: 183 bytes --]

On (10/15/15 20:14), Sergey Senozhatsky wrote:
> Examples of graphs will be attached in a follow up letter.
> 

Please find attached.
(graphs of `git make' using ssd and zram).

	-ss

[-- Attachment #2: git-compile-ssd-totalsgit-compile-zram-totals.png --]
[-- Type: image/png, Size: 6347 bytes --]

[-- Attachment #3: git-compile-ssd-slabs-by-loss.png --]
[-- Type: image/png, Size: 6904 bytes --]

[-- Attachment #4: git-compile-ssd-slabs-by-size.png --]
[-- Type: image/png, Size: 6904 bytes --]

[-- Attachment #5: git-compile-ssd-totals.png --]
[-- Type: image/png, Size: 5417 bytes --]

[-- Attachment #6: git-compile-zram-slabs-by-loss.png --]
[-- Type: image/png, Size: 11240 bytes --]

[-- Attachment #7: git-compile-zram-slabs-by-size.png --]
[-- Type: image/png, Size: 11240 bytes --]

[-- Attachment #8: git-compile-zram-totals.png --]
[-- Type: image/png, Size: 5569 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC][PATCH 0/8] introduce slabinfo extended mode
  2015-10-15 11:14 [RFC][PATCH 0/8] introduce slabinfo extended mode Sergey Senozhatsky
                   ` (8 preceding siblings ...)
  2015-10-15 11:33 ` [RFC][PATCH 0/8] introduce slabinfo extended mode Sergey Senozhatsky
@ 2015-10-16 22:35 ` Andrew Morton
  2015-10-17  2:22   ` Sergey Senozhatsky
  9 siblings, 1 reply; 12+ messages in thread
From: Andrew Morton @ 2015-10-16 22:35 UTC (permalink / raw)
  To: Sergey Senozhatsky
  Cc: linux-kernel, Sergey Senozhatsky, linux-mm, Christoph Lameter

On Thu, 15 Oct 2015 20:14:25 +0900 Sergey Senozhatsky <sergey.senozhatsky@gmail.com> wrote:

> Add 'extended' slabinfo mode that provides additional information:
>  -- totals summary
>  -- slabs sorted by size
>  -- slabs sorted by loss (waste)
> 
> The patches also introduces several new slabinfo options to limit the
> number of slabs reported, sort slabs by loss (waste); and some fixes.

hm, why the "RFC"?  These patches look more mature than most of the
stuff I get ;)

You should have cc'ed linux-mm on these patches: nobody will have
noticed them.

slabinfo is documented a bit in Documentation/vm/slub.txt.  Please
review that file for accuracy and completeness.  It should at least
draw readers' attention to the new tools/vm/slabinfo-gnuplot.sh.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [RFC][PATCH 0/8] introduce slabinfo extended mode
  2015-10-16 22:35 ` Andrew Morton
@ 2015-10-17  2:22   ` Sergey Senozhatsky
  0 siblings, 0 replies; 12+ messages in thread
From: Sergey Senozhatsky @ 2015-10-17  2:22 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Sergey Senozhatsky, linux-kernel, Sergey Senozhatsky, linux-mm,
	Christoph Lameter

On (10/16/15 15:35), Andrew Morton wrote:
> On Thu, 15 Oct 2015 20:14:25 +0900 Sergey Senozhatsky <sergey.senozhatsky@gmail.com> wrote:
> 
> > Add 'extended' slabinfo mode that provides additional information:
> >  -- totals summary
> >  -- slabs sorted by size
> >  -- slabs sorted by loss (waste)
> > 
> > The patches also introduces several new slabinfo options to limit the
> > number of slabs reported, sort slabs by loss (waste); and some fixes.
> 
> hm, why the "RFC"?  These patches look more mature than most of the
> stuff I get ;)
> 

Thank you, sir.

I wasn't so sure about the gnuplot script, that's why I added RFC.


> You should have cc'ed linux-mm on these patches: nobody will have
> noticed them.

I should have done that, my bad.
`./scripts/get_maintainer.pl -f tools/vm/' confused me.


> slabinfo is documented a bit in Documentation/vm/slub.txt.  Please
> review that file for accuracy and completeness.  It should at least
> draw readers' attention to the new tools/vm/slabinfo-gnuplot.sh.

Will take a look.

	-ss

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2015-10-17  2:23 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-10-15 11:14 [RFC][PATCH 0/8] introduce slabinfo extended mode Sergey Senozhatsky
2015-10-15 11:14 ` [PATCH 1/8] tools/vm/slabinfo: use getopt no_argument/optional_argument Sergey Senozhatsky
2015-10-15 11:14 ` [PATCH 2/8] tools/vm/slabinfo: limit the number of reported slabs Sergey Senozhatsky
2015-10-15 11:14 ` [PATCH 3/8] tools/vm/slabinfo: sort slabs by loss Sergey Senozhatsky
2015-10-15 11:14 ` [PATCH 4/8] tools/vm/slabinfo: fix alternate opts names Sergey Senozhatsky
2015-10-15 11:14 ` [PATCH 5/8] tools/vm/slabinfo: introduce extended totals mode Sergey Senozhatsky
2015-10-15 11:14 ` [PATCH 6/8] tools/vm/slabinfo: output sizes in bytes Sergey Senozhatsky
2015-10-15 11:14 ` [PATCH 7/8] tools/vm/slabinfo: cosmetic globals cleanup Sergey Senozhatsky
2015-10-15 11:14 ` [PATCH 8/8] tools/vm/slabinfo: gnuplot slabifo extended stat Sergey Senozhatsky
2015-10-15 11:33 ` [RFC][PATCH 0/8] introduce slabinfo extended mode Sergey Senozhatsky
2015-10-16 22:35 ` Andrew Morton
2015-10-17  2:22   ` Sergey Senozhatsky

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox