Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1356703 > unrolled thread

Re: [PATCHv3 09/13] scripts/gdb: Add meminfo command

Started byJan Kiszka <jan.kiszka@siemens.com>
First post2016-03-13 17:40 +0100
Last post2016-03-14 13:20 +0100
Articles 4 — 2 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: [PATCHv3 09/13] scripts/gdb: Add meminfo command Jan Kiszka <jan.kiszka@siemens.com> - 2016-03-13 17:40 +0100
    Re: [PATCHv3 09/13] scripts/gdb: Add meminfo command Kieran Bingham <kieran.bingham@linaro.org> - 2016-03-13 19:20 +0100
      Re: [PATCHv3 09/13] scripts/gdb: Add meminfo command Jan Kiszka <jan.kiszka@siemens.com> - 2016-03-13 20:10 +0100
        Re: [PATCHv3 09/13] scripts/gdb: Add meminfo command Kieran Bingham <kieran.bingham@linaro.org> - 2016-03-14 13:20 +0100

#1356703 — Re: [PATCHv3 09/13] scripts/gdb: Add meminfo command

FromJan Kiszka <jan.kiszka@siemens.com>
Date2016-03-13 17:40 +0100
SubjectRe: [PATCHv3 09/13] scripts/gdb: Add meminfo command
Message-ID<rchdE-8dH-15@gated-at.bofh.it>
On 2016-03-03 12:41, Kieran Bingham wrote:
> Provide an equivalent of /proc/meminfo which should be available from
> core dumps, or crashed kernels. This should allow a debugger to identify
> if memory pressures were applicable in the instance of their issue
> 

Sound useful.

