Message ID | 1456154652-29023-9-git-send-email-kieran.bingham@linaro.org |
---|---|
State | Superseded |
Headers | show |
I had missed some PEP8 line length warnings on this patch - I've now fixed them up. And a spurious 'pass' statement appeared (highlighted inline), which I've removed. -- Kieran On 22/02/16 15:24, 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 > > 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) > --- > scripts/gdb/linux/constants.py.in | 34 ++++++ > scripts/gdb/linux/proc.py | 219 ++++++++++++++++++++++++++++++++++++++ > 2 files changed, 253 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 44804e10493e..95933f66ea3e 100644 > --- a/scripts/gdb/linux/proc.py > +++ b/scripts/gdb/linux/proc.py > @@ -204,3 +204,222 @@ 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() > + total_swapcache_pages = self.total_swapcache_pages() > + > + file_pages = self.gps("NR_FILE_PAGES") > + cached = file_pages - total_swapcache_pages - 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(total_swapcache_pages)) + > + "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()")) > + 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(totalram-totalhigh)) + > + "LowFree: {:8d} kB\n".format(self.K(freeram-freehigh)) > + ) > + if not constants.LX_CONFIG_MMU: > + mmap_pages_allocated = gdb.parse_and_eval("mmap_pages_allocated.counter") > + gdb.write( > + "MmapCopy: {:8d} kB\n".format(self.K(mmap_pages_allocated)) > + > + ) > + pass Hrm ... No idea where this 'pass' statement crept in ... It has been dropped for the next patch version. > + > + 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)) > + ) > + > + gdb.write( > + "NFS_Unstable: {:8d} kB\n".format(self.gps_K("NR_UNSTABLE_NFS")) + > + "Bounce: {:8d} kB\n".format(self.gps_K("NR_BOUNCE")) + > + "WritebackTmp: {:8d} kB\n".format(self.gps_K("NR_WRITEBACK_TEMP")) > + ) > + > + gdb.write( > + "CommitLimit: {:8d} kB\n".format(self.K(commitlimit)) + > + "Committed_AS: {:8d} kB\n".format(self.K(committed_as)) + > + "VmallocTotal: {:8d} kB\n".format(vmalloc_total) > + ) > + > + # These are always zero now > + gdb.write( > + "VmallocUsed: {:8d} kB\n".format(0) + > + "VmallocChunk: {:8d} kB\n".format(0) > + ) > + > + if constants.LX_CONFIG_MEMORY_FAILURE: > + gdb.write( > + "HardwareCorrupted: {:8d} kB\n" > + ) > + if constants.LX_CONFIG_TRANSPARENT_HUGEPAGE: > + huge = self.gps("NR_ANON_TRANSPARENT_HUGEPAGES") > + # HPAGE_PMD_NR can not be determined in constants.py > + gdb.write( > + "AnonHugePages: {:8d} kB ( * HPAGE_PMD_NR )\n" > + .format(self.K(huge)) > + ) > + if constants.LX_CONFIG_CMA: > + totalcma_pages = int(gdb.parse_and_eval("totalcma_pages")) > + gdb.write( > + "CmaTotal: {:8d} kB\n".format(self.K(totalcma_pages)) + > + "CmaFree: {:8d} kB\n".format(self.gps_K("NR_FREE_CMA_PAGES")) > + ) > + > +LxMeminfo() >
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 44804e10493e..95933f66ea3e 100644 --- a/scripts/gdb/linux/proc.py +++ b/scripts/gdb/linux/proc.py @@ -204,3 +204,222 @@ 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() + total_swapcache_pages = self.total_swapcache_pages() + + file_pages = self.gps("NR_FILE_PAGES") + cached = file_pages - total_swapcache_pages - 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(total_swapcache_pages)) + + "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()")) + 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(totalram-totalhigh)) + + "LowFree: {:8d} kB\n".format(self.K(freeram-freehigh)) + ) + if not constants.LX_CONFIG_MMU: + mmap_pages_allocated = gdb.parse_and_eval("mmap_pages_allocated.counter") + gdb.write( + "MmapCopy: {:8d} kB\n".format(self.K(mmap_pages_allocated)) + + ) + pass + + 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)) + ) + + gdb.write( + "NFS_Unstable: {:8d} kB\n".format(self.gps_K("NR_UNSTABLE_NFS")) + + "Bounce: {:8d} kB\n".format(self.gps_K("NR_BOUNCE")) + + "WritebackTmp: {:8d} kB\n".format(self.gps_K("NR_WRITEBACK_TEMP")) + ) + + gdb.write( + "CommitLimit: {:8d} kB\n".format(self.K(commitlimit)) + + "Committed_AS: {:8d} kB\n".format(self.K(committed_as)) + + "VmallocTotal: {:8d} kB\n".format(vmalloc_total) + ) + + # These are always zero now + gdb.write( + "VmallocUsed: {:8d} kB\n".format(0) + + "VmallocChunk: {:8d} kB\n".format(0) + ) + + if constants.LX_CONFIG_MEMORY_FAILURE: + gdb.write( + "HardwareCorrupted: {:8d} kB\n" + ) + if constants.LX_CONFIG_TRANSPARENT_HUGEPAGE: + huge = self.gps("NR_ANON_TRANSPARENT_HUGEPAGES") + # HPAGE_PMD_NR can not be determined in constants.py + gdb.write( + "AnonHugePages: {:8d} kB ( * HPAGE_PMD_NR )\n" + .format(self.K(huge)) + ) + if constants.LX_CONFIG_CMA: + totalcma_pages = int(gdb.parse_and_eval("totalcma_pages")) + gdb.write( + "CmaTotal: {:8d} kB\n".format(self.K(totalcma_pages)) + + "CmaFree: {:8d} kB\n".format(self.gps_K("NR_FREE_CMA_PAGES")) + ) + +LxMeminfo()
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 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) --- scripts/gdb/linux/constants.py.in | 34 ++++++ scripts/gdb/linux/proc.py | 219 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 253 insertions(+) -- 2.5.0