Print out per-node nr/max_active numbers to improve visibility into node_nr_active operations.
Unified · Split
| @@ -50,6 +50,7 @@ import drgn · 49 unmodified lines | |||
| 50 | from drgn.helpers.linux.list import list_for_each_entry,list_empty | 50 | from drgn.helpers.linux.list import list_for_each_entry,list_empty |
| 51 | from drgn.helpers.linux.percpu import per_cpu_ptr | 51 | from drgn.helpers.linux.percpu import per_cpu_ptr |
| 52 | from drgn.helpers.linux.cpumask import for_each_cpu,for_each_possible_cpu | 52 | from drgn.helpers.linux.cpumask import for_each_cpu,for_each_possible_cpu |
| 53 | from drgn.helpers.linux.nodemask import for_each_node | ||
| 53 | from drgn.helpers.linux.idr import idr_for_each | 54 | from drgn.helpers.linux.idr import idr_for_each |
| 54 | 55 | ||
| 55 | import argparse | 56 | import argparse |
| @@ -107,7 +108,6 @@ WQ_AFFN_NUMA = prog['WQ_AFFN_NUMA'] · 51 unmodified lines | |||
| 107 | WQ_AFFN_SYSTEM = prog['WQ_AFFN_SYSTEM'] | 108 | WQ_AFFN_SYSTEM = prog['WQ_AFFN_SYSTEM'] |
| 108 | 109 | ||
| 109 | WQ_NAME_LEN = prog['WQ_NAME_LEN'].value_() | 110 | WQ_NAME_LEN = prog['WQ_NAME_LEN'].value_() |
| 110 | |||
| 111 | cpumask_str_len = len(cpumask_str(wq_unbound_cpumask)) | 111 | cpumask_str_len = len(cpumask_str(wq_unbound_cpumask)) |
| 112 | 112 | ||
| 113 | print('Affinity Scopes') | 113 | print('Affinity Scopes') |
| @@ -205,3 +205,42 @@ for wq in list_for_each_entry('struct workqueue_struct', workqueues.address_of_( · 91 unmodified lines | |||
| 205 | print(f' {wq.rescuer.task.pid.value_():6}', end='') | 205 | print(f' {wq.rescuer.task.pid.value_():6}', end='') |
| 206 | print(f' {cpumask_str(wq.rescuer.task.cpus_ptr):{rcpus_len}}', end='') | 206 | print(f' {cpumask_str(wq.rescuer.task.cpus_ptr):{rcpus_len}}', end='') |
| 207 | print('') | 207 | print('') |
| 208 | |||
| 209 | print('') | ||
| 210 | print('Unbound workqueue -> node_nr/max_active') | ||
| 211 | print('=======================================') | ||
| 212 | |||
| 213 | if 'node_to_cpumask_map' in prog: | ||
| 214 | __cpu_online_mask = prog['__cpu_online_mask'] | ||
| 215 | node_to_cpumask_map = prog['node_to_cpumask_map'] | ||
| 216 | nr_node_ids = prog['nr_node_ids'].value_() | ||
| 217 | |||
| 218 | print(f'online_cpus={cpumask_str(__cpu_online_mask.address_of_())}') | ||
| 219 | for node in for_each_node(): | ||
| 220 | print(f'NODE[{node:02}]={cpumask_str(node_to_cpumask_map[node])}') | ||
| 221 | print('') | ||
| 222 | |||
| 223 | print(f'[{"workqueue":^{WQ_NAME_LEN-2}}\\ min max', end='') | ||
| 224 | first = True | ||
| 225 | for node in for_each_node(): | ||
| 226 | if first: | ||
| 227 | print(f' NODE {node}', end='') | ||
| 228 | first = False | ||
| 229 | else: | ||
| 230 | print(f' {node:7}', end='') | ||
| 231 | print(f' {"dfl":>7} ]') | ||
| 232 | print('') | ||
| 233 | |||
| 234 | for wq in list_for_each_entry('struct workqueue_struct', workqueues.address_of_(), 'list'): | ||
| 235 | if not (wq.flags & WQ_UNBOUND): | ||
| 236 | continue | ||
| 237 | |||
| 238 | print(f'{wq.name.string_().decode():{WQ_NAME_LEN}} ', end='') | ||
| 239 | print(f'{wq.min_active.value_():3} {wq.max_active.value_():3}', end='') | ||
| 240 | for node in for_each_node(): | ||
| 241 | nna = wq.node_nr_active[node] | ||
| 242 | print(f' {nna.nr.counter.value_():3}/{nna.max.value_():3}', end='') | ||
| 243 | nna = wq.node_nr_active[nr_node_ids] | ||
| 244 | print(f' {nna.nr.counter.value_():3}/{nna.max.value_():3}') | ||
| 245 | else: | ||
| 246 | printf(f'node_to_cpumask_map not present, is NUMA enabled?') | ||