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 gdb.write(','.join(str(cpu) for cpu in loc['cpus'])) 232 gdb.write("\n") 232 gdb.write("\n") 233 if constants.LX_CONFIG_STACKDEPOT: 233 if constants.LX_CONFIG_STACKDEPOT: 234 if loc['handle']: 234 if loc['handle']: 235 stackdepot.stack_depot_print(l 235 stackdepot.stack_depot_print(loc['handle']) 236 gdb.write("\n") 236 gdb.write("\n") 237 237 238 def help(): 238 def help(): 239 t = """Usage: lx-slabtrace --cache_name [c 239 t = """Usage: lx-slabtrace --cache_name [cache_name] [Options] 240 Options: 240 Options: 241 --alloc 241 --alloc 242 print information of allocation tr 242 print information of allocation trace of the allocated objects 243 --free 243 --free 244 print information of freeing trace 244 print information of freeing trace of the allocated objects 245 Example: 245 Example: 246 lx-slabtrace --cache_name kmalloc-1k - 246 lx-slabtrace --cache_name kmalloc-1k --alloc 247 lx-slabtrace --cache_name kmalloc-1k - 247 lx-slabtrace --cache_name kmalloc-1k --free\n""" 248 gdb.write("Unrecognized command\n") 248 gdb.write("Unrecognized command\n") 249 raise gdb.GdbError(t) 249 raise gdb.GdbError(t) 250 250 251 class LxSlabTrace(gdb.Command): 251 class LxSlabTrace(gdb.Command): 252 """Show specific cache slabtrace""" 252 """Show specific cache slabtrace""" 253 253 254 def __init__(self): 254 def __init__(self): 255 super(LxSlabTrace, self).__init__("lx- 255 super(LxSlabTrace, self).__init__("lx-slabtrace", gdb.COMMAND_DATA) 256 256 257 def invoke(self, arg, from_tty): 257 def invoke(self, arg, from_tty): 258 if not constants.LX_CONFIG_SLUB_DEBUG: 258 if not constants.LX_CONFIG_SLUB_DEBUG: 259 raise gdb.GdbError("CONFIG_SLUB_DE 259 raise gdb.GdbError("CONFIG_SLUB_DEBUG is not enabled") 260 260 261 argv = gdb.string_to_argv(arg) 261 argv = gdb.string_to_argv(arg) 262 alloc = track_alloc # default show all 262 alloc = track_alloc # default show alloc_traces 263 263 264 if len(argv) == 3: 264 if len(argv) == 3: 265 if argv[2] == '--alloc': 265 if argv[2] == '--alloc': 266 alloc = track_alloc 266 alloc = track_alloc 267 elif argv[2] == '--free': 267 elif argv[2] == '--free': 268 alloc = track_free 268 alloc = track_free 269 else: 269 else: 270 help() 270 help() 271 if len(argv) >= 2 and argv[0] == '--ca 271 if len(argv) >= 2 and argv[0] == '--cache_name': 272 slabtrace(alloc, argv[1]) 272 slabtrace(alloc, argv[1]) 273 else: 273 else: 274 help() 274 help() 275 LxSlabTrace() 275 LxSlabTrace() 276 276 277 def slabinfo(): 277 def slabinfo(): 278 nr_node_ids = None 278 nr_node_ids = None 279 279 280 if not constants.LX_CONFIG_SLUB_DEBUG: 280 if not constants.LX_CONFIG_SLUB_DEBUG: 281 raise gdb.GdbError("CONFIG_SLUB_DEBUG 281 raise gdb.GdbError("CONFIG_SLUB_DEBUG is not enabled") 282 282 283 def count_free(slab): 283 def count_free(slab): 284 total_free = 0 284 total_free = 0 285 for slab in lists.list_for_each_entry( 285 for slab in lists.list_for_each_entry(slab, slab_ptr_type, 'slab_list'): 286 total_free += int(slab['objects'] 286 total_free += int(slab['objects'] - slab['inuse']) 287 return total_free 287 return total_free 288 288 289 gdb.write("{:^18} | {:^20} | {:^12} | {:^1 289 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} | { 290 gdb.write("{:-^18} | {:-^20} | {:-^12} | {:-^12} | {:-^8} | {:-^11} | {:-^13}\n".format('', '', '', '', '', '', '')) 291 291 292 slab_caches = gdb.parse_and_eval("slab_cac 292 slab_caches = gdb.parse_and_eval("slab_caches") 293 if mm.page_ops().ops.MAX_NUMNODES > 1: 293 if mm.page_ops().ops.MAX_NUMNODES > 1: 294 nr_node_ids = int(gdb.parse_and_eval(" 294 nr_node_ids = int(gdb.parse_and_eval("nr_node_ids")) 295 else: 295 else: 296 nr_node_ids = 1 296 nr_node_ids = 1 297 297 298 for cache in lists.list_for_each_entry(sla 298 for cache in lists.list_for_each_entry(slab_caches, kmem_cache_ptr_type, 'list'): 299 nr_objs = 0 299 nr_objs = 0 300 nr_free = 0 300 nr_free = 0 301 nr_slabs = 0 301 nr_slabs = 0 302 for i in range(0, nr_node_ids): 302 for i in range(0, nr_node_ids): 303 cache_node = cache['node'][i] 303 cache_node = cache['node'][i] 304 try: 304 try: 305 nr_slabs += cache_node['nr_sla 305 nr_slabs += cache_node['nr_slabs']['counter'] 306 nr_objs = int(cache_node['tota 306 nr_objs = int(cache_node['total_objects']['counter']) 307 nr_free = count_free(cache_nod 307 nr_free = count_free(cache_node['partial']) 308 except: 308 except: 309 raise gdb.GdbError(traceback.f 309 raise gdb.GdbError(traceback.format_exc()) 310 active_objs = nr_objs - nr_free 310 active_objs = nr_objs - nr_free 311 num_objs = nr_objs 311 num_objs = nr_objs 312 active_slabs = nr_slabs 312 active_slabs = nr_slabs 313 objects_per_slab = oo_objects(cache['o 313 objects_per_slab = oo_objects(cache['oo']) 314 cache_order = oo_order(cache['oo']) 314 cache_order = oo_order(cache['oo']) 315 gdb.write("{:18s} | {:20.19s} | {:12} 315 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 316 317 class LxSlabInfo(gdb.Command): 317 class LxSlabInfo(gdb.Command): 318 """Show slabinfo""" 318 """Show slabinfo""" 319 319 320 def __init__(self): 320 def __init__(self): 321 super(LxSlabInfo, self).__init__("lx-s 321 super(LxSlabInfo, self).__init__("lx-slabinfo", gdb.COMMAND_DATA) 322 322 323 def invoke(self, arg, from_tty): 323 def invoke(self, arg, from_tty): 324 slabinfo() 324 slabinfo() 325 LxSlabInfo() 325 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.