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 import re 10 import re 11 import traceback 11 import traceback 12 from linux import lists, utils, stackdepot, co 12 from linux import lists, utils, stackdepot, constants, mm 13 13 14 SLAB_RED_ZONE = constants.LX_SLAB_RED_ZO 14 SLAB_RED_ZONE = constants.LX_SLAB_RED_ZONE 15 SLAB_POISON = constants.LX_SLAB_POISON 15 SLAB_POISON = constants.LX_SLAB_POISON 16 SLAB_KMALLOC = constants.LX_SLAB_KMALLO 16 SLAB_KMALLOC = constants.LX_SLAB_KMALLOC 17 SLAB_HWCACHE_ALIGN = constants.LX_SLAB_HWCACH 17 SLAB_HWCACHE_ALIGN = constants.LX_SLAB_HWCACHE_ALIGN 18 SLAB_CACHE_DMA = constants.LX_SLAB_CACHE_ 18 SLAB_CACHE_DMA = constants.LX_SLAB_CACHE_DMA 19 SLAB_CACHE_DMA32 = constants.LX_SLAB_CACHE_ 19 SLAB_CACHE_DMA32 = constants.LX_SLAB_CACHE_DMA32 20 SLAB_STORE_USER = constants.LX_SLAB_STORE_ 20 SLAB_STORE_USER = constants.LX_SLAB_STORE_USER 21 SLAB_PANIC = constants.LX_SLAB_PANIC 21 SLAB_PANIC = constants.LX_SLAB_PANIC 22 22 23 OO_SHIFT = 16 23 OO_SHIFT = 16 24 OO_MASK = (1 << OO_SHIFT) - 1 24 OO_MASK = (1 << OO_SHIFT) - 1 25 25 26 if constants.LX_CONFIG_SLUB_DEBUG: 26 if constants.LX_CONFIG_SLUB_DEBUG: 27 slab_type = utils.CachedType("struct slab" 27 slab_type = utils.CachedType("struct slab") 28 slab_ptr_type = slab_type.get_type().point 28 slab_ptr_type = slab_type.get_type().pointer() 29 kmem_cache_type = utils.CachedType("struct 29 kmem_cache_type = utils.CachedType("struct kmem_cache") 30 kmem_cache_ptr_type = kmem_cache_type.get_ 30 kmem_cache_ptr_type = kmem_cache_type.get_type().pointer() 31 freeptr_t = utils.CachedType("freeptr_t") 31 freeptr_t = utils.CachedType("freeptr_t") 32 freeptr_t_ptr = freeptr_t.get_type().point 32 freeptr_t_ptr = freeptr_t.get_type().pointer() 33 33 34 track_type = gdb.lookup_type('struct track 34 track_type = gdb.lookup_type('struct track') 35 track_alloc = int(gdb.parse_and_eval('TRAC 35 track_alloc = int(gdb.parse_and_eval('TRACK_ALLOC')) 36 track_free = int(gdb.parse_and_eval('TRACK 36 track_free = int(gdb.parse_and_eval('TRACK_FREE')) 37 37 38 def slab_folio(slab): 38 def slab_folio(slab): 39 return slab.cast(gdb.lookup_type("struct f 39 return slab.cast(gdb.lookup_type("struct folio").pointer()) 40 40 41 def slab_address(slab): 41 def slab_address(slab): 42 p_ops = mm.page_ops().ops 42 p_ops = mm.page_ops().ops 43 folio = slab_folio(slab) 43 folio = slab_folio(slab) 44 return p_ops.folio_address(folio) 44 return p_ops.folio_address(folio) 45 45 46 def for_each_object(cache, addr, slab_objects) 46 def for_each_object(cache, addr, slab_objects): 47 p = addr 47 p = addr 48 if cache['flags'] & SLAB_RED_ZONE: 48 if cache['flags'] & SLAB_RED_ZONE: 49 p += int(cache['red_left_pad']) 49 p += int(cache['red_left_pad']) 50 while p < addr + (slab_objects * cache['si 50 while p < addr + (slab_objects * cache['size']): 51 yield p 51 yield p 52 p = p + int(cache['size']) 52 p = p + int(cache['size']) 53 53 54 def get_info_end(cache): 54 def get_info_end(cache): 55 if (cache['offset'] >= cache['inuse']): 55 if (cache['offset'] >= cache['inuse']): 56 return cache['inuse'] + gdb.lookup_typ 56 return cache['inuse'] + gdb.lookup_type("void").pointer().sizeof 57 else: 57 else: 58 return cache['inuse'] 58 return cache['inuse'] 59 59 60 def get_orig_size(cache, obj): 60 def get_orig_size(cache, obj): 61 if cache['flags'] & SLAB_STORE_USER and ca 61 if cache['flags'] & SLAB_STORE_USER and cache['flags'] & SLAB_KMALLOC: 62 p = mm.page_ops().ops.kasan_reset_tag( 62 p = mm.page_ops().ops.kasan_reset_tag(obj) 63 p += get_info_end(cache) 63 p += get_info_end(cache) 64 p += gdb.lookup_type('struct track').s 64 p += gdb.lookup_type('struct track').sizeof * 2 65 p = p.cast(utils.get_uint_type().point 65 p = p.cast(utils.get_uint_type().pointer()) 66 return p.dereference() 66 return p.dereference() 67 else: 67 else: 68 return cache['object_size'] 68 return cache['object_size'] 69 69 70 def get_track(cache, object_pointer, alloc): 70 def get_track(cache, object_pointer, alloc): 71 p = object_pointer + get_info_end(cache) 71 p = object_pointer + get_info_end(cache) 72 p += (alloc * track_type.sizeof) 72 p += (alloc * track_type.sizeof) 73 return p 73 return p 74 74 75 def oo_objects(x): 75 def oo_objects(x): 76 return int(x['x']) & OO_MASK 76 return int(x['x']) & OO_MASK 77 77 78 def oo_order(x): 78 def oo_order(x): 79 return int(x['x']) >> OO_SHIFT 79 return int(x['x']) >> OO_SHIFT 80 80 81 def reciprocal_divide(a, R): 81 def reciprocal_divide(a, R): 82 t = (a * int(R['m'])) >> 32 82 t = (a * int(R['m'])) >> 32 83 return (t + ((a - t) >> int(R['sh1']))) >> 83 return (t + ((a - t) >> int(R['sh1']))) >> int(R['sh2']) 84 84 85 def __obj_to_index(cache, addr, obj): 85 def __obj_to_index(cache, addr, obj): 86 return reciprocal_divide(int(mm.page_ops() 86 return reciprocal_divide(int(mm.page_ops().ops.kasan_reset_tag(obj)) - addr, cache['reciprocal_size']) 87 87 88 def swab64(x): 88 def swab64(x): 89 result = (((x & 0x00000000000000ff) << 56) 89 result = (((x & 0x00000000000000ff) << 56) | \ 90 ((x & 0x000000000000ff00) << 40) | \ 90 ((x & 0x000000000000ff00) << 40) | \ 91 ((x & 0x0000000000ff0000) << 24) | \ 91 ((x & 0x0000000000ff0000) << 24) | \ 92 ((x & 0x00000000ff000000) << 8) | \ 92 ((x & 0x00000000ff000000) << 8) | \ 93 ((x & 0x000000ff00000000) >> 8) | \ 93 ((x & 0x000000ff00000000) >> 8) | \ 94 ((x & 0x0000ff0000000000) >> 24) | \ 94 ((x & 0x0000ff0000000000) >> 24) | \ 95 ((x & 0x00ff000000000000) >> 40) | \ 95 ((x & 0x00ff000000000000) >> 40) | \ 96 ((x & 0xff00000000000000) >> 56)) 96 ((x & 0xff00000000000000) >> 56)) 97 return result 97 return result 98 98 99 def freelist_ptr_decode(cache, ptr, ptr_addr): 99 def freelist_ptr_decode(cache, ptr, ptr_addr): 100 if constants.LX_CONFIG_SLAB_FREELIST_HARDE 100 if constants.LX_CONFIG_SLAB_FREELIST_HARDENED: 101 return ptr['v'] ^ cache['random'] ^ sw 101 return ptr['v'] ^ cache['random'] ^ swab64(int(ptr_addr)) 102 else: 102 else: 103 return ptr['v'] 103 return ptr['v'] 104 104 105 def get_freepointer(cache, obj): 105 def get_freepointer(cache, obj): 106 obj = mm.page_ops().ops.kasan_reset_tag(ob 106 obj = mm.page_ops().ops.kasan_reset_tag(obj) 107 ptr_addr = obj + cache['offset'] 107 ptr_addr = obj + cache['offset'] 108 p = ptr_addr.cast(freeptr_t_ptr).dereferen 108 p = ptr_addr.cast(freeptr_t_ptr).dereference() 109 return freelist_ptr_decode(cache, p, ptr_a 109 return freelist_ptr_decode(cache, p, ptr_addr) 110 110 111 def loc_exist(loc_track, addr, handle, waste): 111 def loc_exist(loc_track, addr, handle, waste): 112 for loc in loc_track: 112 for loc in loc_track: 113 if loc['addr'] == addr and loc['handle 113 if loc['addr'] == addr and loc['handle'] == handle and loc['waste'] == waste: 114 return loc 114 return loc 115 return None 115 return None 116 116 117 def add_location(loc_track, cache, track, orig 117 def add_location(loc_track, cache, track, orig_size): 118 jiffies = gdb.parse_and_eval("jiffies_64") 118 jiffies = gdb.parse_and_eval("jiffies_64") 119 age = jiffies - track['when'] 119 age = jiffies - track['when'] 120 handle = 0 120 handle = 0 121 waste = cache['object_size'] - int(orig_si 121 waste = cache['object_size'] - int(orig_size) 122 pid = int(track['pid']) 122 pid = int(track['pid']) 123 cpuid = int(track['cpu']) 123 cpuid = int(track['cpu']) 124 addr = track['addr'] 124 addr = track['addr'] 125 if constants.LX_CONFIG_STACKDEPOT: 125 if constants.LX_CONFIG_STACKDEPOT: 126 handle = track['handle'] 126 handle = track['handle'] 127 127 128 loc = loc_exist(loc_track, addr, handle, w 128 loc = loc_exist(loc_track, addr, handle, waste) 129 if loc: 129 if loc: 130 loc['count'] += 1 130 loc['count'] += 1 131 if track['when']: 131 if track['when']: 132 loc['sum_time'] += age 132 loc['sum_time'] += age 133 loc['min_time'] = min(loc['min_tim 133 loc['min_time'] = min(loc['min_time'], age) 134 loc['max_time'] = max(loc['max_tim 134 loc['max_time'] = max(loc['max_time'], age) 135 loc['min_pid'] = min(loc['min_pid' 135 loc['min_pid'] = min(loc['min_pid'], pid) 136 loc['max_pid'] = max(loc['max_pid' 136 loc['max_pid'] = max(loc['max_pid'], pid) 137 loc['cpus'].add(cpuid) 137 loc['cpus'].add(cpuid) 138 else: 138 else: 139 loc_track.append({ 139 loc_track.append({ 140 'count' : 1, 140 'count' : 1, 141 'addr' : addr, 141 'addr' : addr, 142 'sum_time' : age, 142 'sum_time' : age, 143 'min_time' : age, 143 'min_time' : age, 144 'max_time' : age, 144 'max_time' : age, 145 'min_pid' : pid, 145 'min_pid' : pid, 146 'max_pid' : pid, 146 'max_pid' : pid, 147 'handle' : handle, 147 'handle' : handle, 148 'waste' : waste, 148 'waste' : waste, 149 'cpus' : {cpuid} 149 'cpus' : {cpuid} 150 } 150 } 151 ) 151 ) 152 152 153 def slabtrace(alloc, cache_name): 153 def slabtrace(alloc, cache_name): 154 154 155 def __fill_map(obj_map, cache, slab): 155 def __fill_map(obj_map, cache, slab): 156 p = slab['freelist'] 156 p = slab['freelist'] 157 addr = slab_address(slab) 157 addr = slab_address(slab) 158 while p != gdb.Value(0): 158 while p != gdb.Value(0): 159 index = __obj_to_index(cache, addr 159 index = __obj_to_index(cache, addr, p) 160 obj_map[index] = True # free objec 160 obj_map[index] = True # free objects 161 p = get_freepointer(cache, p) 161 p = get_freepointer(cache, p) 162 162 163 # process every slab page on the slab_list 163 # process every slab page on the slab_list (partial and full list) 164 def process_slab(loc_track, slab_list, all 164 def process_slab(loc_track, slab_list, alloc, cache): 165 for slab in lists.list_for_each_entry( 165 for slab in lists.list_for_each_entry(slab_list, slab_ptr_type, "slab_list"): 166 obj_map[:] = [False] * oo_objects( 166 obj_map[:] = [False] * oo_objects(cache['oo']) 167 __fill_map(obj_map, cache, slab) 167 __fill_map(obj_map, cache, slab) 168 addr = slab_address(slab) 168 addr = slab_address(slab) 169 for object_pointer in for_each_obj 169 for object_pointer in for_each_object(cache, addr, slab['objects']): 170 if obj_map[__obj_to_index(cach 170 if obj_map[__obj_to_index(cache, addr, object_pointer)] == True: 171 continue 171 continue 172 p = get_track(cache, object_po 172 p = get_track(cache, object_pointer, alloc) 173 track = gdb.Value(p).cast(trac 173 track = gdb.Value(p).cast(track_type.pointer()) 174 if alloc == track_alloc: 174 if alloc == track_alloc: 175 size = get_orig_size(cache 175 size = get_orig_size(cache, object_pointer) 176 else: 176 else: 177 size = cache['object_size' 177 size = cache['object_size'] 178 add_location(loc_track, cache, 178 add_location(loc_track, cache, track, size) 179 continue 179 continue 180 180 181 slab_caches = gdb.parse_and_eval("slab_cac 181 slab_caches = gdb.parse_and_eval("slab_caches") 182 if mm.page_ops().ops.MAX_NUMNODES > 1: 182 if mm.page_ops().ops.MAX_NUMNODES > 1: 183 nr_node_ids = int(gdb.parse_and_eval(" 183 nr_node_ids = int(gdb.parse_and_eval("nr_node_ids")) 184 else: 184 else: 185 nr_node_ids = 1 185 nr_node_ids = 1 186 186 187 target_cache = None 187 target_cache = None 188 loc_track = [] 188 loc_track = [] 189 189 190 for cache in lists.list_for_each_entry(sla 190 for cache in lists.list_for_each_entry(slab_caches, kmem_cache_ptr_type, 'list'): 191 if cache['name'].string() == cache_nam 191 if cache['name'].string() == cache_name: 192 target_cache = cache 192 target_cache = cache 193 break 193 break 194 194 195 obj_map = [False] * oo_objects(target_cach 195 obj_map = [False] * oo_objects(target_cache['oo']) 196 196 197 if target_cache['flags'] & SLAB_STORE_USER 197 if target_cache['flags'] & SLAB_STORE_USER: 198 for i in range(0, nr_node_ids): 198 for i in range(0, nr_node_ids): 199 cache_node = target_cache['node'][ 199 cache_node = target_cache['node'][i] 200 if cache_node['nr_slabs']['counter 200 if cache_node['nr_slabs']['counter'] == 0: 201 continue 201 continue 202 process_slab(loc_track, cache_node 202 process_slab(loc_track, cache_node['partial'], alloc, target_cache) 203 process_slab(loc_track, cache_node 203 process_slab(loc_track, cache_node['full'], alloc, target_cache) 204 else: 204 else: 205 raise gdb.GdbError("SLAB_STORE_USER is 205 raise gdb.GdbError("SLAB_STORE_USER is not set in %s" % target_cache['name'].string()) 206 206 207 for loc in sorted(loc_track, key=lambda x: 207 for loc in sorted(loc_track, key=lambda x:x['count'], reverse=True): 208 if loc['addr']: 208 if loc['addr']: 209 addr = loc['addr'].cast(utils.get_ 209 addr = loc['addr'].cast(utils.get_ulong_type().pointer()) 210 gdb.write("%d %s" % (loc['count'], 210 gdb.write("%d %s" % (loc['count'], str(addr).split(' ')[-1])) 211 else: 211 else: 212 gdb.write("%d <not-available>" % l 212 gdb.write("%d <not-available>" % loc['count']) 213 213 214 if loc['waste']: 214 if loc['waste']: 215 gdb.write(" waste=%d/%d" % (loc['c 215 gdb.write(" waste=%d/%d" % (loc['count'] * loc['waste'], loc['waste'])) 216 216 217 if loc['sum_time'] != loc['min_time']: 217 if loc['sum_time'] != loc['min_time']: 218 gdb.write(" age=%d/%d/%d" % (loc[' 218 gdb.write(" age=%d/%d/%d" % (loc['min_time'], loc['sum_time']/loc['count'], loc['max_time'])) 219 else: 219 else: 220 gdb.write(" age=%d" % loc['min_tim 220 gdb.write(" age=%d" % loc['min_time']) 221 221 222 if loc['min_pid'] != loc['max_pid']: 222 if loc['min_pid'] != loc['max_pid']: 223 gdb.write(" pid=%d-%d" % (loc['min 223 gdb.write(" pid=%d-%d" % (loc['min_pid'], loc['max_pid'])) 224 else: 224 else: 225 gdb.write(" pid=%d" % loc['min_pid 225 gdb.write(" pid=%d" % loc['min_pid']) 226 226 227 if constants.LX_NR_CPUS > 1: 227 if constants.LX_NR_CPUS > 1: 228 nr_cpu = gdb.parse_and_eval('__num 228 nr_cpu = gdb.parse_and_eval('__num_online_cpus')['counter'] 229 if nr_cpu > 1: 229 if nr_cpu > 1: 230 gdb.write(" cpus=") 230 gdb.write(" cpus=") 231 gdb.write(','.join(str(cpu) fo !! 231 for i in loc['cpus']: >> 232 gdb.write("%d," % i) 232 gdb.write("\n") 233 gdb.write("\n") 233 if constants.LX_CONFIG_STACKDEPOT: 234 if constants.LX_CONFIG_STACKDEPOT: 234 if loc['handle']: 235 if loc['handle']: 235 stackdepot.stack_depot_print(l 236 stackdepot.stack_depot_print(loc['handle']) 236 gdb.write("\n") 237 gdb.write("\n") 237 238 238 def help(): 239 def help(): 239 t = """Usage: lx-slabtrace --cache_name [c 240 t = """Usage: lx-slabtrace --cache_name [cache_name] [Options] 240 Options: 241 Options: 241 --alloc 242 --alloc 242 print information of allocation tr 243 print information of allocation trace of the allocated objects 243 --free 244 --free 244 print information of freeing trace 245 print information of freeing trace of the allocated objects 245 Example: 246 Example: 246 lx-slabtrace --cache_name kmalloc-1k - 247 lx-slabtrace --cache_name kmalloc-1k --alloc 247 lx-slabtrace --cache_name kmalloc-1k - 248 lx-slabtrace --cache_name kmalloc-1k --free\n""" 248 gdb.write("Unrecognized command\n") 249 gdb.write("Unrecognized command\n") 249 raise gdb.GdbError(t) 250 raise gdb.GdbError(t) 250 251 251 class LxSlabTrace(gdb.Command): 252 class LxSlabTrace(gdb.Command): 252 """Show specific cache slabtrace""" 253 """Show specific cache slabtrace""" 253 254 254 def __init__(self): 255 def __init__(self): 255 super(LxSlabTrace, self).__init__("lx- 256 super(LxSlabTrace, self).__init__("lx-slabtrace", gdb.COMMAND_DATA) 256 257 257 def invoke(self, arg, from_tty): 258 def invoke(self, arg, from_tty): 258 if not constants.LX_CONFIG_SLUB_DEBUG: 259 if not constants.LX_CONFIG_SLUB_DEBUG: 259 raise gdb.GdbError("CONFIG_SLUB_DE 260 raise gdb.GdbError("CONFIG_SLUB_DEBUG is not enabled") 260 261 261 argv = gdb.string_to_argv(arg) 262 argv = gdb.string_to_argv(arg) 262 alloc = track_alloc # default show all 263 alloc = track_alloc # default show alloc_traces 263 264 264 if len(argv) == 3: 265 if len(argv) == 3: 265 if argv[2] == '--alloc': 266 if argv[2] == '--alloc': 266 alloc = track_alloc 267 alloc = track_alloc 267 elif argv[2] == '--free': 268 elif argv[2] == '--free': 268 alloc = track_free 269 alloc = track_free 269 else: 270 else: 270 help() 271 help() 271 if len(argv) >= 2 and argv[0] == '--ca 272 if len(argv) >= 2 and argv[0] == '--cache_name': 272 slabtrace(alloc, argv[1]) 273 slabtrace(alloc, argv[1]) 273 else: 274 else: 274 help() 275 help() 275 LxSlabTrace() 276 LxSlabTrace() 276 277 277 def slabinfo(): 278 def slabinfo(): 278 nr_node_ids = None 279 nr_node_ids = None 279 280 280 if not constants.LX_CONFIG_SLUB_DEBUG: 281 if not constants.LX_CONFIG_SLUB_DEBUG: 281 raise gdb.GdbError("CONFIG_SLUB_DEBUG 282 raise gdb.GdbError("CONFIG_SLUB_DEBUG is not enabled") 282 283 283 def count_free(slab): 284 def count_free(slab): 284 total_free = 0 285 total_free = 0 285 for slab in lists.list_for_each_entry( 286 for slab in lists.list_for_each_entry(slab, slab_ptr_type, 'slab_list'): 286 total_free += int(slab['objects'] 287 total_free += int(slab['objects'] - slab['inuse']) 287 return total_free 288 return total_free 288 289 289 gdb.write("{:^18} | {:^20} | {:^12} | {:^1 290 gdb.write("{:^18} | {:^20} | {:^12} | {:^12} | {:^8} | {:^11} | {:^13}\n".format('Pointer', 'name', 'active_objs', 'num_objs', 'objsize', 'objperslab', 'pagesperslab')) 290 gdb.write("{:-^18} | {:-^20} | {:-^12} | { 291 gdb.write("{:-^18} | {:-^20} | {:-^12} | {:-^12} | {:-^8} | {:-^11} | {:-^13}\n".format('', '', '', '', '', '', '')) 291 292 292 slab_caches = gdb.parse_and_eval("slab_cac 293 slab_caches = gdb.parse_and_eval("slab_caches") 293 if mm.page_ops().ops.MAX_NUMNODES > 1: 294 if mm.page_ops().ops.MAX_NUMNODES > 1: 294 nr_node_ids = int(gdb.parse_and_eval(" 295 nr_node_ids = int(gdb.parse_and_eval("nr_node_ids")) 295 else: 296 else: 296 nr_node_ids = 1 297 nr_node_ids = 1 297 298 298 for cache in lists.list_for_each_entry(sla 299 for cache in lists.list_for_each_entry(slab_caches, kmem_cache_ptr_type, 'list'): 299 nr_objs = 0 300 nr_objs = 0 300 nr_free = 0 301 nr_free = 0 301 nr_slabs = 0 302 nr_slabs = 0 302 for i in range(0, nr_node_ids): 303 for i in range(0, nr_node_ids): 303 cache_node = cache['node'][i] 304 cache_node = cache['node'][i] 304 try: 305 try: 305 nr_slabs += cache_node['nr_sla 306 nr_slabs += cache_node['nr_slabs']['counter'] 306 nr_objs = int(cache_node['tota 307 nr_objs = int(cache_node['total_objects']['counter']) 307 nr_free = count_free(cache_nod 308 nr_free = count_free(cache_node['partial']) 308 except: 309 except: 309 raise gdb.GdbError(traceback.f 310 raise gdb.GdbError(traceback.format_exc()) 310 active_objs = nr_objs - nr_free 311 active_objs = nr_objs - nr_free 311 num_objs = nr_objs 312 num_objs = nr_objs 312 active_slabs = nr_slabs 313 active_slabs = nr_slabs 313 objects_per_slab = oo_objects(cache['o 314 objects_per_slab = oo_objects(cache['oo']) 314 cache_order = oo_order(cache['oo']) 315 cache_order = oo_order(cache['oo']) 315 gdb.write("{:18s} | {:20.19s} | {:12} 316 gdb.write("{:18s} | {:20.19s} | {:12} | {:12} | {:8} | {:11} | {:13}\n".format(hex(cache), cache['name'].string(), str(active_objs), str(num_objs), str(cache['size']), str(objects_per_slab), str(1 << cache_order))) 316 317 317 class LxSlabInfo(gdb.Command): 318 class LxSlabInfo(gdb.Command): 318 """Show slabinfo""" 319 """Show slabinfo""" 319 320 320 def __init__(self): 321 def __init__(self): 321 super(LxSlabInfo, self).__init__("lx-s 322 super(LxSlabInfo, self).__init__("lx-slabinfo", gdb.COMMAND_DATA) 322 323 323 def invoke(self, arg, from_tty): 324 def invoke(self, arg, from_tty): 324 slabinfo() 325 slabinfo() 325 LxSlabInfo() 326 LxSlabInfo()
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.