> Signed-off-by: Kieran Bingham <kieran.bingham@linaro.org>
> 
> ---
> 
> Changes from v1:
>  - Updated to use LX_ macros for constants
>  - Utilise the LX_CONFIG() options for conditional printing
>  - Fixed meminfo command on Jan's target .config
>  - Added missing segments to meminfo command (HUGEPAGE, QUICKLIST)
>  - Adjusted for new list_for_each_entry() function
>  - Fixed up for !CONFIG_SWAP and !CONFIG_MMU targets (Tested STM32)
> 
> Changes from v2:
>  - Reduce line size on output lines causing pep8 warnings
>  - Remove crept in 'pass' statement
> ---
>  scripts/gdb/linux/constants.py.in |  34 ++++++
>  scripts/gdb/linux/proc.py         | 228 ++++++++++++++++++++++++++++++++++++++
>  2 files changed, 262 insertions(+)
> 
> diff --git a/scripts/gdb/linux/constants.py.in b/scripts/gdb/linux/constants.py.in
> index 57213ad8cf75..66562a8242bd 100644
> --- a/scripts/gdb/linux/constants.py.in
> +++ b/scripts/gdb/linux/constants.py.in
> @@ -12,8 +12,16 @@
>   *
>   */
>  
> +#include <asm/page.h>
> +#include <asm/pgtable.h>
> +#include <asm/thread_info.h>
> +
>  #include <linux/fs.h>
> +#include <linux/swap.h>
>  #include <linux/mount.h>
> +#include <linux/huge_mm.h>
> +#include <linux/vmalloc.h>
> +
>  
>  /* We need to stringify expanded macros so that they can be parsed */
>  
> @@ -51,3 +59,29 @@ LX_VALUE(MNT_NOATIME)
>  LX_VALUE(MNT_NODIRATIME)
>  LX_VALUE(MNT_RELATIME)
>  
> +/* asm/page.h */
> +LX_GDBPARSED(PAGE_SHIFT)
> +
> +/* asm/thread_info.h */
> +LX_GDBPARSED(THREAD_SIZE)
> +
> +/* linux/vmalloc.h */
> +LX_GDBPARSED(VMALLOC_TOTAL)
> +
> +/* linux/swap.h */
> +LX_GDBPARSED(MAX_SWAPFILES)
> +
> +
> +/* Kernel Configs */
> +LX_CONFIG(CONFIG_HIGHMEM)
> +LX_CONFIG(CONFIG_MEMORY_FAILURE)
> +LX_CONFIG(CONFIG_TRANSPARENT_HUGEPAGE)
> +LX_CONFIG(CONFIG_CMA)
> +LX_CONFIG(CONFIG_MMU)
> +LX_CONFIG(CONFIG_SWAP)
> +
> +#ifndef CONFIG_NR_QUICK
> +#define CONFIG_NR_QUICK 0
> +#endif
> +LX_VALUE(CONFIG_NR_QUICK)
> +LX_CONFIG(CONFIG_QUICKLIST)
> diff --git a/scripts/gdb/linux/proc.py b/scripts/gdb/linux/proc.py
> index 115f20b07a54..e5a8dbe3aa3a 100644
> --- a/scripts/gdb/linux/proc.py
> +++ b/scripts/gdb/linux/proc.py
> @@ -195,3 +195,231 @@ values of that process namespace"""
>                          info_opts(MNT_INFO, m_flags)))
>  
>  LxMounts()
> +
> +
> +bdev_type = utils.CachedType("struct block_device")
> +bdev_ptr_type = bdev_type.get_type().pointer()
> +
> +
> +class LxMeminfo(gdb.Command):
> +    """ Identify the memory usage, statistics, and availability
> +
> +Equivalent to cat /proc/meminfo on a running target """
> +
> +    def __init__(self):
> +        super(LxMeminfo, self).__init__("lx-meminfo", gdb.COMMAND_DATA)
> +
> +    def K(self, val):
> +        # Convert from PAGES to KB
> +        return int(val << (constants.LX_PAGE_SHIFT - 10))
> +
> +    def page_K(self, remote_value):
> +        # Obtain page value, and Convert from PAGES to KB
> +        val = int(gdb.parse_and_eval(remote_value))
> +        return self.K(val)
> +
> +    def gps(self, enum_zone_stat_item):
> +        # Access the Global Page State structure
> +        # I would prefer to read this structure in one go and then index
> +        # from the enum. But we can't determine the enum values with out
> +        # a call to GDB anyway so we may as well take the easy route and
> +        # get the value.
> +        remote_value = "vm_stat[" + enum_zone_stat_item + "].counter"
> +        return int(gdb.parse_and_eval(remote_value))
> +
> +    def gps_K(self, enum_zone_stat_item):
> +        return self.K(self.gps(enum_zone_stat_item))
> +
> +    def nr_blockdev_pages(self):
> +        bdevs_head = gdb.parse_and_eval("all_bdevs")
> +        pages = 0
> +        for bdev in lists.list_for_each_entry(bdevs_head,
> +                                              bdev_ptr_type,
> +                                              "bd_list"):
> +            try:
> +                pages += bdev['bd_inode']['i_mapping']['nrpages']
> +            except:
> +                # Any memory read failures are simply not counted
> +                pass
> +        return pages
> +
> +    def total_swapcache_pages(self):
> +        pages = 0
> +        if not constants.LX_CONFIG_SWAP:
> +            return 0
> +
> +        for i in range(0, int(constants.LX_MAX_SWAPFILES)):
> +            swap_space = "swapper_spaces[" + str(i) + "].nrpages"
> +            pages += int(gdb.parse_and_eval(swap_space))
> +        return pages
> +
> +    def vm_commit_limit(self, totalram_pages):
> +        total_swap_pages = 0
> +        overcommit = int(gdb.parse_and_eval("sysctl_overcommit_kbytes"))
> +        overcommit_ratio = int(gdb.parse_and_eval("sysctl_overcommit_ratio"))
> +
> +        if constants.LX_CONFIG_SWAP:
> +            total_swap_pages = int(gdb.parse_and_eval("total_swap_pages"))
> +
> +        hugetlb_total_pages = 0  # hugetlb_total_pages()
> +
> +        if overcommit:
> +            allowed = overcommit >> (constants.LX_PAGE_SHIFT - 10)
> +        else:
> +            allowed = ((totalram_pages - hugetlb_total_pages *
> +                       overcommit_ratio / 100))
> +
> +        allowed += total_swap_pages
> +        return allowed
> +
> +    def quicklist_total_size(self):
> +        count = 0
> +        quicklist = utils.gdb_eval_or_none("quicklist")
> +        if quicklist is None:
> +            return 0
> +
> +        for cpu in cpus.each_online_cpu():
> +            ql = cpus.per_cpu(quicklist, cpu)
> +            for q in range(0, constants.LX_CONFIG_NR_QUICK):
> +                # for (q = ql; q < ql + CONFIG_NR_QUICK; q++)
> +                # count += q->nr_pages
> +                count += ql[q]['nr_pages']
> +
> +        return count
> +
> +    # Main lx-meminfo command execution
> +    # See fs/proc/meminfo.c:meminfo_proc_show()
> +    def invoke(self, arg, from_tty):
> +        totalram = int(gdb.parse_and_eval("totalram_pages"))
> +        freeram = self.gps("NR_FREE_PAGES")
> +        reclaimable = self.gps("NR_SLAB_RECLAIMABLE")
> +        unreclaimable = self.gps("NR_SLAB_UNRECLAIMABLE")
> +        slab = reclaimable + unreclaimable
> +        # for_each_zone(zone)
> +        #     wmark_low += zone->watermark[WMARK_LOW];
> +        wmark_low = 0   # Zone parsing is unimplemented
> +
> +        available = freeram - wmark_low
> +        available += reclaimable - min(reclaimable / 2, wmark_low)
> +
> +        bufferram = self.nr_blockdev_pages()
> +        swapcached = self.total_swapcache_pages()
> +
> +        file_pages = self.gps("NR_FILE_PAGES")
> +        cached = file_pages - swapcached - bufferram
> +
> +        # LRU Pages
> +        active_pages_anon = self.gps("NR_ACTIVE_ANON")
> +        inactive_pages_anon = self.gps("NR_INACTIVE_ANON")
> +        active_pages_file = self.gps("NR_ACTIVE_FILE")
> +        inactive_pages_file = self.gps("NR_INACTIVE_FILE")
> +        unevictable_pages = self.gps("NR_UNEVICTABLE")
> +        active_pages = active_pages_anon + active_pages_file
> +        inactive_pages = inactive_pages_anon + inactive_pages_file
> +
> +        kernelstack = int(self.gps("NR_KERNEL_STACK") *
> +                          constants.LX_THREAD_SIZE / 1024)
> +
> +        commitlimit = int(self.vm_commit_limit(totalram))
> +        committed_as = int(gdb.parse_and_eval("vm_committed_as.count"))
> +
> +        vmalloc_total = int(constants.LX_VMALLOC_TOTAL >> 10)
> +
> +        gdb.write(
> +            "MemTotal:       {:8d} kB\n".format(self.K(totalram)) +
> +            "MemFree:        {:8d} kB\n".format(self.K(freeram)) +
> +            "MemAvailable:   {:8d} kB\n".format(self.K(available)) +
> +            "Buffers:        {:8d} kB\n".format(self.K(bufferram)) +
> +            "Cached:         {:8d} kB\n".format(self.K(cached)) +
> +            "SwapCached:     {:8d} kB\n".format(self.K(swapcached)) +
> +            "Active:         {:8d} kB\n".format(self.K(active_pages)) +
> +            "Inactive:       {:8d} kB\n".format(self.K(inactive_pages)) +
> +            "Active(anon):   {:8d} kB\n".format(self.K(active_pages_anon)) +
> +            "Inactive(anon): {:8d} kB\n".format(self.K(inactive_pages_anon)) +
> +            "Active(file):   {:8d} kB\n".format(self.K(active_pages_file)) +
> +            "Inactive(file): {:8d} kB\n".format(self.K(inactive_pages_file)) +
> +            "Unevictable:    {:8d} kB\n".format(self.K(unevictable_pages)) +
> +            "Mlocked:        {:8d} kB\n".format(self.gps_K("NR_MLOCK"))
> +            )
> +
> +        if constants.LX_CONFIG_HIGHMEM:
> +            totalhigh = int(gdb.parse_and_eval("totalhigh_pages"))
> +            freehigh = int(gdb.parse_and_eval("nr_free_highpages()"))
> +            lowtotal = totalram - totalhigh
> +            lowfree = freeram - freehigh
> +            gdb.write(
> +                "HighTotal:      {:8d} kB\n".format(self.K(totalhigh)) +
> +                "HighFree:       {:8d} kB\n".format(self.K(freehigh)) +
> +                "LowTotal:       {:8d} kB\n".format(self.K(lowtotal)) +
> +                "LowFree:        {:8d} kB\n".format(self.K(lowfree))
> +                )
> +
> +        if not constants.LX_CONFIG_MMU:
> +            mmap_pg_alloc = gdb.parse_and_eval("mmap_pages_allocated.counter")
> +            gdb.write(
> +                "MmapCopy:       {:8d} kB\n".format(self.K(mmap_pg_alloc))
> +                )
> +
> +        gdb.write(
> +            "SwapTotal:      {:8d} kB\n".format(self.K(0)) +
> +            "SwapFree:       {:8d} kB\n".format(self.K(0)) +
> +            "Dirty:          {:8d} kB\n".format(self.gps_K("NR_FILE_DIRTY")) +
> +            "Writeback:      {:8d} kB\n".format(self.gps_K("NR_WRITEBACK")) +
> +            "AnonPages:      {:8d} kB\n".format(self.gps_K("NR_ANON_PAGES")) +
> +            "Mapped:         {:8d} kB\n".format(self.gps_K("NR_FILE_MAPPED")) +
> +            "Shmem:          {:8d} kB\n".format(self.gps_K("NR_SHMEM")) +
> +            "Slab:           {:8d} kB\n".format(self.K(slab)) +
> +            "SReclaimable:   {:8d} kB\n".format(self.K(reclaimable)) +
> +            "SUnreclaim:     {:8d} kB\n".format(self.K(unreclaimable)) +
> +            "KernelStack:    {:8d} kB\n".format(kernelstack) +
> +            "PageTables:     {:8d} kB\n".format(self.gps_K("NR_PAGETABLE"))
> +            )
> +
> +        if constants.LX_CONFIG_QUICKLIST:
> +            quicklist = self.quicklist_total_size()
> +            gdb.write(
> +               "Quicklists:     {:8d} kB\n".format(self.K(quicklist))

scripts/gdb/linux/proc.py:381:16: E121 continuation line under-indented
for hanging indent

Please make sure to run pep8 on the series before posting.

Jan

-- 
Siemens AG, Corporate Technology, CT RDA ITP SES-DE
Corporate Competence Center Embedded Linux

[toc] | [next] | [standalone]


#1356713

FromKieran Bingham <kieran.bingham@linaro.org>
Date2016-03-13 19:20 +0100
Message-ID<rciMp-RT-5@gated-at.bofh.it>
In reply to#1356703
On 13/03/16 16:34, Jan Kiszka wrote:
> On 2016-03-03 12:41, Kieran Bingham wrote:
>> Provide an equivalent of /proc/meminfo which should be available from
>> core dumps, or crashed kernels. This should allow a debugger to identify
>> if memory pressures were applicable in the instance of their issue
>>
> 
> Sound useful.
> 
>> Signed-off-by: Kieran Bingham <kieran.bingham@linaro.org>
>>
>> ---
>>
>> Changes from v1:
>>  - Updated to use LX_ macros for constants
>>  - Utilise the LX_CONFIG() options for conditional printing
>>  - Fixed meminfo command on Jan's target .config
>>  - Added missing segments to meminfo command (HUGEPAGE, QUICKLIST)
>>  - Adjusted for new list_for_each_entry() function
>>  - Fixed up for !CONFIG_SWAP and !CONFIG_MMU targets (Tested STM32)
>>
>> Changes from v2:
>>  - Reduce line size on output lines causing pep8 warnings
>>  - Remove crept in 'pass' statement
>> ---
>>  scripts/gdb/linux/constants.py.in |  34 ++++++
>>  scripts/gdb/linux/proc.py         | 228 ++++++++++++++++++++++++++++++++++++++
>>  2 files changed, 262 insertions(+)
>>
>> diff --git a/scripts/gdb/linux/constants.py.in b/scripts/gdb/linux/constants.py.in
>> index 57213ad8cf75..66562a8242bd 100644
>> --- a/scripts/gdb/linux/constants.py.in
>> +++ b/scripts/gdb/linux/constants.py.in
>> @@ -12,8 +12,16 @@
>>   *
>>   */
>>  
>> +#include <asm/page.h>
>> +#include <asm/pgtable.h>
>> +#include <asm/thread_info.h>
>> +
>>  #include <linux/fs.h>
>> +#include <linux/swap.h>
>>  #include <linux/mount.h>
>> +#include <linux/huge_mm.h>
>> +#include <linux/vmalloc.h>
>> +
>>  
>>  /* We need to stringify expanded macros so that they can be parsed */
>>  
>> @@ -51,3 +59,29 @@ LX_VALUE(MNT_NOATIME)
>>  LX_VALUE(MNT_NODIRATIME)
>>  LX_VALUE(MNT_RELATIME)
>>  
>> +/* asm/page.h */
>> +LX_GDBPARSED(PAGE_SHIFT)
>> +
>> +/* asm/thread_info.h */
>> +LX_GDBPARSED(THREAD_SIZE)
>> +
>> +/* linux/vmalloc.h */
>> +LX_GDBPARSED(VMALLOC_TOTAL)
>> +
>> +/* linux/swap.h */
>> +LX_GDBPARSED(MAX_SWAPFILES)
>> +
>> +
>> +/* Kernel Configs */
>> +LX_CONFIG(CONFIG_HIGHMEM)
>> +LX_CONFIG(CONFIG_MEMORY_FAILURE)
>> +LX_CONFIG(CONFIG_TRANSPARENT_HUGEPAGE)
>> +LX_CONFIG(CONFIG_CMA)
>> +LX_CONFIG(CONFIG_MMU)
>> +LX_CONFIG(CONFIG_SWAP)
>> +
>> +#ifndef CONFIG_NR_QUICK
>> +#define CONFIG_NR_QUICK 0
>> +#endif
>> +LX_VALUE(CONFIG_NR_QUICK)
>> +LX_CONFIG(CONFIG_QUICKLIST)
>> diff --git a/scripts/gdb/linux/proc.py b/scripts/gdb/linux/proc.py
>> index 115f20b07a54..e5a8dbe3aa3a 100644
>> --- a/scripts/gdb/linux/proc.py
>> +++ b/scripts/gdb/linux/proc.py
>> @@ -195,3 +195,231 @@ values of that process namespace"""
>>                          info_opts(MNT_INFO, m_flags)))
>>  
>>  LxMounts()
>> +
>> +
>> +bdev_type = utils.CachedType("struct block_device")
>> +bdev_ptr_type = bdev_type.get_type().pointer()
>> +
>> +
>> +class LxMeminfo(gdb.Command):
>> +    """ Identify the memory usage, statistics, and availability
>> +
>> +Equivalent to cat /proc/meminfo on a running target """
>> +
>> +    def __init__(self):
>> +        super(LxMeminfo, self).__init__("lx-meminfo", gdb.COMMAND_DATA)
>> +
>> +    def K(self, val):
>> +        # Convert from PAGES to KB
>> +        return int(val << (constants.LX_PAGE_SHIFT - 10))
>> +
>> +    def page_K(self, remote_value):
>> +        # Obtain page value, and Convert from PAGES to KB
>> +        val = int(gdb.parse_and_eval(remote_value))
>> +        return self.K(val)
>> +
>> +    def gps(self, enum_zone_stat_item):
>> +        # Access the Global Page State structure
>> +        # I would prefer to read this structure in one go and then index
>> +        # from the enum. But we can't determine the enum values with out
>> +        # a call to GDB anyway so we may as well take the easy route and
>> +        # get the value.
>> +        remote_value = "vm_stat[" + enum_zone_stat_item + "].counter"
>> +        return int(gdb.parse_and_eval(remote_value))
>> +
>> +    def gps_K(self, enum_zone_stat_item):
>> +        return self.K(self.gps(enum_zone_stat_item))
>> +
>> +    def nr_blockdev_pages(self):
>> +        bdevs_head = gdb.parse_and_eval("all_bdevs")
>> +        pages = 0
>> +        for bdev in lists.list_for_each_entry(bdevs_head,
>> +                                              bdev_ptr_type,
>> +                                              "bd_list"):
>> +            try:
>> +                pages += bdev['bd_inode']['i_mapping']['nrpages']
>> +            except:
>> +                # Any memory read failures are simply not counted
>> +                pass
>> +        return pages
>> +
>> +    def total_swapcache_pages(self):
>> +        pages = 0
>> +        if not constants.LX_CONFIG_SWAP:
>> +            return 0
>> +
>> +        for i in range(0, int(constants.LX_MAX_SWAPFILES)):
>> +            swap_space = "swapper_spaces[" + str(i) + "].nrpages"
>> +            pages += int(gdb.parse_and_eval(swap_space))
>> +        return pages
>> +
>> +    def vm_commit_limit(self, totalram_pages):
>> +        total_swap_pages = 0
>> +        overcommit = int(gdb.parse_and_eval("sysctl_overcommit_kbytes"))
>> +        overcommit_ratio = int(gdb.parse_and_eval("sysctl_overcommit_ratio"))
>> +
>> +        if constants.LX_CONFIG_SWAP:
>> +            total_swap_pages = int(gdb.parse_and_eval("total_swap_pages"))
>> +
>> +        hugetlb_total_pages = 0  # hugetlb_total_pages()
>> +
>> +        if overcommit:
>> +            allowed = overcommit >> (constants.LX_PAGE_SHIFT - 10)
>> +        else:
>> +            allowed = ((totalram_pages - hugetlb_total_pages *
>> +                       overcommit_ratio / 100))
>> +
>> +        allowed += total_swap_pages
>> +        return allowed
>> +
>> +    def quicklist_total_size(self):
>> +        count = 0
>> +        quicklist = utils.gdb_eval_or_none("quicklist")
>> +        if quicklist is None:
>> +            return 0
>> +
>> +        for cpu in cpus.each_online_cpu():
>> +            ql = cpus.per_cpu(quicklist, cpu)
>> +            for q in range(0, constants.LX_CONFIG_NR_QUICK):
>> +                # for (q = ql; q < ql + CONFIG_NR_QUICK; q++)
>> +                # count += q->nr_pages
>> +                count += ql[q]['nr_pages']
>> +
>> +        return count
>> +
>> +    # Main lx-meminfo command execution
>> +    # See fs/proc/meminfo.c:meminfo_proc_show()
>> +    def invoke(self, arg, from_tty):
>> +        totalram = int(gdb.parse_and_eval("totalram_pages"))
>> +        freeram = self.gps("NR_FREE_PAGES")
>> +        reclaimable = self.gps("NR_SLAB_RECLAIMABLE")
>> +        unreclaimable = self.gps("NR_SLAB_UNRECLAIMABLE")
>> +        slab = reclaimable + unreclaimable
>> +        # for_each_zone(zone)
>> +        #     wmark_low += zone->watermark[WMARK_LOW];
>> +        wmark_low = 0   # Zone parsing is unimplemented
>> +
>> +        available = freeram - wmark_low
>> +        available += reclaimable - min(reclaimable / 2, wmark_low)
>> +
>> +        bufferram = self.nr_blockdev_pages()
>> +        swapcached = self.total_swapcache_pages()
>> +
>> +        file_pages = self.gps("NR_FILE_PAGES")
>> +        cached = file_pages - swapcached - bufferram
>> +
>> +        # LRU Pages
>> +        active_pages_anon = self.gps("NR_ACTIVE_ANON")
>> +        inactive_pages_anon = self.gps("NR_INACTIVE_ANON")
>> +        active_pages_file = self.gps("NR_ACTIVE_FILE")
>> +        inactive_pages_file = self.gps("NR_INACTIVE_FILE")
>> +        unevictable_pages = self.gps("NR_UNEVICTABLE")
>> +        active_pages = active_pages_anon + active_pages_file
>> +        inactive_pages = inactive_pages_anon + inactive_pages_file
>> +
>> +        kernelstack = int(self.gps("NR_KERNEL_STACK") *
>> +                          constants.LX_THREAD_SIZE / 1024)
>> +
>> +        commitlimit = int(self.vm_commit_limit(totalram))
>> +        committed_as = int(gdb.parse_and_eval("vm_committed_as.count"))
>> +
>> +        vmalloc_total = int(constants.LX_VMALLOC_TOTAL >> 10)
>> +
>> +        gdb.write(
>> +            "MemTotal:       {:8d} kB\n".format(self.K(totalram)) +
>> +            "MemFree:        {:8d} kB\n".format(self.K(freeram)) +
>> +            "MemAvailable:   {:8d} kB\n".format(self.K(available)) +
>> +            "Buffers:        {:8d} kB\n".format(self.K(bufferram)) +
>> +            "Cached:         {:8d} kB\n".format(self.K(cached)) +
>> +            "SwapCached:     {:8d} kB\n".format(self.K(swapcached)) +
>> +            "Active:         {:8d} kB\n".format(self.K(active_pages)) +
>> +            "Inactive:       {:8d} kB\n".format(self.K(inactive_pages)) +
>> +            "Active(anon):   {:8d} kB\n".format(self.K(active_pages_anon)) +
>> +            "Inactive(anon): {:8d} kB\n".format(self.K(inactive_pages_anon)) +
>> +            "Active(file):   {:8d} kB\n".format(self.K(active_pages_file)) +
>> +            "Inactive(file): {:8d} kB\n".format(self.K(inactive_pages_file)) +
>> +            "Unevictable:    {:8d} kB\n".format(self.K(unevictable_pages)) +
>> +            "Mlocked:        {:8d} kB\n".format(self.gps_K("NR_MLOCK"))
>> +            )
>> +
>> +        if constants.LX_CONFIG_HIGHMEM:
>> +            totalhigh = int(gdb.parse_and_eval("totalhigh_pages"))
>> +            freehigh = int(gdb.parse_and_eval("nr_free_highpages()"))
>> +            lowtotal = totalram - totalhigh
>> +            lowfree = freeram - freehigh
>> +            gdb.write(
>> +                "HighTotal:      {:8d} kB\n".format(self.K(totalhigh)) +
>> +                "HighFree:       {:8d} kB\n".format(self.K(freehigh)) +
>> +                "LowTotal:       {:8d} kB\n".format(self.K(lowtotal)) +
>> +                "LowFree:        {:8d} kB\n".format(self.K(lowfree))
>> +                )
>> +
>> +        if not constants.LX_CONFIG_MMU:
>> +            mmap_pg_alloc = gdb.parse_and_eval("mmap_pages_allocated.counter")
>> +            gdb.write(
>> +                "MmapCopy:       {:8d} kB\n".format(self.K(mmap_pg_alloc))
>> +                )
>> +
>> +        gdb.write(
>> +            "SwapTotal:      {:8d} kB\n".format(self.K(0)) +
>> +            "SwapFree:       {:8d} kB\n".format(self.K(0)) +
>> +            "Dirty:          {:8d} kB\n".format(self.gps_K("NR_FILE_DIRTY")) +
>> +            "Writeback:      {:8d} kB\n".format(self.gps_K("NR_WRITEBACK")) +
>> +            "AnonPages:      {:8d} kB\n".format(self.gps_K("NR_ANON_PAGES")) +
>> +            "Mapped:         {:8d} kB\n".format(self.gps_K("NR_FILE_MAPPED")) +
>> +            "Shmem:          {:8d} kB\n".format(self.gps_K("NR_SHMEM")) +
>> +            "Slab:           {:8d} kB\n".format(self.K(slab)) +
>> +            "SReclaimable:   {:8d} kB\n".format(self.K(reclaimable)) +
>> +            "SUnreclaim:     {:8d} kB\n".format(self.K(unreclaimable)) +
>> +            "KernelStack:    {:8d} kB\n".format(kernelstack) +
>> +            "PageTables:     {:8d} kB\n".format(self.gps_K("NR_PAGETABLE"))
>> +            )
>> +
>> +        if constants.LX_CONFIG_QUICKLIST:
>> +            quicklist = self.quicklist_total_size()
>> +            gdb.write(
>> +               "Quicklists:     {:8d} kB\n".format(self.K(quicklist))
> 
> scripts/gdb/linux/proc.py:381:16: E121 continuation line under-indented
> for hanging indent
> 
> Please make sure to run pep8 on the series before posting.

My apologies for the error, but on my laptop pep8 runs clean?

What version are you running?
I have the following:

$ pep8 --version
1.6.2

Perhaps I need to update something here.

Kieran

[toc] | [prev] | [next] | [standalone]


#1356718

FromJan Kiszka <jan.kiszka@siemens.com>
Date2016-03-13 20:10 +0100
Message-ID<rcjyN-1pI-5@gated-at.bofh.it>
In reply to#1356713
On 2016-03-13 19:16, Kieran Bingham wrote:
> On 13/03/16 16:34, Jan Kiszka wrote:
>> On 2016-03-03 12:41, Kieran Bingham wrote:
>>> Provide an equivalent of /proc/meminfo which should be available from
>>> core dumps, or crashed kernels. This should allow a debugger to identify
>>> if memory pressures were applicable in the instance of their issue
>>>
>>
>> Sound useful.
>>
>>> Signed-off-by: Kieran Bingham <kieran.bingham@linaro.org>
>>>
>>> ---
>>>
>>> Changes from v1:
>>>  - Updated to use LX_ macros for constants
>>>  - Utilise the LX_CONFIG() options for conditional printing
>>>  - Fixed meminfo command on Jan's target .config
>>>  - Added missing segments to meminfo command (HUGEPAGE, QUICKLIST)
>>>  - Adjusted for new list_for_each_entry() function
>>>  - Fixed up for !CONFIG_SWAP and !CONFIG_MMU targets (Tested STM32)
>>>
>>> Changes from v2:
>>>  - Reduce line size on output lines causing pep8 warnings
>>>  - Remove crept in 'pass' statement
>>> ---
>>>  scripts/gdb/linux/constants.py.in |  34 ++++++
>>>  scripts/gdb/linux/proc.py         | 228 ++++++++++++++++++++++++++++++++++++++
>>>  2 files changed, 262 insertions(+)
>>>
>>> diff --git a/scripts/gdb/linux/constants.py.in b/scripts/gdb/linux/constants.py.in
>>> index 57213ad8cf75..66562a8242bd 100644
>>> --- a/scripts/gdb/linux/constants.py.in
>>> +++ b/scripts/gdb/linux/constants.py.in
>>> @@ -12,8 +12,16 @@
>>>   *
>>>   */
>>>  
>>> +#include <asm/page.h>
>>> +#include <asm/pgtable.h>
>>> +#include <asm/thread_info.h>
>>> +
>>>  #include <linux/fs.h>
>>> +#include <linux/swap.h>
>>>  #include <linux/mount.h>
>>> +#include <linux/huge_mm.h>
>>> +#include <linux/vmalloc.h>
>>> +
>>>  
>>>  /* We need to stringify expanded macros so that they can be parsed */
>>>  
>>> @@ -51,3 +59,29 @@ LX_VALUE(MNT_NOATIME)
>>>  LX_VALUE(MNT_NODIRATIME)
>>>  LX_VALUE(MNT_RELATIME)
>>>  
>>> +/* asm/page.h */
>>> +LX_GDBPARSED(PAGE_SHIFT)
>>> +
>>> +/* asm/thread_info.h */
>>> +LX_GDBPARSED(THREAD_SIZE)
>>> +
>>> +/* linux/vmalloc.h */
>>> +LX_GDBPARSED(VMALLOC_TOTAL)
>>> +
>>> +/* linux/swap.h */
>>> +LX_GDBPARSED(MAX_SWAPFILES)
>>> +
>>> +
>>> +/* Kernel Configs */
>>> +LX_CONFIG(CONFIG_HIGHMEM)
>>> +LX_CONFIG(CONFIG_MEMORY_FAILURE)
>>> +LX_CONFIG(CONFIG_TRANSPARENT_HUGEPAGE)
>>> +LX_CONFIG(CONFIG_CMA)
>>> +LX_CONFIG(CONFIG_MMU)
>>> +LX_CONFIG(CONFIG_SWAP)
>>> +
>>> +#ifndef CONFIG_NR_QUICK
>>> +#define CONFIG_NR_QUICK 0
>>> +#endif
>>> +LX_VALUE(CONFIG_NR_QUICK)
>>> +LX_CONFIG(CONFIG_QUICKLIST)
>>> diff --git a/scripts/gdb/linux/proc.py b/scripts/gdb/linux/proc.py
>>> index 115f20b07a54..e5a8dbe3aa3a 100644
>>> --- a/scripts/gdb/linux/proc.py
>>> +++ b/scripts/gdb/linux/proc.py
>>> @@ -195,3 +195,231 @@ values of that process namespace"""
>>>                          info_opts(MNT_INFO, m_flags)))
>>>  
>>>  LxMounts()
>>> +
>>> +
>>> +bdev_type = utils.CachedType("struct block_device")
>>> +bdev_ptr_type = bdev_type.get_type().pointer()
>>> +
>>> +
>>> +class LxMeminfo(gdb.Command):
>>> +    """ Identify the memory usage, statistics, and availability
>>> +
>>> +Equivalent to cat /proc/meminfo on a running target """
>>> +
>>> +    def __init__(self):
>>> +        super(LxMeminfo, self).__init__("lx-meminfo", gdb.COMMAND_DATA)
>>> +
>>> +    def K(self, val):
>>> +        # Convert from PAGES to KB
>>> +        return int(val << (constants.LX_PAGE_SHIFT - 10))
>>> +
>>> +    def page_K(self, remote_value):
>>> +        # Obtain page value, and Convert from PAGES to KB
>>> +        val = int(gdb.parse_and_eval(remote_value))
>>> +        return self.K(val)
>>> +
>>> +    def gps(self, enum_zone_stat_item):
>>> +        # Access the Global Page State structure
>>> +        # I would prefer to read this structure in one go and then index
>>> +        # from the enum. But we can't determine the enum values with out
>>> +        # a call to GDB anyway so we may as well take the easy route and
>>> +        # get the value.
>>> +        remote_value = "vm_stat[" + enum_zone_stat_item + "].counter"
>>> +        return int(gdb.parse_and_eval(remote_value))
>>> +
>>> +    def gps_K(self, enum_zone_stat_item):
>>> +        return self.K(self.gps(enum_zone_stat_item))
>>> +
>>> +    def nr_blockdev_pages(self):
>>> +        bdevs_head = gdb.parse_and_eval("all_bdevs")
>>> +        pages = 0
>>> +        for bdev in lists.list_for_each_entry(bdevs_head,
>>> +                                              bdev_ptr_type,
>>> +                                              "bd_list"):
>>> +            try:
>>> +                pages += bdev['bd_inode']['i_mapping']['nrpages']
>>> +            except:
>>> +                # Any memory read failures are simply not counted
>>> +                pass
>>> +        return pages
>>> +
>>> +    def total_swapcache_pages(self):
>>> +        pages = 0
>>> +        if not constants.LX_CONFIG_SWAP:
>>> +            return 0
>>> +
>>> +        for i in range(0, int(constants.LX_MAX_SWAPFILES)):
>>> +            swap_space = "swapper_spaces[" + str(i) + "].nrpages"
>>> +            pages += int(gdb.parse_and_eval(swap_space))
>>> +        return pages
>>> +
>>> +    def vm_commit_limit(self, totalram_pages):
>>> +        total_swap_pages = 0
>>> +        overcommit = int(gdb.parse_and_eval("sysctl_overcommit_kbytes"))
>>> +        overcommit_ratio = int(gdb.parse_and_eval("sysctl_overcommit_ratio"))
>>> +
>>> +        if constants.LX_CONFIG_SWAP:
>>> +            total_swap_pages = int(gdb.parse_and_eval("total_swap_pages"))
>>> +
>>> +        hugetlb_total_pages = 0  # hugetlb_total_pages()
>>> +
>>> +        if overcommit:
>>> +            allowed = overcommit >> (constants.LX_PAGE_SHIFT - 10)
>>> +        else:
>>> +            allowed = ((totalram_pages - hugetlb_total_pages *
>>> +                       overcommit_ratio / 100))
>>> +
>>> +        allowed += total_swap_pages
>>> +        return allowed
>>> +
>>> +    def quicklist_total_size(self):
>>> +        count = 0
>>> +        quicklist = utils.gdb_eval_or_none("quicklist")
>>> +        if quicklist is None:
>>> +            return 0
>>> +
>>> +        for cpu in cpus.each_online_cpu():
>>> +            ql = cpus.per_cpu(quicklist, cpu)
>>> +            for q in range(0, constants.LX_CONFIG_NR_QUICK):
>>> +                # for (q = ql; q < ql + CONFIG_NR_QUICK; q++)
>>> +                # count += q->nr_pages
>>> +                count += ql[q]['nr_pages']
>>> +
>>> +        return count
>>> +
>>> +    # Main lx-meminfo command execution
>>> +    # See fs/proc/meminfo.c:meminfo_proc_show()
>>> +    def invoke(self, arg, from_tty):
>>> +        totalram = int(gdb.parse_and_eval("totalram_pages"))
>>> +        freeram = self.gps("NR_FREE_PAGES")
>>> +        reclaimable = self.gps("NR_SLAB_RECLAIMABLE")
>>> +        unreclaimable = self.gps("NR_SLAB_UNRECLAIMABLE")
>>> +        slab = reclaimable + unreclaimable
>>> +        # for_each_zone(zone)
>>> +        #     wmark_low += zone->watermark[WMARK_LOW];
>>> +        wmark_low = 0   # Zone parsing is unimplemented
>>> +
>>> +        available = freeram - wmark_low
>>> +        available += reclaimable - min(reclaimable / 2, wmark_low)
>>> +
>>> +        bufferram = self.nr_blockdev_pages()
>>> +        swapcached = self.total_swapcache_pages()
>>> +
>>> +        file_pages = self.gps("NR_FILE_PAGES")
>>> +        cached = file_pages - swapcached - bufferram
>>> +
>>> +        # LRU Pages
>>> +        active_pages_anon = self.gps("NR_ACTIVE_ANON")
>>> +        inactive_pages_anon = self.gps("NR_INACTIVE_ANON")
>>> +        active_pages_file = self.gps("NR_ACTIVE_FILE")
>>> +        inactive_pages_file = self.gps("NR_INACTIVE_FILE")
>>> +        unevictable_pages = self.gps("NR_UNEVICTABLE")
>>> +        active_pages = active_pages_anon + active_pages_file
>>> +        inactive_pages = inactive_pages_anon + inactive_pages_file
>>> +
>>> +        kernelstack = int(self.gps("NR_KERNEL_STACK") *
>>> +                          constants.LX_THREAD_SIZE / 1024)
>>> +
>>> +        commitlimit = int(self.vm_commit_limit(totalram))
>>> +        committed_as = int(gdb.parse_and_eval("vm_committed_as.count"))
>>> +
>>> +        vmalloc_total = int(constants.LX_VMALLOC_TOTAL >> 10)
>>> +
>>> +        gdb.write(
>>> +            "MemTotal:       {:8d} kB\n".format(self.K(totalram)) +
>>> +            "MemFree:        {:8d} kB\n".format(self.K(freeram)) +
>>> +            "MemAvailable:   {:8d} kB\n".format(self.K(available)) +
>>> +            "Buffers:        {:8d} kB\n".format(self.K(bufferram)) +
>>> +            "Cached:         {:8d} kB\n".format(self.K(cached)) +
>>> +            "SwapCached:     {:8d} kB\n".format(self.K(swapcached)) +
>>> +            "Active:         {:8d} kB\n".format(self.K(active_pages)) +
>>> +            "Inactive:       {:8d} kB\n".format(self.K(inactive_pages)) +
>>> +            "Active(anon):   {:8d} kB\n".format(self.K(active_pages_anon)) +
>>> +            "Inactive(anon): {:8d} kB\n".format(self.K(inactive_pages_anon)) +
>>> +            "Active(file):   {:8d} kB\n".format(self.K(active_pages_file)) +
>>> +            "Inactive(file): {:8d} kB\n".format(self.K(inactive_pages_file)) +
>>> +            "Unevictable:    {:8d} kB\n".format(self.K(unevictable_pages)) +
>>> +            "Mlocked:        {:8d} kB\n".format(self.gps_K("NR_MLOCK"))
>>> +            )
>>> +
>>> +        if constants.LX_CONFIG_HIGHMEM:
>>> +            totalhigh = int(gdb.parse_and_eval("totalhigh_pages"))
>>> +            freehigh = int(gdb.parse_and_eval("nr_free_highpages()"))
>>> +            lowtotal = totalram - totalhigh
>>> +            lowfree = freeram - freehigh
>>> +            gdb.write(
>>> +                "HighTotal:      {:8d} kB\n".format(self.K(totalhigh)) +
>>> +                "HighFree:       {:8d} kB\n".format(self.K(freehigh)) +
>>> +                "LowTotal:       {:8d} kB\n".format(self.K(lowtotal)) +
>>> +                "LowFree:        {:8d} kB\n".format(self.K(lowfree))
>>> +                )
>>> +
>>> +        if not constants.LX_CONFIG_MMU:
>>> +            mmap_pg_alloc = gdb.parse_and_eval("mmap_pages_allocated.counter")
>>> +            gdb.write(
>>> +                "MmapCopy:       {:8d} kB\n".format(self.K(mmap_pg_alloc))
>>> +                )
>>> +
>>> +        gdb.write(
>>> +            "SwapTotal:      {:8d} kB\n".format(self.K(0)) +
>>> +            "SwapFree:       {:8d} kB\n".format(self.K(0)) +
>>> +            "Dirty:          {:8d} kB\n".format(self.gps_K("NR_FILE_DIRTY")) +
>>> +            "Writeback:      {:8d} kB\n".format(self.gps_K("NR_WRITEBACK")) +
>>> +            "AnonPages:      {:8d} kB\n".format(self.gps_K("NR_ANON_PAGES")) +
>>> +            "Mapped:         {:8d} kB\n".format(self.gps_K("NR_FILE_MAPPED")) +
>>> +            "Shmem:          {:8d} kB\n".format(self.gps_K("NR_SHMEM")) +
>>> +            "Slab:           {:8d} kB\n".format(self.K(slab)) +
>>> +            "SReclaimable:   {:8d} kB\n".format(self.K(reclaimable)) +
>>> +            "SUnreclaim:     {:8d} kB\n".format(self.K(unreclaimable)) +
>>> +            "KernelStack:    {:8d} kB\n".format(kernelstack) +
>>> +            "PageTables:     {:8d} kB\n".format(self.gps_K("NR_PAGETABLE"))
>>> +            )
>>> +
>>> +        if constants.LX_CONFIG_QUICKLIST:
>>> +            quicklist = self.quicklist_total_size()
>>> +            gdb.write(
>>> +               "Quicklists:     {:8d} kB\n".format(self.K(quicklist))
>>
>> scripts/gdb/linux/proc.py:381:16: E121 continuation line under-indented
>> for hanging indent
>>
>> Please make sure to run pep8 on the series before posting.
> 
> My apologies for the error, but on my laptop pep8 runs clean?
> 
> What version are you running?
> I have the following:
> 
> $ pep8 --version
> 1.6.2

Hmm, 1.5.7 here - pep8 regression?

The problem above is simply a missing space (4 required, instead of 3).

Jan

-- 
Siemens AG, Corporate Technology, CT RDA ITP SES-DE
Corporate Competence Center Embedded Linux

[toc] | [prev] | [next] | [standalone]


#1357195

FromKieran Bingham <kieran.bingham@linaro.org>
Date2016-03-14 13:20 +0100
Message-ID<rczDz-3BO-5@gated-at.bofh.it>
In reply to#1356718

On 13/03/16 19:08, Jan Kiszka wrote:
> On 2016-03-13 19:16, Kieran Bingham wrote:
>> On 13/03/16 16:34, Jan Kiszka wrote:
>>> On 2016-03-03 12:41, Kieran Bingham wrote:
>>>> Provide an equivalent of /proc/meminfo which should be available from
>>>> core dumps, or crashed kernels. This should allow a debugger to identify
>>>> if memory pressures were applicable in the instance of their issue
>>>>
>>>
>>> Sound useful.
>>>
>>>> Signed-off-by: Kieran Bingham <kieran.bingham@linaro.org>
>>>>
>>>> ---
>>>>
>>>> Changes from v1:
>>>>  - Updated to use LX_ macros for constants
>>>>  - Utilise the LX_CONFIG() options for conditional printing
>>>>  - Fixed meminfo command on Jan's target .config
>>>>  - Added missing segments to meminfo command (HUGEPAGE, QUICKLIST)
>>>>  - Adjusted for new list_for_each_entry() function
>>>>  - Fixed up for !CONFIG_SWAP and !CONFIG_MMU targets (Tested STM32)
>>>>
>>>> Changes from v2:
>>>>  - Reduce line size on output lines causing pep8 warnings
>>>>  - Remove crept in 'pass' statement
>>>> ---
>>>>  scripts/gdb/linux/constants.py.in |  34 ++++++
>>>>  scripts/gdb/linux/proc.py         | 228 ++++++++++++++++++++++++++++++++++++++
>>>>  2 files changed, 262 insertions(+)
>>>>
>>>> diff --git a/scripts/gdb/linux/constants.py.in b/scripts/gdb/linux/constants.py.in
>>>> index 57213ad8cf75..66562a8242bd 100644
>>>> --- a/scripts/gdb/linux/constants.py.in
>>>> +++ b/scripts/gdb/linux/constants.py.in
>>>> @@ -12,8 +12,16 @@
>>>>   *
>>>>   */
>>>>  
>>>> +#include <asm/page.h>
>>>> +#include <asm/pgtable.h>
>>>> +#include <asm/thread_info.h>
>>>> +
>>>>  #include <linux/fs.h>
>>>> +#include <linux/swap.h>
>>>>  #include <linux/mount.h>
>>>> +#include <linux/huge_mm.h>
>>>> +#include <linux/vmalloc.h>
>>>> +
>>>>  
>>>>  /* We need to stringify expanded macros so that they can be parsed */
>>>>  
>>>> @@ -51,3 +59,29 @@ LX_VALUE(MNT_NOATIME)
>>>>  LX_VALUE(MNT_NODIRATIME)
>>>>  LX_VALUE(MNT_RELATIME)
>>>>  
>>>> +/* asm/page.h */
>>>> +LX_GDBPARSED(PAGE_SHIFT)
>>>> +
>>>> +/* asm/thread_info.h */
>>>> +LX_GDBPARSED(THREAD_SIZE)
>>>> +
>>>> +/* linux/vmalloc.h */
>>>> +LX_GDBPARSED(VMALLOC_TOTAL)
>>>> +
>>>> +/* linux/swap.h */
>>>> +LX_GDBPARSED(MAX_SWAPFILES)
>>>> +
>>>> +
>>>> +/* Kernel Configs */
>>>> +LX_CONFIG(CONFIG_HIGHMEM)
>>>> +LX_CONFIG(CONFIG_MEMORY_FAILURE)
>>>> +LX_CONFIG(CONFIG_TRANSPARENT_HUGEPAGE)
>>>> +LX_CONFIG(CONFIG_CMA)
>>>> +LX_CONFIG(CONFIG_MMU)
>>>> +LX_CONFIG(CONFIG_SWAP)
>>>> +
>>>> +#ifndef CONFIG_NR_QUICK
>>>> +#define CONFIG_NR_QUICK 0
>>>> +#endif
>>>> +LX_VALUE(CONFIG_NR_QUICK)
>>>> +LX_CONFIG(CONFIG_QUICKLIST)
>>>> diff --git a/scripts/gdb/linux/proc.py b/scripts/gdb/linux/proc.py
>>>> index 115f20b07a54..e5a8dbe3aa3a 100644
>>>> --- a/scripts/gdb/linux/proc.py
>>>> +++ b/scripts/gdb/linux/proc.py
>>>> @@ -195,3 +195,231 @@ values of that process namespace"""
>>>>                          info_opts(MNT_INFO, m_flags)))
>>>>  
>>>>  LxMounts()
>>>> +
>>>> +
>>>> +bdev_type = utils.CachedType("struct block_device")
>>>> +bdev_ptr_type = bdev_type.get_type().pointer()
>>>> +
>>>> +
>>>> +class LxMeminfo(gdb.Command):
>>>> +    """ Identify the memory usage, statistics, and availability
>>>> +
>>>> +Equivalent to cat /proc/meminfo on a running target """
>>>> +
>>>> +    def __init__(self):
>>>> +        super(LxMeminfo, self).__init__("lx-meminfo", gdb.COMMAND_DATA)
>>>> +
>>>> +    def K(self, val):
>>>> +        # Convert from PAGES to KB
>>>> +        return int(val << (constants.LX_PAGE_SHIFT - 10))
>>>> +
>>>> +    def page_K(self, remote_value):
>>>> +        # Obtain page value, and Convert from PAGES to KB
>>>> +        val = int(gdb.parse_and_eval(remote_value))
>>>> +        return self.K(val)
>>>> +
>>>> +    def gps(self, enum_zone_stat_item):
>>>> +        # Access the Global Page State structure
>>>> +        # I would prefer to read this structure in one go and then index
>>>> +        # from the enum. But we can't determine the enum values with out
>>>> +        # a call to GDB anyway so we may as well take the easy route and
>>>> +        # get the value.
>>>> +        remote_value = "vm_stat[" + enum_zone_stat_item + "].counter"
>>>> +        return int(gdb.parse_and_eval(remote_value))
>>>> +
>>>> +    def gps_K(self, enum_zone_stat_item):
>>>> +        return self.K(self.gps(enum_zone_stat_item))
>>>> +
>>>> +    def nr_blockdev_pages(self):
>>>> +        bdevs_head = gdb.parse_and_eval("all_bdevs")
>>>> +        pages = 0
>>>> +        for bdev in lists.list_for_each_entry(bdevs_head,
>>>> +                                              bdev_ptr_type,
>>>> +                                              "bd_list"):
>>>> +            try:
>>>> +                pages += bdev['bd_inode']['i_mapping']['nrpages']
>>>> +            except:
>>>> +                # Any memory read failures are simply not counted
>>>> +                pass
>>>> +        return pages
>>>> +
>>>> +    def total_swapcache_pages(self):
>>>> +        pages = 0
>>>> +        if not constants.LX_CONFIG_SWAP:
>>>> +            return 0
>>>> +
>>>> +        for i in range(0, int(constants.LX_MAX_SWAPFILES)):
>>>> +            swap_space = "swapper_spaces[" + str(i) + "].nrpages"
>>>> +            pages += int(gdb.parse_and_eval(swap_space))
>>>> +        return pages
>>>> +
>>>> +    def vm_commit_limit(self, totalram_pages):
>>>> +        total_swap_pages = 0
>>>> +        overcommit = int(gdb.parse_and_eval("sysctl_overcommit_kbytes"))
>>>> +        overcommit_ratio = int(gdb.parse_and_eval("sysctl_overcommit_ratio"))
>>>> +
>>>> +        if constants.LX_CONFIG_SWAP:
>>>> +            total_swap_pages = int(gdb.parse_and_eval("total_swap_pages"))
>>>> +
>>>> +        hugetlb_total_pages = 0  # hugetlb_total_pages()
>>>> +
>>>> +        if overcommit:
>>>> +            allowed = overcommit >> (constants.LX_PAGE_SHIFT - 10)
>>>> +        else:
>>>> +            allowed = ((totalram_pages - hugetlb_total_pages *
>>>> +                       overcommit_ratio / 100))
>>>> +
>>>> +        allowed += total_swap_pages
>>>> +        return allowed
>>>> +
>>>> +    def quicklist_total_size(self):
>>>> +        count = 0
>>>> +        quicklist = utils.gdb_eval_or_none("quicklist")
>>>> +        if quicklist is None:
>>>> +            return 0
>>>> +
>>>> +        for cpu in cpus.each_online_cpu():
>>>> +            ql = cpus.per_cpu(quicklist, cpu)
>>>> +            for q in range(0, constants.LX_CONFIG_NR_QUICK):
>>>> +                # for (q = ql; q < ql + CONFIG_NR_QUICK; q++)
>>>> +                # count += q->nr_pages
>>>> +                count += ql[q]['nr_pages']
>>>> +
>>>> +        return count
>>>> +
>>>> +    # Main lx-meminfo command execution
>>>> +    # See fs/proc/meminfo.c:meminfo_proc_show()
>>>> +    def invoke(self, arg, from_tty):
>>>> +        totalram = int(gdb.parse_and_eval("totalram_pages"))
>>>> +        freeram = self.gps("NR_FREE_PAGES")
>>>> +        reclaimable = self.gps("NR_SLAB_RECLAIMABLE")
>>>> +        unreclaimable = self.gps("NR_SLAB_UNRECLAIMABLE")
>>>> +        slab = reclaimable + unreclaimable
>>>> +        # for_each_zone(zone)
>>>> +        #     wmark_low += zone->watermark[WMARK_LOW];
>>>> +        wmark_low = 0   # Zone parsing is unimplemented
>>>> +
>>>> +        available = freeram - wmark_low
>>>> +        available += reclaimable - min(reclaimable / 2, wmark_low)
>>>> +
>>>> +        bufferram = self.nr_blockdev_pages()
>>>> +        swapcached = self.total_swapcache_pages()
>>>> +
>>>> +        file_pages = self.gps("NR_FILE_PAGES")
>>>> +        cached = file_pages - swapcached - bufferram
>>>> +
>>>> +        # LRU Pages
>>>> +        active_pages_anon = self.gps("NR_ACTIVE_ANON")
>>>> +        inactive_pages_anon = self.gps("NR_INACTIVE_ANON")
>>>> +        active_pages_file = self.gps("NR_ACTIVE_FILE")
>>>> +        inactive_pages_file = self.gps("NR_INACTIVE_FILE")
>>>> +        unevictable_pages = self.gps("NR_UNEVICTABLE")
>>>> +        active_pages = active_pages_anon + active_pages_file
>>>> +        inactive_pages = inactive_pages_anon + inactive_pages_file
>>>> +
>>>> +        kernelstack = int(self.gps("NR_KERNEL_STACK") *
>>>> +                          constants.LX_THREAD_SIZE / 1024)
>>>> +
>>>> +        commitlimit = int(self.vm_commit_limit(totalram))
>>>> +        committed_as = int(gdb.parse_and_eval("vm_committed_as.count"))
>>>> +
>>>> +        vmalloc_total = int(constants.LX_VMALLOC_TOTAL >> 10)
>>>> +
>>>> +        gdb.write(
>>>> +            "MemTotal:       {:8d} kB\n".format(self.K(totalram)) +
>>>> +            "MemFree:        {:8d} kB\n".format(self.K(freeram)) +
>>>> +            "MemAvailable:   {:8d} kB\n".format(self.K(available)) +
>>>> +            "Buffers:        {:8d} kB\n".format(self.K(bufferram)) +
>>>> +            "Cached:         {:8d} kB\n".format(self.K(cached)) +
>>>> +            "SwapCached:     {:8d} kB\n".format(self.K(swapcached)) +
>>>> +            "Active:         {:8d} kB\n".format(self.K(active_pages)) +
>>>> +            "Inactive:       {:8d} kB\n".format(self.K(inactive_pages)) +
>>>> +            "Active(anon):   {:8d} kB\n".format(self.K(active_pages_anon)) +
>>>> +            "Inactive(anon): {:8d} kB\n".format(self.K(inactive_pages_anon)) +
>>>> +            "Active(file):   {:8d} kB\n".format(self.K(active_pages_file)) +
>>>> +            "Inactive(file): {:8d} kB\n".format(self.K(inactive_pages_file)) +
>>>> +            "Unevictable:    {:8d} kB\n".format(self.K(unevictable_pages)) +
>>>> +            "Mlocked:        {:8d} kB\n".format(self.gps_K("NR_MLOCK"))
>>>> +            )
>>>> +
>>>> +        if constants.LX_CONFIG_HIGHMEM:
>>>> +            totalhigh = int(gdb.parse_and_eval("totalhigh_pages"))
>>>> +            freehigh = int(gdb.parse_and_eval("nr_free_highpages()"))
>>>> +            lowtotal = totalram - totalhigh
>>>> +            lowfree = freeram - freehigh
>>>> +            gdb.write(
>>>> +                "HighTotal:      {:8d} kB\n".format(self.K(totalhigh)) +
>>>> +                "HighFree:       {:8d} kB\n".format(self.K(freehigh)) +
>>>> +                "LowTotal:       {:8d} kB\n".format(self.K(lowtotal)) +
>>>> +                "LowFree:        {:8d} kB\n".format(self.K(lowfree))
>>>> +                )
>>>> +
>>>> +        if not constants.LX_CONFIG_MMU:
>>>> +            mmap_pg_alloc = gdb.parse_and_eval("mmap_pages_allocated.counter")
>>>> +            gdb.write(
>>>> +                "MmapCopy:       {:8d} kB\n".format(self.K(mmap_pg_alloc))
>>>> +                )
>>>> +
>>>> +        gdb.write(
>>>> +            "SwapTotal:      {:8d} kB\n".format(self.K(0)) +
>>>> +            "SwapFree:       {:8d} kB\n".format(self.K(0)) +
>>>> +            "Dirty:          {:8d} kB\n".format(self.gps_K("NR_FILE_DIRTY")) +
>>>> +            "Writeback:      {:8d} kB\n".format(self.gps_K("NR_WRITEBACK")) +
>>>> +            "AnonPages:      {:8d} kB\n".format(self.gps_K("NR_ANON_PAGES")) +
>>>> +            "Mapped:         {:8d} kB\n".format(self.gps_K("NR_FILE_MAPPED")) +
>>>> +            "Shmem:          {:8d} kB\n".format(self.gps_K("NR_SHMEM")) +
>>>> +            "Slab:           {:8d} kB\n".format(self.K(slab)) +
>>>> +            "SReclaimable:   {:8d} kB\n".format(self.K(reclaimable)) +
>>>> +            "SUnreclaim:     {:8d} kB\n".format(self.K(unreclaimable)) +
>>>> +            "KernelStack:    {:8d} kB\n".format(kernelstack) +
>>>> +            "PageTables:     {:8d} kB\n".format(self.gps_K("NR_PAGETABLE"))
>>>> +            )
>>>> +
>>>> +        if constants.LX_CONFIG_QUICKLIST:
>>>> +            quicklist = self.quicklist_total_size()
>>>> +            gdb.write(
>>>> +               "Quicklists:     {:8d} kB\n".format(self.K(quicklist))
>>>
>>> scripts/gdb/linux/proc.py:381:16: E121 continuation line under-indented
>>> for hanging indent
>>>
>>> Please make sure to run pep8 on the series before posting.
>>
>> My apologies for the error, but on my laptop pep8 runs clean?
>>
>> What version are you running?
>> I have the following:
>>
>> $ pep8 --version
>> 1.6.2
> 
> Hmm, 1.5.7 here - pep8 regression?
> 
> The problem above is simply a missing space (4 required, instead of 3).

Ok - I see it.
Fixed up locally ready for a v4

I will try to downgrade to 1.5.7, and retest before v4. Then try to
figure out where to report a regression on the tool!

> 
> Jan
> 

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web