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

TOMOYO Linux Cross Reference
Linux/tools/writeback/wb_monitor.py

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ 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.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /tools/writeback/wb_monitor.py (Architecture sparc64) and /tools/writeback/wb_monitor.py (Architecture m68k)


  1 #!/usr/bin/env drgn                                 1 #!/usr/bin/env drgn
  2 #                                                   2 #
  3 # Copyright (C) 2024 Kemeng Shi <shikemeng@huaw      3 # Copyright (C) 2024 Kemeng Shi <shikemeng@huaweicloud.com>
  4 # Copyright (C) 2024 Huawei Inc                     4 # Copyright (C) 2024 Huawei Inc
  5                                                     5 
  6 desc = """                                          6 desc = """
  7 This is a drgn script based on wq_monitor.py t      7 This is a drgn script based on wq_monitor.py to monitor writeback info on
  8 backing dev. For more info on drgn, visit http      8 backing dev. For more info on drgn, visit https://github.com/osandov/drgn.
  9                                                     9 
 10   writeback(kB)     Amount of dirty pages are      10   writeback(kB)     Amount of dirty pages are currently being written back to
 11                     disk.                          11                     disk.
 12                                                    12 
 13   reclaimable(kB)   Amount of pages are curren     13   reclaimable(kB)   Amount of pages are currently reclaimable.
 14                                                    14 
 15   dirtied(kB)       Amount of pages have been      15   dirtied(kB)       Amount of pages have been dirtied.
 16                                                    16 
 17   wrttien(kB)       Amount of dirty pages have     17   wrttien(kB)       Amount of dirty pages have been written back to disk.
 18                                                    18 
 19   avg_wb(kBps)      Smoothly estimated write b     19   avg_wb(kBps)      Smoothly estimated write bandwidth of writing dirty pages
 20                     back to disk.                  20                     back to disk.
 21 """                                                21 """
 22                                                    22 
 23 import signal                                      23 import signal
 24 import re                                          24 import re
 25 import time                                        25 import time
 26 import json                                        26 import json
 27                                                    27 
 28 import drgn                                        28 import drgn
 29 from drgn.helpers.linux.list import list_for_e     29 from drgn.helpers.linux.list import list_for_each_entry
 30                                                    30 
 31 import argparse                                    31 import argparse
 32 parser = argparse.ArgumentParser(description=d     32 parser = argparse.ArgumentParser(description=desc,
 33                                  formatter_cla     33                                  formatter_class=argparse.RawTextHelpFormatter)
 34 parser.add_argument('bdi', metavar='REGEX', na     34 parser.add_argument('bdi', metavar='REGEX', nargs='*',
 35                     help='Target backing devic     35                     help='Target backing device name patterns (all if empty)')
 36 parser.add_argument('-i', '--interval', metava     36 parser.add_argument('-i', '--interval', metavar='SECS', type=float, default=1,
 37                     help='Monitoring interval      37                     help='Monitoring interval (0 to print once and exit)')
 38 parser.add_argument('-j', '--json', action='st     38 parser.add_argument('-j', '--json', action='store_true',
 39                     help='Output in json')         39                     help='Output in json')
 40 parser.add_argument('-c', '--cgroup', action='     40 parser.add_argument('-c', '--cgroup', action='store_true',
 41                     help='show writeback of bd     41                     help='show writeback of bdi in cgroup')
 42 args = parser.parse_args()                         42 args = parser.parse_args()
 43                                                    43 
 44 bdi_list                = prog['bdi_list']         44 bdi_list                = prog['bdi_list']
 45                                                    45 
 46 WB_RECLAIMABLE          = prog['WB_RECLAIMABLE     46 WB_RECLAIMABLE          = prog['WB_RECLAIMABLE']
 47 WB_WRITEBACK            = prog['WB_WRITEBACK']     47 WB_WRITEBACK            = prog['WB_WRITEBACK']
 48 WB_DIRTIED              = prog['WB_DIRTIED']       48 WB_DIRTIED              = prog['WB_DIRTIED']
 49 WB_WRITTEN              = prog['WB_WRITTEN']       49 WB_WRITTEN              = prog['WB_WRITTEN']
 50 NR_WB_STAT_ITEMS        = prog['NR_WB_STAT_ITE     50 NR_WB_STAT_ITEMS        = prog['NR_WB_STAT_ITEMS']
 51                                                    51 
 52 PAGE_SHIFT              = prog['PAGE_SHIFT']       52 PAGE_SHIFT              = prog['PAGE_SHIFT']
 53                                                    53 
 54 def K(x):                                          54 def K(x):
 55     return x << (PAGE_SHIFT - 10)                  55     return x << (PAGE_SHIFT - 10)
 56                                                    56 
 57 class Stats:                                       57 class Stats:
 58     def dict(self, now):                           58     def dict(self, now):
 59         return { 'timestamp'            : now,     59         return { 'timestamp'            : now,
 60                  'name'                 : self     60                  'name'                 : self.name,
 61                  'writeback'            : self     61                  'writeback'            : self.stats[WB_WRITEBACK],
 62                  'reclaimable'          : self     62                  'reclaimable'          : self.stats[WB_RECLAIMABLE],
 63                  'dirtied'              : self     63                  'dirtied'              : self.stats[WB_DIRTIED],
 64                  'written'              : self     64                  'written'              : self.stats[WB_WRITTEN],
 65                  'avg_wb'               : self     65                  'avg_wb'               : self.avg_bw, }
 66                                                    66 
 67     def table_header_str():                        67     def table_header_str():
 68         return f'{"":>16} {"writeback":>10} {"     68         return f'{"":>16} {"writeback":>10} {"reclaimable":>12} ' \
 69                 f'{"dirtied":>9} {"written":>9     69                 f'{"dirtied":>9} {"written":>9} {"avg_bw":>9}'
 70                                                    70 
 71     def table_row_str(self):                       71     def table_row_str(self):
 72         out = f'{self.name[-16:]:16} ' \           72         out = f'{self.name[-16:]:16} ' \
 73               f'{self.stats[WB_WRITEBACK]:10}      73               f'{self.stats[WB_WRITEBACK]:10} ' \
 74               f'{self.stats[WB_RECLAIMABLE]:12     74               f'{self.stats[WB_RECLAIMABLE]:12} ' \
 75               f'{self.stats[WB_DIRTIED]:9} ' \     75               f'{self.stats[WB_DIRTIED]:9} ' \
 76               f'{self.stats[WB_WRITTEN]:9} ' \     76               f'{self.stats[WB_WRITTEN]:9} ' \
 77               f'{self.avg_bw:9} '                  77               f'{self.avg_bw:9} '
 78         return out                                 78         return out
 79                                                    79 
 80     def show_header():                             80     def show_header():
 81         if Stats.table_fmt:                        81         if Stats.table_fmt:
 82             print()                                82             print()
 83             print(Stats.table_header_str())        83             print(Stats.table_header_str())
 84                                                    84 
 85     def show_stats(self):                          85     def show_stats(self):
 86         if Stats.table_fmt:                        86         if Stats.table_fmt:
 87             print(self.table_row_str())            87             print(self.table_row_str())
 88         else:                                      88         else:
 89             print(self.dict(Stats.now))            89             print(self.dict(Stats.now))
 90                                                    90 
 91 class WbStats(Stats):                              91 class WbStats(Stats):
 92     def __init__(self, wb):                        92     def __init__(self, wb):
 93         bdi_name = wb.bdi.dev_name.string_().d     93         bdi_name = wb.bdi.dev_name.string_().decode()
 94         # avoid to use bdi.wb.memcg_css which      94         # avoid to use bdi.wb.memcg_css which is only defined when
 95         # CONFIG_CGROUP_WRITEBACK is enabled       95         # CONFIG_CGROUP_WRITEBACK is enabled
 96         if wb == wb.bdi.wb.address_of_():          96         if wb == wb.bdi.wb.address_of_():
 97             ino = "1"                              97             ino = "1"
 98         else:                                      98         else:
 99             ino = str(wb.memcg_css.cgroup.kn.i     99             ino = str(wb.memcg_css.cgroup.kn.id.value_())
100         self.name = bdi_name + '_' + ino          100         self.name = bdi_name + '_' + ino
101                                                   101 
102         self.stats = [0] * NR_WB_STAT_ITEMS       102         self.stats = [0] * NR_WB_STAT_ITEMS
103         for i in range(NR_WB_STAT_ITEMS):         103         for i in range(NR_WB_STAT_ITEMS):
104             if wb.stat[i].count >= 0:             104             if wb.stat[i].count >= 0:
105                 self.stats[i] = int(K(wb.stat[    105                 self.stats[i] = int(K(wb.stat[i].count))
106             else:                                 106             else:
107                 self.stats[i] = 0                 107                 self.stats[i] = 0
108                                                   108 
109         self.avg_bw = int(K(wb.avg_write_bandw    109         self.avg_bw = int(K(wb.avg_write_bandwidth))
110                                                   110 
111 class BdiStats(Stats):                            111 class BdiStats(Stats):
112     def __init__(self, bdi):                      112     def __init__(self, bdi):
113         self.name = bdi.dev_name.string_().dec    113         self.name = bdi.dev_name.string_().decode()
114         self.stats = [0] * NR_WB_STAT_ITEMS       114         self.stats = [0] * NR_WB_STAT_ITEMS
115         self.avg_bw = 0                           115         self.avg_bw = 0
116                                                   116 
117     def collectStats(self, wb_stats):             117     def collectStats(self, wb_stats):
118         for i in range(NR_WB_STAT_ITEMS):         118         for i in range(NR_WB_STAT_ITEMS):
119             self.stats[i] += wb_stats.stats[i]    119             self.stats[i] += wb_stats.stats[i]
120                                                   120 
121         self.avg_bw += wb_stats.avg_bw            121         self.avg_bw += wb_stats.avg_bw
122                                                   122 
123 exit_req = False                                  123 exit_req = False
124                                                   124 
125 def sigint_handler(signr, frame):                 125 def sigint_handler(signr, frame):
126     global exit_req                               126     global exit_req
127     exit_req = True                               127     exit_req = True
128                                                   128 
129 def main():                                       129 def main():
130     # handle args                                 130     # handle args
131     Stats.table_fmt = not args.json               131     Stats.table_fmt = not args.json
132     interval = args.interval                      132     interval = args.interval
133     cgroup = args.cgroup                          133     cgroup = args.cgroup
134                                                   134 
135     re_str = None                                 135     re_str = None
136     if args.bdi:                                  136     if args.bdi:
137         for r in args.bdi:                        137         for r in args.bdi:
138             if re_str is None:                    138             if re_str is None:
139                 re_str = r                        139                 re_str = r
140             else:                                 140             else:
141                 re_str += '|' + r                 141                 re_str += '|' + r
142                                                   142 
143     filter_re = re.compile(re_str) if re_str e    143     filter_re = re.compile(re_str) if re_str else None
144                                                   144 
145     # monitoring loop                             145     # monitoring loop
146     signal.signal(signal.SIGINT, sigint_handle    146     signal.signal(signal.SIGINT, sigint_handler)
147                                                   147 
148     while not exit_req:                           148     while not exit_req:
149         Stats.now = time.time()                   149         Stats.now = time.time()
150                                                   150 
151         Stats.show_header()                       151         Stats.show_header()
152         for bdi in list_for_each_entry('struct    152         for bdi in list_for_each_entry('struct backing_dev_info', bdi_list.address_of_(), 'bdi_list'):
153             bdi_stats = BdiStats(bdi)             153             bdi_stats = BdiStats(bdi)
154             if filter_re and not filter_re.sea    154             if filter_re and not filter_re.search(bdi_stats.name):
155                 continue                          155                 continue
156                                                   156 
157             for wb in list_for_each_entry('str    157             for wb in list_for_each_entry('struct bdi_writeback', bdi.wb_list.address_of_(), 'bdi_node'):
158                 wb_stats = WbStats(wb)            158                 wb_stats = WbStats(wb)
159                 bdi_stats.collectStats(wb_stat    159                 bdi_stats.collectStats(wb_stats)
160                 if cgroup:                        160                 if cgroup:
161                     wb_stats.show_stats()         161                     wb_stats.show_stats()
162                                                   162 
163             bdi_stats.show_stats()                163             bdi_stats.show_stats()
164             if cgroup and Stats.table_fmt:        164             if cgroup and Stats.table_fmt:
165                 print()                           165                 print()
166                                                   166 
167         if interval == 0:                         167         if interval == 0:
168             break                                 168             break
169         time.sleep(interval)                      169         time.sleep(interval)
170                                                   170 
171 if __name__ == "__main__":                        171 if __name__ == "__main__":
172     main()                                        172     main()
                                                      

~ [ 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