[Crash-utility] [PATCH] "kmem -i" extremely slow on dumps from large memory systems

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The “kmem -i” command is extremely slow (appears to hang) on dumps from large memory systems.

 

For example, on 120GB crash dump from a high-end server with 32TB of RAM (ie. 8Giga Pages),

the “kmem -i” command is taking over 50 minutes to execute on a DL380 Gen10. To report basic

general memory usage figures, we should only be reading global counters, without having to walk

the full flat/sparse mem map page table. Hence, dump_kmeminfo() should first be reading globals,

and then only call dump_mem_map() if important information (ie. slabs or total ram) is missing.

 

Signed-off-by: Georges Aureau <georges.aureau@xxxxxxx>

--

diff --git a/memory.c b/memory.c

index 8c01ed0..8e2b2e9 100644

--- a/memory.c

+++ b/memory.c

@@ -8546,18 +8546,19 @@ dump_kmeminfo(void)

         ulong get_buffers;

         ulong get_slabs;

             char buf[BUFSIZE];

+            ulong flags;

-

-             BZERO(&meminfo, sizeof(struct meminfo));

-             meminfo.flags = GET_ALL;

-             dump_mem_map(&meminfo);

-             get_totalram = meminfo.get_totalram;

-             shared_pages = meminfo.get_shared;

-             get_buffers = meminfo.get_buffers;

-             get_slabs = meminfo.get_slabs;

+            /*

+            * By default, we will no longer call dump_mem_map() as this is too

+            * slow for large memory systems. If we have to call it (eg. missing

+            * important information such as slabs or total ram), we will also

+            * collect shared pages. Otherwise, we won't print shared pages.

+            */

+            flags = GET_SHARED_PAGES;

+            shared_pages = 0;

              /*

-             *  If vm_stat array exists, override page search info.

+            *  If vm_stat array does not exists, then set mem map flag.

              */

             if (vm_stat_init()) {

                            if (dump_vm_stat("NR_SLAB", &nr_slab, 0))

@@ -8571,10 +8572,11 @@ dump_kmeminfo(void)

                                          get_slabs = nr_slab;

                                          if (dump_vm_stat("NR_SLAB_UNRECLAIMABLE_B", &nr_slab, 0))

                                                         get_slabs += nr_slab;

+                           } else {

+                                         flags |= GET_SLAB_PAGES;

                            }

             }

-             fprintf(fp, "%s", kmeminfo_hdr);

             /*

              *  Get total RAM based upon how the various versions of si_meminfo()

          *  have done it, latest to earliest:

@@ -8586,9 +8588,32 @@ dump_kmeminfo(void)

                 symbol_exists("_totalram_pages")) {

                            totalram_pages = vt->totalram_pages ?

                                           vt->totalram_pages : get_totalram;

-             } else

-                           totalram_pages = get_totalram;

+            } else {

+                           flags |= GET_TOTALRAM_PAGES;

+            }

+            /*

+            * If we want more than just shared pages (missing slabs or total ram)

+            * then call dump_mem_map() and also collect buffers.

+            */

+            if (flags != GET_SHARED_PAGES) {

+                           BZERO(&meminfo, sizeof(struct meminfo));

+                           flags |= GET_BUFFERS_PAGES;

+                           meminfo.flags = flags;

+                           dump_mem_map(&meminfo);

+                           /* Update the missing information */

+                           if (flags & GET_SLAB_PAGES) {

+                                         get_slabs = meminfo.get_slabs;

+                           }

+                           if (flags & GET_TOTALRAM_PAGES) {

+                                         get_totalram = meminfo.get_totalram;

+                                         totalram_pages = get_totalram;

+                           }

+                           shared_pages = meminfo.get_shared;

+                           get_buffers = meminfo.get_buffers;

+            }

+

+            fprintf(fp, "%s", kmeminfo_hdr);

             fprintf(fp, "%13s  %7ld  %11s         ----\n", "TOTAL MEM",

                             totalram_pages, pages_to_size(totalram_pages, buf));

@@ -8613,9 +8638,11 @@ dump_kmeminfo(void)

          *  differently than the kernel -- it just tallies the non-reserved

          *  pages that have a count of greater than 1.

              */

-        pct = (shared_pages * 100)/totalram_pages;

-        fprintf(fp, "%13s  %7ld  %11s  %3ld%% of TOTAL MEM\n",

-                           "SHARED", shared_pages, pages_to_size(shared_pages, buf), pct);

+            if (shared_pages) {

+            pct = (shared_pages * 100)/totalram_pages;

+            fprintf(fp, "%13s  %7ld  %11s  %3ld%% of TOTAL MEM\n",

+                                         "SHARED", shared_pages, pages_to_size(shared_pages, buf), pct);

+            }

              subtract_buffer_pages = 0;

             if (symbol_exists("buffermem_pages")) {

@@ -8634,7 +8661,7 @@ dump_kmeminfo(void)

         fprintf(fp, "%13s  %7ld  %11s  %3ld%% of TOTAL MEM\n",

                             "BUFFERS", buffer_pages, pages_to_size(buffer_pages, buf), pct);

-             if (CRASHDEBUG(1))

+            if (CRASHDEBUG(1)&&(flags&GET_BUFFERS_PAGES))

              error(NOTE, "pages with buffers: %ld\n", get_buffers);

              /*

 

--
Crash-utility mailing list -- devel@xxxxxxxxxxxxxxxxxxxxxxxxxxx
To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxxxxxxxxxxxx
https://${domain_name}/admin/lists/devel.lists.crash-utility.osci.io/
Contribution Guidelines: https://github.com/crash-utility/crash/wiki

[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux