Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/testing/selftests/damon/drgn_dump_damon_status.py
51978 views
1
#!/usr/bin/env drgn
2
# SPDX-License-Identifier: GPL-2.0
3
4
'''
5
Read DAMON context data and dump as a json string.
6
'''
7
import drgn
8
from drgn import FaultError, NULL, Object, cast, container_of, execscript, offsetof, reinterpret, sizeof
9
from drgn.helpers.common import *
10
from drgn.helpers.linux import *
11
12
import json
13
import sys
14
15
if "prog" not in globals():
16
try:
17
prog = drgn.get_default_prog()
18
except drgn.NoDefaultProgramError:
19
prog = drgn.program_from_kernel()
20
drgn.set_default_prog(prog)
21
22
def to_dict(object, attr_name_converter):
23
d = {}
24
for attr_name, converter in attr_name_converter:
25
d[attr_name] = converter(getattr(object, attr_name))
26
return d
27
28
def ops_to_dict(ops):
29
return to_dict(ops, [
30
['id', int],
31
])
32
33
def intervals_goal_to_dict(goal):
34
return to_dict(goal, [
35
['access_bp', int],
36
['aggrs', int],
37
['min_sample_us', int],
38
['max_sample_us', int],
39
])
40
41
def attrs_to_dict(attrs):
42
return to_dict(attrs, [
43
['sample_interval', int],
44
['aggr_interval', int],
45
['ops_update_interval', int],
46
['intervals_goal', intervals_goal_to_dict],
47
['min_nr_regions', int],
48
['max_nr_regions', int],
49
])
50
51
def addr_range_to_dict(addr_range):
52
return to_dict(addr_range, [
53
['start', int],
54
['end', int],
55
])
56
57
def region_to_dict(region):
58
return to_dict(region, [
59
['ar', addr_range_to_dict],
60
['sampling_addr', int],
61
['nr_accesses', int],
62
['nr_accesses_bp', int],
63
['age', int],
64
])
65
66
def regions_to_list(regions):
67
return [region_to_dict(r)
68
for r in list_for_each_entry(
69
'struct damon_region', regions.address_of_(), 'list')]
70
71
def target_to_dict(target):
72
return to_dict(target, [
73
['pid', int],
74
['nr_regions', int],
75
['regions_list', regions_to_list],
76
['obsolete', bool],
77
])
78
79
def targets_to_list(targets):
80
return [target_to_dict(t)
81
for t in list_for_each_entry(
82
'struct damon_target', targets.address_of_(), 'list')]
83
84
def damos_access_pattern_to_dict(pattern):
85
return to_dict(pattern, [
86
['min_sz_region', int],
87
['max_sz_region', int],
88
['min_nr_accesses', int],
89
['max_nr_accesses', int],
90
['min_age_region', int],
91
['max_age_region', int],
92
])
93
94
def damos_quota_goal_to_dict(goal):
95
return to_dict(goal, [
96
['metric', int],
97
['target_value', int],
98
['current_value', int],
99
['last_psi_total', int],
100
['nid', int],
101
])
102
103
def damos_quota_goals_to_list(goals):
104
return [damos_quota_goal_to_dict(g)
105
for g in list_for_each_entry(
106
'struct damos_quota_goal', goals.address_of_(), 'list')]
107
108
def damos_quota_to_dict(quota):
109
return to_dict(quota, [
110
['reset_interval', int],
111
['ms', int], ['sz', int],
112
['goals', damos_quota_goals_to_list],
113
['esz', int],
114
['weight_sz', int],
115
['weight_nr_accesses', int],
116
['weight_age', int],
117
])
118
119
def damos_watermarks_to_dict(watermarks):
120
return to_dict(watermarks, [
121
['metric', int],
122
['interval', int],
123
['high', int], ['mid', int], ['low', int],
124
])
125
126
def damos_migrate_dests_to_dict(dests):
127
nr_dests = int(dests.nr_dests)
128
node_id_arr = []
129
weight_arr = []
130
for i in range(nr_dests):
131
node_id_arr.append(int(dests.node_id_arr[i]))
132
weight_arr.append(int(dests.weight_arr[i]))
133
return {
134
'node_id_arr': node_id_arr,
135
'weight_arr': weight_arr,
136
'nr_dests': nr_dests,
137
}
138
139
def damos_filter_to_dict(damos_filter):
140
filter_type_keyword = {
141
0: 'anon',
142
1: 'active',
143
2: 'memcg',
144
3: 'young',
145
4: 'hugepage_size',
146
5: 'unmapped',
147
6: 'addr',
148
7: 'target'
149
}
150
dict_ = {
151
'type': filter_type_keyword[int(damos_filter.type)],
152
'matching': bool(damos_filter.matching),
153
'allow': bool(damos_filter.allow),
154
}
155
type_ = dict_['type']
156
if type_ == 'memcg':
157
dict_['memcg_id'] = int(damos_filter.memcg_id)
158
elif type_ == 'addr':
159
dict_['addr_range'] = [int(damos_filter.addr_range.start),
160
int(damos_filter.addr_range.end)]
161
elif type_ == 'target':
162
dict_['target_idx'] = int(damos_filter.target_idx)
163
elif type_ == 'hugeapge_size':
164
dict_['sz_range'] = [int(damos_filter.sz_range.min),
165
int(damos_filter.sz_range.max)]
166
return dict_
167
168
def scheme_to_dict(scheme):
169
dict_ = to_dict(scheme, [
170
['pattern', damos_access_pattern_to_dict],
171
['action', int],
172
['apply_interval_us', int],
173
['quota', damos_quota_to_dict],
174
['wmarks', damos_watermarks_to_dict],
175
['target_nid', int],
176
['migrate_dests', damos_migrate_dests_to_dict],
177
])
178
core_filters = []
179
for f in list_for_each_entry(
180
'struct damos_filter', scheme.core_filters.address_of_(), 'list'):
181
core_filters.append(damos_filter_to_dict(f))
182
dict_['core_filters'] = core_filters
183
ops_filters = []
184
for f in list_for_each_entry(
185
'struct damos_filter', scheme.ops_filters.address_of_(), 'list'):
186
ops_filters.append(damos_filter_to_dict(f))
187
dict_['ops_filters'] = ops_filters
188
189
return dict_
190
191
def schemes_to_list(schemes):
192
return [scheme_to_dict(s)
193
for s in list_for_each_entry(
194
'struct damos', schemes.address_of_(), 'list')]
195
196
def damon_ctx_to_dict(ctx):
197
return to_dict(ctx, [
198
['ops', ops_to_dict],
199
['attrs', attrs_to_dict],
200
['adaptive_targets', targets_to_list],
201
['schemes', schemes_to_list],
202
])
203
204
def main():
205
if len(sys.argv) < 3:
206
print('Usage: %s <kdamond pid> <file>' % sys.argv[0])
207
exit(1)
208
209
pid = int(sys.argv[1])
210
file_to_store = sys.argv[2]
211
212
kthread_data = cast('struct kthread *',
213
find_task(prog, pid).worker_private).data
214
ctx = cast('struct damon_ctx *', kthread_data)
215
status = {'contexts': [damon_ctx_to_dict(ctx)]}
216
if file_to_store == 'stdout':
217
print(json.dumps(status, indent=4))
218
else:
219
with open(file_to_store, 'w') as f:
220
json.dump(status, f, indent=4)
221
222
if __name__ == '__main__':
223
main()
224
225