tools/vm/slabinfo: use alphabetic order when two values are equal
authorYuanzheng Song <songyuanzheng@huawei.com>
Sat, 28 May 2022 06:31:17 +0000 (06:31 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 25 Aug 2022 09:40:13 +0000 (11:40 +0200)
commit 4f5ceb8851f0081af54313abbf56de1615911faf upstream.

When the number of partial slabs in each cache is the same (e.g., the
value are 0), the results of the `slabinfo -X -N5` and `slabinfo -P -N5`
are different.

/ # slabinfo -X -N5
...
Slabs sorted by number of partial slabs
---------------------------------------
Name                   Objects Objsize           Space Slabs/Part/Cpu  O/S O %Fr %Ef Flg
inode_cache              15180     392         6217728        758/0/1   20 1   0  95 a
kernfs_node_cache        22494      88         2002944        488/0/1   46 0   0  98
shmem_inode_cache          663     464          319488         38/0/1   17 1   0  96
biovec-max                  50    3072          163840          4/0/1   10 3   0  93 A
dentry                   19050     136         2600960        633/0/2   30 0   0  99 a

/ # slabinfo -P -N5
Name                   Objects Objsize           Space Slabs/Part/Cpu  O/S O %Fr %Ef Flg
bdev_cache                  32     984           32.7K          1/0/1   16 2   0  96 Aa
ext4_inode_cache            42     752           32.7K          1/0/1   21 2   0  96 a
dentry                   19050     136            2.6M        633/0/2   30 0   0  99 a
TCPv6                       17    1840           32.7K          0/0/1   17 3   0  95 A
RAWv6                       18     856           16.3K          0/0/1   18 2   0  94 A

This problem is caused by the sort_slabs().  So let's use alphabetic order
when two values are equal in the sort_slabs().

By the way, the content of the `slabinfo -h` is not aligned because the

`-P|--partial Sort by number of partial slabs`

uses tabs instead of spaces.  So let's use spaces instead of tabs to fix
it.

Link: https://lkml.kernel.org/r/20220528063117.935158-1-songyuanzheng@huawei.com
Fixes: 1106b205a3fe ("tools/vm/slabinfo: add partial slab listing to -X")
Signed-off-by: Yuanzheng Song <songyuanzheng@huawei.com>
Cc: "Tobin C. Harding" <tobin@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
tools/vm/slabinfo.c

index 5b98f3e..0fffaee 100644 (file)
@@ -125,7 +125,7 @@ static void usage(void)
                "-n|--numa              Show NUMA information\n"
                "-N|--lines=K           Show the first K slabs\n"
                "-o|--ops               Show kmem_cache_ops\n"
-               "-P|--partial           Sort by number of partial slabs\n"
+               "-P|--partial           Sort by number of partial slabs\n"
                "-r|--report            Detailed report on single slabs\n"
                "-s|--shrink            Shrink slabs\n"
                "-S|--Size              Sort by size\n"
@@ -1067,15 +1067,27 @@ static void sort_slabs(void)
                for (s2 = s1 + 1; s2 < slabinfo + slabs; s2++) {
                        int result;
 
-                       if (sort_size)
-                               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 if (sort_partial)
-                               result = s1->partial < s2->partial;
-                       else
+                       if (sort_size) {
+                               if (slab_size(s1) == slab_size(s2))
+                                       result = strcasecmp(s1->name, s2->name);
+                               else
+                                       result = slab_size(s1) < slab_size(s2);
+                       } else if (sort_active) {
+                               if (slab_activity(s1) == slab_activity(s2))
+                                       result = strcasecmp(s1->name, s2->name);
+                               else
+                                       result = slab_activity(s1) < slab_activity(s2);
+                       } else if (sort_loss) {
+                               if (slab_waste(s1) == slab_waste(s2))
+                                       result = strcasecmp(s1->name, s2->name);
+                               else
+                                       result = slab_waste(s1) < slab_waste(s2);
+                       } else if (sort_partial) {
+                               if (s1->partial == s2->partial)
+                                       result = strcasecmp(s1->name, s2->name);
+                               else
+                                       result = s1->partial < s2->partial;
+                       } else
                                result = strcasecmp(s1->name, s2->name);
 
                        if (show_inverted)