Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) #!/usr/bin/env drgn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) # Copyright (C) 2020 Roman Gushchin <guro@fb.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) # Copyright (C) 2020 Facebook
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) from os import stat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) import argparse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) import sys
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) from drgn.helpers.linux import list_for_each_entry, list_empty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) from drgn.helpers.linux import for_each_page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) from drgn.helpers.linux.cpumask import for_each_online_cpu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) from drgn.helpers.linux.percpu import per_cpu_ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) from drgn import container_of, FaultError, Object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) DESC = """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) This is a drgn script to provide slab statistics for memory cgroups.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) It supports cgroup v2 and v1 and can emulate memory.kmem.slabinfo
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) interface of cgroup v1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) For drgn, visit https://github.com/osandov/drgn.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) MEMCGS = {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) OO_SHIFT = 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) OO_MASK = ((1 << OO_SHIFT) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) def err(s):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)     print('slabinfo.py: error: %s' % s, file=sys.stderr, flush=True)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)     sys.exit(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) def find_memcg_ids(css=prog['root_mem_cgroup'].css, prefix=''):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)     if not list_empty(css.children.address_of_()):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)         for css in list_for_each_entry('struct cgroup_subsys_state',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)                                        css.children.address_of_(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)                                        'sibling'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)             name = prefix + '/' + css.cgroup.kn.name.string_().decode('utf-8')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)             memcg = container_of(css, 'struct mem_cgroup', 'css')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43)             MEMCGS[css.cgroup.kn.id.value_()] = memcg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44)             find_memcg_ids(css, name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) def is_root_cache(s):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)     try:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)         return False if s.memcg_params.root_cache else True
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)     except AttributeError:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)         return True
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) def cache_name(s):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)     if is_root_cache(s):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)         return s.name.string_().decode('utf-8')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)     else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)         return s.memcg_params.root_cache.name.string_().decode('utf-8')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) # SLUB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) def oo_order(s):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)     return s.oo.x >> OO_SHIFT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) def oo_objects(s):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)     return s.oo.x & OO_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) def count_partial(n, fn):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)     nr_pages = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)     for page in list_for_each_entry('struct page', n.partial.address_of_(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)                                     'lru'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)          nr_pages += fn(page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)     return nr_pages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) def count_free(page):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)     return page.objects - page.inuse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) def slub_get_slabinfo(s, cfg):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)     nr_slabs = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)     nr_objs = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)     nr_free = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)     for node in range(cfg['nr_nodes']):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)         n = s.node[node]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)         nr_slabs += n.nr_slabs.counter.value_()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)         nr_objs += n.total_objects.counter.value_()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)         nr_free += count_partial(n, count_free)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)     return {'active_objs': nr_objs - nr_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)             'num_objs': nr_objs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)             'active_slabs': nr_slabs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)             'num_slabs': nr_slabs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)             'objects_per_slab': oo_objects(s),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)             'cache_order': oo_order(s),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)             'limit': 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)             'batchcount': 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)             'shared': 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)             'shared_avail': 0}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) def cache_show(s, cfg, objs):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)     if cfg['allocator'] == 'SLUB':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)         sinfo = slub_get_slabinfo(s, cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)     else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)         err('SLAB isn\'t supported yet')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)     if cfg['shared_slab_pages']:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)         sinfo['active_objs'] = objs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)         sinfo['num_objs'] = objs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)     print('%-17s %6lu %6lu %6u %4u %4d'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)           ' : tunables %4u %4u %4u'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)           ' : slabdata %6lu %6lu %6lu' % (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)               cache_name(s), sinfo['active_objs'], sinfo['num_objs'],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)               s.size, sinfo['objects_per_slab'], 1 << sinfo['cache_order'],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)               sinfo['limit'], sinfo['batchcount'], sinfo['shared'],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)               sinfo['active_slabs'], sinfo['num_slabs'],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)               sinfo['shared_avail']))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) def detect_kernel_config():
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)     cfg = {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)     cfg['nr_nodes'] = prog['nr_online_nodes'].value_()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)     if prog.type('struct kmem_cache').members[1].name == 'flags':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)         cfg['allocator'] = 'SLUB'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)     elif prog.type('struct kmem_cache').members[1].name == 'batchcount':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)         cfg['allocator'] = 'SLAB'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)     else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)         err('Can\'t determine the slab allocator')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)     cfg['shared_slab_pages'] = False
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)     try:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)         if prog.type('struct obj_cgroup'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)             cfg['shared_slab_pages'] = True
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)     except:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)         pass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)     return cfg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) def for_each_slab_page(prog):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)     PGSlab = 1 << prog.constant('PG_slab')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)     PGHead = 1 << prog.constant('PG_head')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)     for page in for_each_page(prog):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)         try:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)             if page.flags.value_() & PGSlab:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)                 yield page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)         except FaultError:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)             pass
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) def main():
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)     parser = argparse.ArgumentParser(description=DESC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)                                      formatter_class=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)                                      argparse.RawTextHelpFormatter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)     parser.add_argument('cgroup', metavar='CGROUP',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)                         help='Target memory cgroup')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)     args = parser.parse_args()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)     try:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)         cgroup_id = stat(args.cgroup).st_ino
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)         find_memcg_ids()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)         memcg = MEMCGS[cgroup_id]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)     except KeyError:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)         err('Can\'t find the memory cgroup')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)     cfg = detect_kernel_config()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)     print('# name            <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab>'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)           ' : tunables <limit> <batchcount> <sharedfactor>'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)           ' : slabdata <active_slabs> <num_slabs> <sharedavail>')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)     if cfg['shared_slab_pages']:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)         obj_cgroups = set()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)         stats = {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)         caches = {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)         # find memcg pointers belonging to the specified cgroup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)         obj_cgroups.add(memcg.objcg.value_())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)         for ptr in list_for_each_entry('struct obj_cgroup',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)                                        memcg.objcg_list.address_of_(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)                                        'list'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)             obj_cgroups.add(ptr.value_())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)         # look over all slab pages, belonging to non-root memcgs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)         # and look for objects belonging to the given memory cgroup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)         for page in for_each_slab_page(prog):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)             objcg_vec_raw = page.memcg_data.value_()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)             if objcg_vec_raw == 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)                 continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)             cache = page.slab_cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)             if not cache:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)                 continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)             addr = cache.value_()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)             caches[addr] = cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)             # clear the lowest bit to get the true obj_cgroups
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)             objcg_vec = Object(prog, 'struct obj_cgroup **',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)                                value=objcg_vec_raw & ~1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)             if addr not in stats:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)                 stats[addr] = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)             for i in range(oo_objects(cache)):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)                 if objcg_vec[i].value_() in obj_cgroups:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)                     stats[addr] += 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)         for addr in caches:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)             if stats[addr] > 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)                 cache_show(caches[addr], cfg, stats[addr])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)     else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)         for s in list_for_each_entry('struct kmem_cache',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)                                      memcg.kmem_caches.address_of_(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)                                      'memcg_params.kmem_caches_node'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)             cache_show(s, cfg, None)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) main()