#!/usr/bin/env drgn
# SPDX-License-Identifier: GPL-2.0
'' '
Read DAMON context data and dump as a json string.
'' '
import drgn
from drgn import FaultError, NULL, Object, cast, container_of, execscript, offsetof, reinterpret, sizeof
from drgn.helpers.common import *
from drgn.helpers.linux import *
import json
import sys
if "prog" not in globals():
try :
prog = drgn.get_default_prog()
except drgn.NoDefaultProgramError:
prog = drgn.program_from_kernel()
drgn.set_default_prog(prog)
def to_dict(object, attr_name_converter):
d = {}
for attr_name, converter in attr_name_converter:
d[attr_name] = converter(getattr(object, attr_name))
return d
def ops_to_dict(ops):
return to_dict(ops, [
['id' , int],
])
def intervals_goal_to_dict(goal):
return to_dict(goal, [
['access_bp' , int],
['aggrs' , int],
['min_sample_us' , int],
['max_sample_us' , int],
])
def attrs_to_dict(attrs):
return to_dict(attrs, [
['sample_interval' , int],
['aggr_interval' , int],
['ops_update_interval' , int],
['intervals_goal' , intervals_goal_to_dict],
['min_nr_regions' , int],
['max_nr_regions' , int],
])
def addr_range_to_dict(addr_range):
return to_dict(addr_range, [
['start' , int],
['end' , int],
])
def region_to_dict(region):
return to_dict(region, [
['ar' , addr_range_to_dict],
['sampling_addr' , int],
['nr_accesses' , int],
['nr_accesses_bp' , int],
['age' , int],
])
def regions_to_list(regions):
return [region_to_dict(r)
for r in list_for_each_entry(
'struct damon_region' , regions.address_of_(), 'list' )]
def target_to_dict(target):
return to_dict(target, [
['pid' , int],
['nr_regions' , int],
['regions_list' , regions_to_list],
])
def targets_to_list(targets):
return [target_to_dict(t)
for t in list_for_each_entry(
'struct damon_target' , targets.address_of_(), 'list' )]
def damos_access_pattern_to_dict(pattern):
return to_dict(pattern, [
['min_sz_region' , int],
['max_sz_region' , int],
['min_nr_accesses' , int],
['max_nr_accesses' , int],
['min_age_region' , int],
['max_age_region' , int],
])
def damos_quota_goal_to_dict(goal):
return to_dict(goal, [
['metric' , int],
['target_value' , int],
['current_value' , int],
['last_psi_total' , int],
['nid' , int],
])
def damos_quota_goals_to_list(goals):
return [damos_quota_goal_to_dict(g)
for g in list_for_each_entry(
'struct damos_quota_goal' , goals.address_of_(), 'list' )]
def damos_quota_to_dict(quota):
return to_dict(quota, [
['reset_interval' , int],
['ms' , int], ['sz' , int],
['goals' , damos_quota_goals_to_list],
['esz' , int],
['weight_sz' , int],
['weight_nr_accesses' , int],
['weight_age' , int],
])
def damos_watermarks_to_dict(watermarks):
return to_dict(watermarks, [
['metric' , int],
['interval' , int],
['high' , int], ['mid' , int], ['low' , int],
])
def damos_migrate_dests_to_dict(dests):
nr_dests = int(dests.nr_dests)
node_id_arr = []
weight_arr = []
for i in range(nr_dests):
node_id_arr.append(int(dests.node_id_arr[i]))
weight_arr.append(int(dests.weight_arr[i]))
return {
'node_id_arr' : node_id_arr,
'weight_arr' : weight_arr,
'nr_dests' : nr_dests,
}
def damos_filter_to_dict(damos_filter):
filter_type_keyword = {
0: 'anon' ,
1: 'active' ,
2: 'memcg' ,
3: 'young' ,
4: 'hugepage_size' ,
5: 'unmapped' ,
6: 'addr' ,
7: 'target'
}
dict_ = {
'type' : filter_type_keyword[int(damos_filter.type)],
'matching' : bool(damos_filter.matching),
'allow' : bool(damos_filter.allow),
}
type_ = dict_['type' ]
if type_ == 'memcg' :
dict_['memcg_id' ] = int(damos_filter.memcg_id)
elif type_ == 'addr' :
dict_['addr_range' ] = [int(damos_filter.addr_range.start),
int(damos_filter.addr_range.end)]
elif type_ == 'target' :
dict_['target_idx' ] = int(damos_filter.target_idx)
elif type_ == 'hugeapge_size' :
dict_['sz_range' ] = [int(damos_filter.sz_range.min),
int(damos_filter.sz_range.max)]
return dict_
def scheme_to_dict(scheme):
dict_ = to_dict(scheme, [
['pattern' , damos_access_pattern_to_dict],
['action' , int],
['apply_interval_us' , int],
['quota' , damos_quota_to_dict],
['wmarks' , damos_watermarks_to_dict],
['target_nid' , int],
['migrate_dests' , damos_migrate_dests_to_dict],
])
filters = []
for f in list_for_each_entry(
'struct damos_filter' , scheme.filters.address_of_(), 'list' ):
filters.append(damos_filter_to_dict(f))
dict_['filters' ] = filters
ops_filters = []
for f in list_for_each_entry(
'struct damos_filter' , scheme.ops_filters.address_of_(), 'list' ):
ops_filters.append(damos_filter_to_dict(f))
dict_['ops_filters' ] = ops_filters
return dict_
def schemes_to_list(schemes):
return [scheme_to_dict(s)
for s in list_for_each_entry(
'struct damos' , schemes.address_of_(), 'list' )]
def damon_ctx_to_dict(ctx):
return to_dict(ctx, [
['ops' , ops_to_dict],
['attrs' , attrs_to_dict],
['adaptive_targets' , targets_to_list],
['schemes' , schemes_to_list],
])
def main():
if len(sys.argv) < 3:
print('Usage: %s ' % sys.argv[0])
exit(1)
pid = int(sys.argv[1])
file_to_store = sys.argv[2]
kthread_data = cast('struct kthread *' ,
find_task(prog, pid).worker_private).data
ctx = cast('struct damon_ctx *' , kthread_data)
status = {'contexts' : [damon_ctx_to_dict(ctx)]}
if file_to_store == 'stdout' :
print(json.dumps(status, indent=4))
else :
with open(file_to_store, 'w' ) as f:
json.dump(status, f, indent=4)
if __name__ == '__main__' :
main()
Messung V0.5 C=86 H=93 G=89
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet)
¤
*© Formatika GbR, Deutschland