~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/scripts/gdb/linux/page_owner.py

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /scripts/gdb/linux/page_owner.py (Architecture ppc) and /scripts/gdb/linux/page_owner.py (Architecture m68k)


  1 # SPDX-License-Identifier: GPL-2.0                  1 # SPDX-License-Identifier: GPL-2.0
  2 #                                                   2 #
  3 # Copyright (c) 2023 MediaTek Inc.                  3 # Copyright (c) 2023 MediaTek Inc.
  4 #                                                   4 #
  5 # Authors:                                          5 # Authors:
  6 #  Kuan-Ying Lee <Kuan-Ying.Lee@mediatek.com>        6 #  Kuan-Ying Lee <Kuan-Ying.Lee@mediatek.com>
  7 #                                                   7 #
  8                                                     8 
  9 import gdb                                          9 import gdb
 10 from linux import utils, stackdepot, constants     10 from linux import utils, stackdepot, constants, mm
 11                                                    11 
 12 if constants.LX_CONFIG_PAGE_OWNER:                 12 if constants.LX_CONFIG_PAGE_OWNER:
 13     page_ext_t = utils.CachedType('struct page     13     page_ext_t = utils.CachedType('struct page_ext')
 14     page_owner_t = utils.CachedType('struct pa     14     page_owner_t = utils.CachedType('struct page_owner')
 15                                                    15 
 16     PAGE_OWNER_STACK_DEPTH = 16                    16     PAGE_OWNER_STACK_DEPTH = 16
 17     PAGE_EXT_OWNER = constants.LX_PAGE_EXT_OWN     17     PAGE_EXT_OWNER = constants.LX_PAGE_EXT_OWNER
 18     PAGE_EXT_INVALID = 0x1                         18     PAGE_EXT_INVALID = 0x1
 19     PAGE_EXT_OWNER_ALLOCATED = constants.LX_PA     19     PAGE_EXT_OWNER_ALLOCATED = constants.LX_PAGE_EXT_OWNER_ALLOCATED
 20                                                    20 
 21 def help():                                        21 def help():
 22     t = """Usage: lx-dump-page-owner [Option]      22     t = """Usage: lx-dump-page-owner [Option]
 23     Option:                                        23     Option:
 24         --pfn [Decimal pfn]                        24         --pfn [Decimal pfn]
 25     Example:                                       25     Example:
 26         lx-dump-page-owner --pfn 655360\n"""       26         lx-dump-page-owner --pfn 655360\n"""
 27     gdb.write("Unrecognized command\n")            27     gdb.write("Unrecognized command\n")
 28     raise gdb.GdbError(t)                          28     raise gdb.GdbError(t)
 29                                                    29 
 30 class DumpPageOwner(gdb.Command):                  30 class DumpPageOwner(gdb.Command):
 31     """Dump page owner"""                          31     """Dump page owner"""
 32                                                    32 
 33     min_pfn = None                                 33     min_pfn = None
 34     max_pfn = None                                 34     max_pfn = None
 35     p_ops = None                                   35     p_ops = None
 36     migrate_reason_names = None                    36     migrate_reason_names = None
 37                                                    37 
 38     def __init__(self):                            38     def __init__(self):
 39         super(DumpPageOwner, self).__init__("l     39         super(DumpPageOwner, self).__init__("lx-dump-page-owner", gdb.COMMAND_SUPPORT)
 40                                                    40 
 41     def invoke(self, args, from_tty):              41     def invoke(self, args, from_tty):
 42         if not constants.LX_CONFIG_PAGE_OWNER:     42         if not constants.LX_CONFIG_PAGE_OWNER:
 43             raise gdb.GdbError('CONFIG_PAGE_OW     43             raise gdb.GdbError('CONFIG_PAGE_OWNER does not enable')
 44                                                    44 
 45         page_owner_inited = gdb.parse_and_eval     45         page_owner_inited = gdb.parse_and_eval('page_owner_inited')
 46         if page_owner_inited['key']['enabled']     46         if page_owner_inited['key']['enabled']['counter'] != 0x1:
 47             raise gdb.GdbError('page_owner_ini     47             raise gdb.GdbError('page_owner_inited is not enabled')
 48                                                    48 
 49         self.p_ops = mm.page_ops().ops             49         self.p_ops = mm.page_ops().ops
 50         self.get_page_owner_info()                 50         self.get_page_owner_info()
 51         argv = gdb.string_to_argv(args)            51         argv = gdb.string_to_argv(args)
 52         if len(argv) == 0:                         52         if len(argv) == 0:
 53               self.read_page_owner()               53               self.read_page_owner()
 54         elif len(argv) == 2:                       54         elif len(argv) == 2:
 55             if argv[0] == "--pfn":                 55             if argv[0] == "--pfn":
 56                 pfn = int(argv[1])                 56                 pfn = int(argv[1])
 57                 self.read_page_owner_by_addr(s     57                 self.read_page_owner_by_addr(self.p_ops.pfn_to_page(pfn))
 58             else:                                  58             else:
 59                 help()                             59                 help()
 60         else:                                      60         else:
 61             help()                                 61             help()
 62                                                    62 
 63     def get_page_owner_info(self):                 63     def get_page_owner_info(self):
 64         self.min_pfn = int(gdb.parse_and_eval(     64         self.min_pfn = int(gdb.parse_and_eval("min_low_pfn"))
 65         self.max_pfn = int(gdb.parse_and_eval(     65         self.max_pfn = int(gdb.parse_and_eval("max_pfn"))
 66         self.page_ext_size = int(gdb.parse_and     66         self.page_ext_size = int(gdb.parse_and_eval("page_ext_size"))
 67         self.migrate_reason_names = gdb.parse_     67         self.migrate_reason_names = gdb.parse_and_eval('migrate_reason_names')
 68                                                    68 
 69     def page_ext_invalid(self, page_ext):          69     def page_ext_invalid(self, page_ext):
 70         if page_ext == gdb.Value(0):               70         if page_ext == gdb.Value(0):
 71             return True                            71             return True
 72         if page_ext.cast(utils.get_ulong_type(     72         if page_ext.cast(utils.get_ulong_type()) & PAGE_EXT_INVALID == PAGE_EXT_INVALID:
 73             return True                            73             return True
 74         return False                               74         return False
 75                                                    75 
 76     def get_entry(self, base, index):              76     def get_entry(self, base, index):
 77         return (base.cast(utils.get_ulong_type     77         return (base.cast(utils.get_ulong_type()) + self.page_ext_size * index).cast(page_ext_t.get_type().pointer())
 78                                                    78 
 79     def lookup_page_ext(self, page):               79     def lookup_page_ext(self, page):
 80         pfn = self.p_ops.page_to_pfn(page)         80         pfn = self.p_ops.page_to_pfn(page)
 81         section = self.p_ops.pfn_to_section(pf     81         section = self.p_ops.pfn_to_section(pfn)
 82         page_ext = section["page_ext"]             82         page_ext = section["page_ext"]
 83         if self.page_ext_invalid(page_ext):        83         if self.page_ext_invalid(page_ext):
 84             return gdb.Value(0)                    84             return gdb.Value(0)
 85         return self.get_entry(page_ext, pfn)       85         return self.get_entry(page_ext, pfn)
 86                                                    86 
 87     def page_ext_get(self, page):                  87     def page_ext_get(self, page):
 88         page_ext = self.lookup_page_ext(page)      88         page_ext = self.lookup_page_ext(page)
 89         if page_ext != gdb.Value(0):               89         if page_ext != gdb.Value(0):
 90             return page_ext                        90             return page_ext
 91         else:                                      91         else:
 92             return gdb.Value(0)                    92             return gdb.Value(0)
 93                                                    93 
 94     def get_page_owner(self, page_ext):            94     def get_page_owner(self, page_ext):
 95         addr = page_ext.cast(utils.get_ulong_t     95         addr = page_ext.cast(utils.get_ulong_type()) + gdb.parse_and_eval("page_owner_ops")["offset"].cast(utils.get_ulong_type())
 96         return addr.cast(page_owner_t.get_type     96         return addr.cast(page_owner_t.get_type().pointer())
 97                                                    97 
 98     def read_page_owner_by_addr(self, struct_p     98     def read_page_owner_by_addr(self, struct_page_addr):
 99         page = gdb.Value(struct_page_addr).cas     99         page = gdb.Value(struct_page_addr).cast(utils.get_page_type().pointer())
100         pfn = self.p_ops.page_to_pfn(page)        100         pfn = self.p_ops.page_to_pfn(page)
101                                                   101 
102         if pfn < self.min_pfn or pfn > self.ma    102         if pfn < self.min_pfn or pfn > self.max_pfn or (not self.p_ops.pfn_valid(pfn)):
103             gdb.write("pfn is invalid\n")         103             gdb.write("pfn is invalid\n")
104             return                                104             return
105                                                   105 
106         page = self.p_ops.pfn_to_page(pfn)        106         page = self.p_ops.pfn_to_page(pfn)
107         page_ext = self.page_ext_get(page)        107         page_ext = self.page_ext_get(page)
108                                                   108 
109         if page_ext == gdb.Value(0):              109         if page_ext == gdb.Value(0):
110             gdb.write("page_ext is null\n")       110             gdb.write("page_ext is null\n")
111             return                                111             return
112                                                   112 
113         if not (page_ext['flags'] & (1 << PAGE    113         if not (page_ext['flags'] & (1 << PAGE_EXT_OWNER)):
114             gdb.write("page_owner flag is inva    114             gdb.write("page_owner flag is invalid\n")
115             raise gdb.GdbError('page_owner inf    115             raise gdb.GdbError('page_owner info is not present (never set?)\n')
116                                                   116 
117         if mm.test_bit(PAGE_EXT_OWNER_ALLOCATE    117         if mm.test_bit(PAGE_EXT_OWNER_ALLOCATED, page_ext['flags'].address):
118             gdb.write('page_owner tracks the p    118             gdb.write('page_owner tracks the page as allocated\n')
119         else:                                     119         else:
120             gdb.write('page_owner tracks the p    120             gdb.write('page_owner tracks the page as freed\n')
121                                                   121 
122         if not (page_ext['flags'] & (1 << PAGE    122         if not (page_ext['flags'] & (1 << PAGE_EXT_OWNER_ALLOCATED)):
123             gdb.write("page_owner is not alloc    123             gdb.write("page_owner is not allocated\n")
124                                                   124 
125         page_owner = self.get_page_owner(page_    125         page_owner = self.get_page_owner(page_ext)
126         gdb.write("Page last allocated via ord    126         gdb.write("Page last allocated via order %d, gfp_mask: 0x%x, pid: %d, tgid: %d (%s), ts %u ns, free_ts %u ns\n" %\
127                 (page_owner["order"], page_own    127                 (page_owner["order"], page_owner["gfp_mask"],\
128                 page_owner["pid"], page_owner[    128                 page_owner["pid"], page_owner["tgid"], page_owner["comm"].string(),\
129                 page_owner["ts_nsec"], page_ow    129                 page_owner["ts_nsec"], page_owner["free_ts_nsec"]))
130         gdb.write("PFN: %d, Flags: 0x%x\n" % (    130         gdb.write("PFN: %d, Flags: 0x%x\n" % (pfn, page['flags']))
131         if page_owner["handle"] == 0:             131         if page_owner["handle"] == 0:
132             gdb.write('page_owner allocation s    132             gdb.write('page_owner allocation stack trace missing\n')
133         else:                                     133         else:
134             stackdepot.stack_depot_print(page_    134             stackdepot.stack_depot_print(page_owner["handle"])
135                                                   135 
136         if page_owner["free_handle"] == 0:        136         if page_owner["free_handle"] == 0:
137             gdb.write('page_owner free stack t    137             gdb.write('page_owner free stack trace missing\n')
138         else:                                     138         else:
139             gdb.write('page last free stack tr    139             gdb.write('page last free stack trace:\n')
140             stackdepot.stack_depot_print(page_    140             stackdepot.stack_depot_print(page_owner["free_handle"])
141         if page_owner['last_migrate_reason'] !    141         if page_owner['last_migrate_reason'] != -1:
142             gdb.write('page has been migrated,    142             gdb.write('page has been migrated, last migrate reason: %s\n' % self.migrate_reason_names[page_owner['last_migrate_reason']])
143                                                   143 
144     def read_page_owner(self):                    144     def read_page_owner(self):
145         pfn = self.min_pfn                        145         pfn = self.min_pfn
146                                                   146 
147         # Find a valid PFN or the start of a M    147         # Find a valid PFN or the start of a MAX_ORDER_NR_PAGES area
148         while ((not self.p_ops.pfn_valid(pfn))    148         while ((not self.p_ops.pfn_valid(pfn)) and (pfn & (self.p_ops.MAX_ORDER_NR_PAGES - 1))) != 0:
149             pfn += 1                              149             pfn += 1
150                                                   150 
151         while pfn < self.max_pfn:                 151         while pfn < self.max_pfn:
152             #                                     152             #
153             # If the new page is in a new MAX_    153             # If the new page is in a new MAX_ORDER_NR_PAGES area,
154             # validate the area as existing, s    154             # validate the area as existing, skip it if not
155             #                                     155             #
156             if ((pfn & (self.p_ops.MAX_ORDER_N    156             if ((pfn & (self.p_ops.MAX_ORDER_NR_PAGES - 1)) == 0) and (not self.p_ops.pfn_valid(pfn)):
157                 pfn += (self.p_ops.MAX_ORDER_N    157                 pfn += (self.p_ops.MAX_ORDER_NR_PAGES - 1)
158                 continue;                         158                 continue;
159                                                   159 
160             page = self.p_ops.pfn_to_page(pfn)    160             page = self.p_ops.pfn_to_page(pfn)
161             page_ext = self.page_ext_get(page)    161             page_ext = self.page_ext_get(page)
162             if page_ext == gdb.Value(0):          162             if page_ext == gdb.Value(0):
163                 pfn += 1                          163                 pfn += 1
164                 continue                          164                 continue
165                                                   165 
166             if not (page_ext['flags'] & (1 <<     166             if not (page_ext['flags'] & (1 << PAGE_EXT_OWNER)):
167                 pfn += 1                          167                 pfn += 1
168                 continue                          168                 continue
169             if not (page_ext['flags'] & (1 <<     169             if not (page_ext['flags'] & (1 << PAGE_EXT_OWNER_ALLOCATED)):
170                 pfn += 1                          170                 pfn += 1
171                 continue                          171                 continue
172                                                   172 
173             page_owner = self.get_page_owner(p    173             page_owner = self.get_page_owner(page_ext)
174             gdb.write("Page allocated via orde    174             gdb.write("Page allocated via order %d, gfp_mask: 0x%x, pid: %d, tgid: %d (%s), ts %u ns, free_ts %u ns\n" %\
175                     (page_owner["order"], page    175                     (page_owner["order"], page_owner["gfp_mask"],\
176                     page_owner["pid"], page_ow    176                     page_owner["pid"], page_owner["tgid"], page_owner["comm"].string(),\
177                     page_owner["ts_nsec"], pag    177                     page_owner["ts_nsec"], page_owner["free_ts_nsec"]))
178             gdb.write("PFN: %d, Flags: 0x%x\n"    178             gdb.write("PFN: %d, Flags: 0x%x\n" % (pfn, page['flags']))
179             stackdepot.stack_depot_print(page_    179             stackdepot.stack_depot_print(page_owner["handle"])
180             pfn += (1 << page_owner["order"])     180             pfn += (1 << page_owner["order"])
181                                                   181 
182 DumpPageOwner()                                   182 DumpPageOwner()
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php