damo 3.2.2__tar.gz → 3.2.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {damo-3.2.2 → damo-3.2.4}/PKG-INFO +5 -5
- {damo-3.2.2 → damo-3.2.4}/README.md +4 -4
- {damo-3.2.2 → damo-3.2.4}/src/damo/_damon.py +136 -24
- {damo-3.2.2 → damo-3.2.4}/src/damo/_damon_args.py +120 -4
- {damo-3.2.2 → damo-3.2.4}/src/damo/_damon_features.py +14 -3
- {damo-3.2.2 → damo-3.2.4}/src/damo/_damon_sysfs.py +109 -8
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_report_access.py +5 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_version.py +1 -1
- {damo-3.2.2 → damo-3.2.4}/src/damo.egg-info/PKG-INFO +5 -5
- {damo-3.2.2 → damo-3.2.4}/pyproject.toml +0 -0
- {damo-3.2.2 → damo-3.2.4}/setup.cfg +0 -0
- {damo-3.2.2 → damo-3.2.4}/setup.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/__init__.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/_damo_ascii_color.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/_damo_deprecated.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/_damo_deprecation_notice.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/_damo_dist.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/_damo_fmt_str.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/_damo_fs.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/_damo_print.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/_damo_records.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/_damo_subcmds.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/_damo_subproc.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/_damo_sysinfo.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/_damo_yaml.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/_damon_dbgfs.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/_damon_modules.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_adjust.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_args.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_args_accesses_filter.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_args_accesses_format.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_args_damon.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_convert_record_format.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_diagnose.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_features.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_help.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_help_access_filter_options.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_help_access_format_options.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_help_damon_param_options.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_lru_sort.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_module.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_module_general.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_module_stat.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_monitor.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_nr_regions.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_pa_layout.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_reclaim.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_record.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_record_info.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_replay.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_report.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_report_damon.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_report_footprint.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_report_heatmap.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_report_holistic.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_report_pa_layout.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_report_profile.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_report_record_info.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_report_sysinfo.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_report_times.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_report_trace.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_schemes.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_setup_cli_completion.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_start.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_stop.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_tune.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_validate.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo/damo_wss.py +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo.egg-info/SOURCES.txt +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo.egg-info/dependency_links.txt +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo.egg-info/entry_points.txt +0 -0
- {damo-3.2.2 → damo-3.2.4}/src/damo.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: damo
|
|
3
|
-
Version: 3.2.
|
|
3
|
+
Version: 3.2.4
|
|
4
4
|
Summary: DAMON user-space tool
|
|
5
5
|
Home-page: https://github.com/damonitor/damo
|
|
6
6
|
Author: SeongJae Park
|
|
@@ -71,7 +71,7 @@ The second and last commands will show the access pattern of your workload,
|
|
|
71
71
|
like below:
|
|
72
72
|
|
|
73
73
|

|
|
74
|
-

|
|
75
75
|
|
|
76
76
|
|
|
77
77
|
FAQs
|
|
@@ -90,7 +90,7 @@ Where can I get more detailed usage?
|
|
|
90
90
|
------------------------------------
|
|
91
91
|
|
|
92
92
|
The below sections provide quick introductions for `damo`'s major features.
|
|
93
|
-
For more detailed usage, please refer to [USAGE.md](https://github.com/damonitor/damo/blob/v3.2.
|
|
93
|
+
For more detailed usage, please refer to [USAGE.md](https://github.com/damonitor/damo/blob/v3.2.4/USAGE.md) file.
|
|
94
94
|
|
|
95
95
|
|
|
96
96
|
What does the version numbers mean?
|
|
@@ -115,7 +115,7 @@ We try our best to make `damo` stable and doesn't introduce regressions to
|
|
|
115
115
|
users. However, nothing goes forever. Sometimes, some features will be
|
|
116
116
|
deprecated. Some features will have longer support more than others.
|
|
117
117
|
|
|
118
|
-
In short, features that documented on [USAGE.md](https://github.com/damonitor/damo/blob/v3.2.
|
|
118
|
+
In short, features that documented on [USAGE.md](https://github.com/damonitor/damo/blob/v3.2.4/USAGE.md) and not explicitly
|
|
119
119
|
marked as experimental will be better supported, and provides at least three
|
|
120
120
|
months of deprecation grace period. Within the grace period, users can ask
|
|
121
121
|
extension of the support. Even after the grace period, please reach out to
|
|
@@ -138,7 +138,7 @@ Quick Intro for Major Features
|
|
|
138
138
|
==============================
|
|
139
139
|
|
|
140
140
|
Below are quick introductions for `damo`'s major features.
|
|
141
|
-
For more detailed usage, please refer to [USAGE.md](https://github.com/damonitor/damo/blob/v3.2.
|
|
141
|
+
For more detailed usage, please refer to [USAGE.md](https://github.com/damonitor/damo/blob/v3.2.4/USAGE.md) file.
|
|
142
142
|
|
|
143
143
|
|
|
144
144
|
Snapshot Data Access Pattern
|
|
@@ -47,7 +47,7 @@ The second and last commands will show the access pattern of your workload,
|
|
|
47
47
|
like below:
|
|
48
48
|
|
|
49
49
|

|
|
50
|
-

|
|
51
51
|
|
|
52
52
|
|
|
53
53
|
FAQs
|
|
@@ -66,7 +66,7 @@ Where can I get more detailed usage?
|
|
|
66
66
|
------------------------------------
|
|
67
67
|
|
|
68
68
|
The below sections provide quick introductions for `damo`'s major features.
|
|
69
|
-
For more detailed usage, please refer to [USAGE.md](https://github.com/damonitor/damo/blob/v3.2.
|
|
69
|
+
For more detailed usage, please refer to [USAGE.md](https://github.com/damonitor/damo/blob/v3.2.4/USAGE.md) file.
|
|
70
70
|
|
|
71
71
|
|
|
72
72
|
What does the version numbers mean?
|
|
@@ -91,7 +91,7 @@ We try our best to make `damo` stable and doesn't introduce regressions to
|
|
|
91
91
|
users. However, nothing goes forever. Sometimes, some features will be
|
|
92
92
|
deprecated. Some features will have longer support more than others.
|
|
93
93
|
|
|
94
|
-
In short, features that documented on [USAGE.md](https://github.com/damonitor/damo/blob/v3.2.
|
|
94
|
+
In short, features that documented on [USAGE.md](https://github.com/damonitor/damo/blob/v3.2.4/USAGE.md) and not explicitly
|
|
95
95
|
marked as experimental will be better supported, and provides at least three
|
|
96
96
|
months of deprecation grace period. Within the grace period, users can ask
|
|
97
97
|
extension of the support. Even after the grace period, please reach out to
|
|
@@ -114,7 +114,7 @@ Quick Intro for Major Features
|
|
|
114
114
|
==============================
|
|
115
115
|
|
|
116
116
|
Below are quick introductions for `damo`'s major features.
|
|
117
|
-
For more detailed usage, please refer to [USAGE.md](https://github.com/damonitor/damo/blob/v3.2.
|
|
117
|
+
For more detailed usage, please refer to [USAGE.md](https://github.com/damonitor/damo/blob/v3.2.4/USAGE.md) file.
|
|
118
118
|
|
|
119
119
|
|
|
120
120
|
Snapshot Data Access Pattern
|
|
@@ -16,6 +16,84 @@ import _damo_fmt_str
|
|
|
16
16
|
|
|
17
17
|
# Core data structures
|
|
18
18
|
|
|
19
|
+
class DamonFilter:
|
|
20
|
+
filter_type = None # anon, memcg
|
|
21
|
+
matching = None
|
|
22
|
+
allow = None
|
|
23
|
+
path = None
|
|
24
|
+
|
|
25
|
+
def __init__(self, filter_type, matching, allow=False, path=None):
|
|
26
|
+
self.filter_type = filter_type
|
|
27
|
+
self.matching = _damo_fmt_str.text_to_bool(matching)
|
|
28
|
+
self.allow = _damo_fmt_str.text_to_bool(allow)
|
|
29
|
+
self.path = path
|
|
30
|
+
|
|
31
|
+
def to_str(self, raw):
|
|
32
|
+
words = []
|
|
33
|
+
if self.allow:
|
|
34
|
+
words.append('allow')
|
|
35
|
+
else:
|
|
36
|
+
words.append('reject')
|
|
37
|
+
if self.matching is False:
|
|
38
|
+
words.append('non')
|
|
39
|
+
words.append(self.filter_type)
|
|
40
|
+
if self.filter_type in ['anon']:
|
|
41
|
+
return ' '.join(words)
|
|
42
|
+
if self.filter_type == 'memcg':
|
|
43
|
+
return ' '.join(words + [self.path])
|
|
44
|
+
|
|
45
|
+
def __str__(self):
|
|
46
|
+
return self.to_str(False)
|
|
47
|
+
|
|
48
|
+
def __eq__(self, other):
|
|
49
|
+
return type(self) == type(other) and \
|
|
50
|
+
self.filter_type == other.filter_type and \
|
|
51
|
+
self.matching == other.matching and \
|
|
52
|
+
self.allow == other.allow and self.path == other.path
|
|
53
|
+
|
|
54
|
+
@classmethod
|
|
55
|
+
def from_kvpairs(cls, kv):
|
|
56
|
+
return DamonFilter(
|
|
57
|
+
filter_type=kv['filter_type'], matching=kv['matching'],
|
|
58
|
+
allow=kv['allow'], path=kv['path'])
|
|
59
|
+
|
|
60
|
+
def to_kvpairs(self, raw=False):
|
|
61
|
+
return collections.OrderedDict([
|
|
62
|
+
('filter_type', self.filter_type),
|
|
63
|
+
('matching', self.matching),
|
|
64
|
+
('allow', self.allow),
|
|
65
|
+
('path', self.path),
|
|
66
|
+
])
|
|
67
|
+
|
|
68
|
+
class DamonProbe:
|
|
69
|
+
filters = None
|
|
70
|
+
|
|
71
|
+
def __init__(self, filters):
|
|
72
|
+
if type(filters) is not list:
|
|
73
|
+
raise Exception('filters for DamonProbe() is not a list')
|
|
74
|
+
self.filters = filters
|
|
75
|
+
|
|
76
|
+
def to_str(self, raw):
|
|
77
|
+
return ', '.join([f.to_str(raw) for f in self.filters])
|
|
78
|
+
|
|
79
|
+
def __str__(self):
|
|
80
|
+
return self.to_str(False)
|
|
81
|
+
|
|
82
|
+
def __eq__(self, other):
|
|
83
|
+
return type(self) == type(other) and \
|
|
84
|
+
self.filters == other.filters
|
|
85
|
+
|
|
86
|
+
@classmethod
|
|
87
|
+
def from_kvpairs(cls, kv):
|
|
88
|
+
return DamonProbe(filters=[
|
|
89
|
+
DamonFilter.from_kvpairs(filter_kv)
|
|
90
|
+
for filter_kv in kv['filters']])
|
|
91
|
+
|
|
92
|
+
def to_kvpairs(self, raw=False):
|
|
93
|
+
return collections.OrderedDict([
|
|
94
|
+
('filters', [f.to_kvpairs(raw) for f in self.filters]),
|
|
95
|
+
])
|
|
96
|
+
|
|
19
97
|
class OpsAttrs:
|
|
20
98
|
use_reports = None
|
|
21
99
|
write_only = None
|
|
@@ -449,12 +527,13 @@ class DamonRegion:
|
|
|
449
527
|
end = None
|
|
450
528
|
# nr_accesses and age could be None
|
|
451
529
|
nr_accesses = None
|
|
530
|
+
probe_hits = None # list of integers
|
|
452
531
|
age = None
|
|
453
532
|
sz_filter_passed = None
|
|
454
533
|
scheme = None # non-None if tried region
|
|
455
534
|
|
|
456
535
|
def __init__(self, start, end, nr_accesses=None, nr_accesses_unit=None,
|
|
457
|
-
age=None, age_unit=None, sz_filter_passed=0):
|
|
536
|
+
age=None, age_unit=None, sz_filter_passed=0, probe_hits=None):
|
|
458
537
|
self.start = _damo_fmt_str.text_to_bytes(start)
|
|
459
538
|
self.end = _damo_fmt_str.text_to_bytes(end)
|
|
460
539
|
|
|
@@ -463,6 +542,9 @@ class DamonRegion:
|
|
|
463
542
|
self.nr_accesses = DamonNrAccesses(nr_accesses, nr_accesses_unit)
|
|
464
543
|
self.age = DamonAge(age, age_unit)
|
|
465
544
|
self.sz_filter_passed = sz_filter_passed
|
|
545
|
+
if probe_hits is None:
|
|
546
|
+
probe_hits = []
|
|
547
|
+
self.probe_hits = probe_hits
|
|
466
548
|
|
|
467
549
|
def to_str(self, raw, intervals=None):
|
|
468
550
|
if self.nr_accesses == None:
|
|
@@ -482,6 +564,9 @@ class DamonRegion:
|
|
|
482
564
|
_damo_fmt_str.format_addr_range(self.start, self.end, raw),
|
|
483
565
|
self.nr_accesses.to_str(nr_accesses_unit, raw),
|
|
484
566
|
self.age.to_str(age_unit, raw))
|
|
567
|
+
if self.probe_hits:
|
|
568
|
+
str += ', probe_hits: %s' % ' '.join(
|
|
569
|
+
['%d' % h for h in self.probe_hits])
|
|
485
570
|
if self.sz_filter_passed is not None:
|
|
486
571
|
str += ', filter_passed: %s' % _damo_fmt_str.format_sz(
|
|
487
572
|
self.sz_filter_passed, raw)
|
|
@@ -505,6 +590,7 @@ class DamonRegion:
|
|
|
505
590
|
region = DamonRegion(kvpairs['start'], kvpairs['end'])
|
|
506
591
|
region.nr_accesses = DamonNrAccesses.from_kvpairs(
|
|
507
592
|
kvpairs['nr_accesses'])
|
|
593
|
+
region.probe_hits = kvpairs.get('probe_hits', [])
|
|
508
594
|
region.age = DamonAge.from_kvpairs(kvpairs['age'])
|
|
509
595
|
if 'sz_filter_passed' in kvpairs:
|
|
510
596
|
region.sz_filter_passed = _damo_fmt_str.text_to_bytes(
|
|
@@ -523,6 +609,7 @@ class DamonRegion:
|
|
|
523
609
|
('end', _damo_fmt_str.format_nr(self.end, raw)),
|
|
524
610
|
('nr_accesses', self.nr_accesses.to_kvpairs(raw)),
|
|
525
611
|
('age', self.age.to_kvpairs(raw)),
|
|
612
|
+
('probe_hits', self.probe_hits),
|
|
526
613
|
('sz_filter_passed', _damo_fmt_str.format_sz(
|
|
527
614
|
self.sz_filter_passed, raw)),
|
|
528
615
|
])
|
|
@@ -724,10 +811,13 @@ qgoal_node_memcg_used_bp = 'node_memcg_used_bp'
|
|
|
724
811
|
qgoal_node_memcg_free_bp = 'node_memcg_free_bp'
|
|
725
812
|
qgoal_active_mem_bp = 'active_mem_bp'
|
|
726
813
|
qgoal_inactive_mem_bp = 'inactive_mem_bp'
|
|
814
|
+
qgoal_node_eligible_mem_bp = 'node_eligible_mem_bp'
|
|
727
815
|
qgoal_metrics = [qgoal_user_input, qgoal_some_mem_psi_us,
|
|
728
816
|
qgoal_node_mem_used_bp, qgoal_node_mem_free_bp,
|
|
729
817
|
qgoal_node_memcg_used_bp, qgoal_node_memcg_free_bp,
|
|
730
|
-
qgoal_active_mem_bp, qgoal_inactive_mem_bp
|
|
818
|
+
qgoal_active_mem_bp, qgoal_inactive_mem_bp,
|
|
819
|
+
qgoal_node_eligible_mem_bp,
|
|
820
|
+
]
|
|
731
821
|
|
|
732
822
|
class DamosQuotaGoal:
|
|
733
823
|
metric = None
|
|
@@ -1193,30 +1283,33 @@ class DamosStats:
|
|
|
1193
1283
|
max_nr_snapshots=max_nr_snapshots)
|
|
1194
1284
|
|
|
1195
1285
|
# TODO: check support of pageout and lru_(de)prio
|
|
1286
|
+
|
|
1287
|
+
damos_action_willneed = 'willneed'
|
|
1288
|
+
damos_action_cold = 'cold'
|
|
1289
|
+
damos_action_pageout = 'pageout'
|
|
1290
|
+
damos_action_hugepage = 'hugepage'
|
|
1291
|
+
damos_action_collapse = 'collapse'
|
|
1292
|
+
damos_action_nohugepage = 'nohugepage'
|
|
1293
|
+
damos_action_lru_prio = 'lru_prio'
|
|
1294
|
+
damos_action_lru_deprio = 'lru_deprio'
|
|
1295
|
+
damos_action_migrate_hot = 'migrate_hot'
|
|
1296
|
+
damos_action_migrate_cold = 'migrate_cold'
|
|
1297
|
+
damos_action_stat = 'stat'
|
|
1298
|
+
|
|
1196
1299
|
damos_actions = [
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1300
|
+
damos_action_willneed,
|
|
1301
|
+
damos_action_cold,
|
|
1302
|
+
damos_action_pageout,
|
|
1303
|
+
damos_action_hugepage,
|
|
1304
|
+
damos_action_collapse,
|
|
1305
|
+
damos_action_nohugepage,
|
|
1306
|
+
damos_action_lru_prio,
|
|
1307
|
+
damos_action_lru_deprio,
|
|
1308
|
+
damos_action_migrate_hot,
|
|
1309
|
+
damos_action_migrate_cold,
|
|
1310
|
+
damos_action_stat,
|
|
1207
1311
|
]
|
|
1208
1312
|
|
|
1209
|
-
damos_action_willneed = damos_actions[0]
|
|
1210
|
-
damos_action_cold = damos_actions[1]
|
|
1211
|
-
damos_action_pageout = damos_actions[2]
|
|
1212
|
-
damos_action_hugepage = damos_actions[3]
|
|
1213
|
-
damos_action_nohugepage = damos_actions[4]
|
|
1214
|
-
damos_action_lru_prio = damos_actions[5]
|
|
1215
|
-
damos_action_lru_deprio = damos_actions[6]
|
|
1216
|
-
damos_action_migrate_hot = damos_actions[7]
|
|
1217
|
-
damos_action_migrate_cold = damos_actions[8]
|
|
1218
|
-
damos_action_stat = damos_actions[9]
|
|
1219
|
-
|
|
1220
1313
|
def is_damos_migrate_action(action):
|
|
1221
1314
|
if action == damos_action_migrate_hot or \
|
|
1222
1315
|
action == damos_action_migrate_cold:
|
|
@@ -1393,6 +1486,7 @@ class DamonCtx:
|
|
|
1393
1486
|
targets = None
|
|
1394
1487
|
intervals = None
|
|
1395
1488
|
nr_regions = None
|
|
1489
|
+
probes = None
|
|
1396
1490
|
sample_control = None
|
|
1397
1491
|
pause = None
|
|
1398
1492
|
schemes = None
|
|
@@ -1400,7 +1494,7 @@ class DamonCtx:
|
|
|
1400
1494
|
|
|
1401
1495
|
def __init__(self, ops='paddr', targets=None, intervals=None,
|
|
1402
1496
|
nr_regions=None, schemes=None, ops_attrs=None,
|
|
1403
|
-
sample_control=None, addr_unit=None, pause=None):
|
|
1497
|
+
sample_control=None, addr_unit=None, pause=None, probes=None):
|
|
1404
1498
|
self.ops = ops
|
|
1405
1499
|
self.ops_attrs = ops_attrs if ops_attrs is not None else OpsAttrs()
|
|
1406
1500
|
if addr_unit is None:
|
|
@@ -1414,6 +1508,9 @@ class DamonCtx:
|
|
|
1414
1508
|
if intervals is not None else DamonIntervals())
|
|
1415
1509
|
self.nr_regions = (nr_regions if nr_regions is not None
|
|
1416
1510
|
else DamonNrRegionsRange())
|
|
1511
|
+
if probes is None:
|
|
1512
|
+
probes = []
|
|
1513
|
+
self.probes = probes
|
|
1417
1514
|
if sample_control is None:
|
|
1418
1515
|
sample_control = DamonSampleControl()
|
|
1419
1516
|
self.sample_control = sample_control
|
|
@@ -1424,6 +1521,16 @@ class DamonCtx:
|
|
|
1424
1521
|
for scheme in self.schemes:
|
|
1425
1522
|
scheme.context = self
|
|
1426
1523
|
|
|
1524
|
+
def add_probes_str(self, lines, raw):
|
|
1525
|
+
if len(self.probes) == 0:
|
|
1526
|
+
return
|
|
1527
|
+
if len(self.probes) == 1:
|
|
1528
|
+
lines.append('probe %s' % self.probes[0].to_str(raw))
|
|
1529
|
+
return
|
|
1530
|
+
lines.append('probes')
|
|
1531
|
+
for idx, probe in enumerate(self.probes):
|
|
1532
|
+
lines.append('- %s' % probe.to_str(raw))
|
|
1533
|
+
|
|
1427
1534
|
def to_str(self, raw, params_only=False, omit_damos_tried_regions=False):
|
|
1428
1535
|
ops_line_tokens = ['ops: %s' % self.ops]
|
|
1429
1536
|
if self.ops_attrs.use_reports:
|
|
@@ -1437,6 +1544,7 @@ class DamonCtx:
|
|
|
1437
1544
|
'addr_unit %s' % _damo_fmt_str.format_sz_accurate(
|
|
1438
1545
|
self.addr_unit, raw))
|
|
1439
1546
|
lines = [' '.join(ops_line_tokens)]
|
|
1547
|
+
self.add_probes_str(lines, raw)
|
|
1440
1548
|
if self.pause is True:
|
|
1441
1549
|
lines.append('pause: True')
|
|
1442
1550
|
for idx, target in enumerate(self.targets):
|
|
@@ -1476,6 +1584,8 @@ class DamonCtx:
|
|
|
1476
1584
|
sample_control = DamonSampleControl()
|
|
1477
1585
|
addr_unit = kv.get('addr_unit', 1)
|
|
1478
1586
|
pause = _damo_fmt_str.text_to_bool(kv.get('pause', False))
|
|
1587
|
+
probes = [DamonProbe.from_kvpairs(probe_kv)
|
|
1588
|
+
for probe_kv in kv.get('probes', [])]
|
|
1479
1589
|
ctx = DamonCtx(
|
|
1480
1590
|
kv['ops'],
|
|
1481
1591
|
[DamonTarget.from_kvpairs(t) for t in kv['targets']],
|
|
@@ -1485,6 +1595,7 @@ class DamonCtx:
|
|
|
1485
1595
|
if 'nr_regions' in kv else DamonNrRegionsRange(),
|
|
1486
1596
|
[Damos.from_kvpairs(s) for s in kv['schemes']]
|
|
1487
1597
|
if 'schemes' in kv else [],
|
|
1598
|
+
probes=probes,
|
|
1488
1599
|
sample_control=sample_control,
|
|
1489
1600
|
addr_unit=addr_unit,
|
|
1490
1601
|
pause=pause)
|
|
@@ -1499,6 +1610,7 @@ class DamonCtx:
|
|
|
1499
1610
|
kv['intervals'] = self.intervals.to_kvpairs(raw)
|
|
1500
1611
|
if not omit_defaults or self.nr_regions != DamonNrRegionsRange():
|
|
1501
1612
|
kv['nr_regions'] = self.nr_regions.to_kvpairs(raw)
|
|
1613
|
+
kv['probes'] = [probe.to_kvpairs(raw) for probe in self.probes]
|
|
1502
1614
|
kv['sample_control'] = self.sample_control.to_kvpairs(raw)
|
|
1503
1615
|
kv['pause'] = self.pause
|
|
1504
1616
|
kv['schemes'] = [s.to_kvpairs(raw, omit_defaults, params_only)
|
|
@@ -641,8 +641,8 @@ def damon_ctx_for(args, idx):
|
|
|
641
641
|
|
|
642
642
|
def get_nr_ctxs(args):
|
|
643
643
|
candidates = []
|
|
644
|
-
for v in [args.ops, args.
|
|
645
|
-
args.maxr, args.monitoring_intervals,
|
|
644
|
+
for v in [args.ops, args.nr_probes, args.sample, args.aggr, args.updr,
|
|
645
|
+
args.minr, args.maxr, args.monitoring_intervals,
|
|
646
646
|
args.monitoring_intervals_goal,
|
|
647
647
|
args.monitoring_nr_regions_range]:
|
|
648
648
|
if v is not None:
|
|
@@ -752,6 +752,90 @@ def gen_assign_schemes(ctxs, args):
|
|
|
752
752
|
scheme_idx += nr
|
|
753
753
|
return None
|
|
754
754
|
|
|
755
|
+
def probe_filter_for(filter_arg_fields):
|
|
756
|
+
fields = filter_arg_fields
|
|
757
|
+
if len(fields) < 2:
|
|
758
|
+
return None, 'expected >=2 fields but %d' % len(fields)
|
|
759
|
+
if not fields[0] in ['allow', 'reject']:
|
|
760
|
+
return None, 'expected allow|reject but %s' % fields[0]
|
|
761
|
+
allow = fields[0] == 'allow'
|
|
762
|
+
fields = fields[1:]
|
|
763
|
+
matching = True
|
|
764
|
+
if fields[0] == 'non':
|
|
765
|
+
matching = False
|
|
766
|
+
fields = fields[1:]
|
|
767
|
+
if len(fields) < 1:
|
|
768
|
+
return None, 'filter type is not given'
|
|
769
|
+
filter_type = fields[0]
|
|
770
|
+
fields = fields[1:]
|
|
771
|
+
path = None
|
|
772
|
+
if filter_type == 'memcg':
|
|
773
|
+
if len(fields) < 1:
|
|
774
|
+
return None, 'memcg path is not given'
|
|
775
|
+
path = fields[0]
|
|
776
|
+
try:
|
|
777
|
+
filter = _damon.DamonFilter(filter_type=filter_type, matching=matching,
|
|
778
|
+
allow=allow, path=path)
|
|
779
|
+
except Exception as e:
|
|
780
|
+
return None, 'filter creation fail (%s)' % e
|
|
781
|
+
return filter, None
|
|
782
|
+
|
|
783
|
+
def probe_filters_for(filters_args):
|
|
784
|
+
filters = []
|
|
785
|
+
for filter_args in filters_args:
|
|
786
|
+
filter, err = probe_filter_for(filter_args)
|
|
787
|
+
if err is not None:
|
|
788
|
+
return None, err
|
|
789
|
+
filters.append(filter)
|
|
790
|
+
return filters, None
|
|
791
|
+
|
|
792
|
+
def probes_for(args):
|
|
793
|
+
filters, err = probe_filters_for(args.probe_filter)
|
|
794
|
+
if err is not None:
|
|
795
|
+
return None, err
|
|
796
|
+
if len(filters) == 0:
|
|
797
|
+
return [], None
|
|
798
|
+
probes = []
|
|
799
|
+
filter_idx = 0
|
|
800
|
+
if args.nr_probe_filters is None:
|
|
801
|
+
args.nr_probe_filters = [len(args.probe_filter)]
|
|
802
|
+
if sum(args.nr_probe_filters) != len(filters):
|
|
803
|
+
return None, \
|
|
804
|
+
'--nr_probe_filters mismatches --probe_filter (%d != %d)' % (
|
|
805
|
+
sum(args.nr_probe_filters), len(filters))
|
|
806
|
+
for nr in args.nr_probe_filters:
|
|
807
|
+
filters_for_probe = filters[filter_idx:filter_idx + nr]
|
|
808
|
+
try:
|
|
809
|
+
probe = _damon.DamonProbe(filters=filters_for_probe)
|
|
810
|
+
except Exception as e:
|
|
811
|
+
return None, 'probe creation fail (%s)' % e
|
|
812
|
+
probes.append(probe)
|
|
813
|
+
filter_idx += nr
|
|
814
|
+
return probes, None
|
|
815
|
+
|
|
816
|
+
def gen_assign_probes(ctxs, args):
|
|
817
|
+
probes, err = probes_for(args)
|
|
818
|
+
if err is not None:
|
|
819
|
+
return err
|
|
820
|
+
if args.nr_probes is None:
|
|
821
|
+
if len(ctxs) != 1 and len(probes) > 0:
|
|
822
|
+
return '--nr_probes is required'
|
|
823
|
+
args.nr_probes = [len(probes)]
|
|
824
|
+
args.nr_probes += [0] * (len(ctxs) - 1)
|
|
825
|
+
if sum(args.nr_probes) != len(probes):
|
|
826
|
+
return '--nr_probes mismatches number of probes (%d != %d)' % (
|
|
827
|
+
sum(args.nr_probes), len(probes))
|
|
828
|
+
if len(args.nr_probes) != len(ctxs):
|
|
829
|
+
return '--nr_probes mismatches number of contexts (%d != %d)' % (
|
|
830
|
+
len(args.nr_probes), len(ctxs))
|
|
831
|
+
ctx_idx = 0
|
|
832
|
+
probe_idx = 0
|
|
833
|
+
for nr in args.nr_probes:
|
|
834
|
+
ctxs[ctx_idx].probes = probes[probe_idx:probe_idx + nr]
|
|
835
|
+
ctx_idx += 1
|
|
836
|
+
probe_idx += nr
|
|
837
|
+
return None
|
|
838
|
+
|
|
755
839
|
def damon_ctxs_for(args):
|
|
756
840
|
fillup_none_ctx_args(args)
|
|
757
841
|
fillup_none_target_args(args)
|
|
@@ -770,6 +854,10 @@ def damon_ctxs_for(args):
|
|
|
770
854
|
if err is not None:
|
|
771
855
|
return None, err
|
|
772
856
|
|
|
857
|
+
err = gen_assign_probes(ctxs, args)
|
|
858
|
+
if err is not None:
|
|
859
|
+
return None, err
|
|
860
|
+
|
|
773
861
|
return ctxs, err
|
|
774
862
|
|
|
775
863
|
def kdamonds_from_json_arg(arg):
|
|
@@ -854,7 +942,7 @@ def deduce_target_update_args(args):
|
|
|
854
942
|
def warn_for(arg, feature):
|
|
855
943
|
if _damo_sysinfo.damon_feature_available(feature):
|
|
856
944
|
return
|
|
857
|
-
sys.stderr.write('%s is passed but %s DAMON feature is not available' %
|
|
945
|
+
sys.stderr.write('%s is passed but %s DAMON feature is not available\n' %
|
|
858
946
|
(arg, feature))
|
|
859
947
|
|
|
860
948
|
def warn_for_features(arg, features):
|
|
@@ -862,7 +950,7 @@ def warn_for_features(arg, features):
|
|
|
862
950
|
if _damo_sysinfo.damon_feature_available(feature):
|
|
863
951
|
return
|
|
864
952
|
sys.stderr.write(
|
|
865
|
-
'%s is passed but any of %s DAMON features is not available' %
|
|
953
|
+
'%s is passed but any of %s DAMON features is not available\n' %
|
|
866
954
|
(arg, ', '.join(features)))
|
|
867
955
|
|
|
868
956
|
def warn_unsupported_damon_features_for(args):
|
|
@@ -870,6 +958,19 @@ def warn_unsupported_damon_features_for(args):
|
|
|
870
958
|
if args.sample_primitives is not None:
|
|
871
959
|
warn_for('--sample_primitives', 'sysfs/damon_sample_control')
|
|
872
960
|
|
|
961
|
+
if args.probe_filter != []:
|
|
962
|
+
warn_for('--probe_filter', 'sysfs/attrs_monitoring')
|
|
963
|
+
|
|
964
|
+
# 7.2
|
|
965
|
+
if _damon.damos_action_collapse in args.damos_action:
|
|
966
|
+
warn_for('--damos_action collapse', 'sysfs/damos_action_collapse')
|
|
967
|
+
for quota_goal in args.damos_quota_goal:
|
|
968
|
+
metric = quota_goal[0]
|
|
969
|
+
if metric == _damon.qgoal_node_eligible_mem_bp:
|
|
970
|
+
warn_for('--damos_quota_goal %s' % metric,
|
|
971
|
+
'sysfs/damos_quota_goal_node_eligible_mem_bp')
|
|
972
|
+
|
|
973
|
+
# 7.1
|
|
873
974
|
if args.damos_quota_goal_tuner != []:
|
|
874
975
|
warn_for('--damos_quota_goal_tuner', 'sysfs/damos_quota_goal_tuner')
|
|
875
976
|
if args.pause_ctx is not None:
|
|
@@ -1273,6 +1374,21 @@ def set_monitoring_damos_common_args(parser, hide_help=False):
|
|
|
1273
1374
|
action='append',
|
|
1274
1375
|
help='monitoring operations set'
|
|
1275
1376
|
if not hide_help else argparse.SUPPRESS)
|
|
1377
|
+
|
|
1378
|
+
parser.add_argument('--probe_filter', nargs='+', action='append',
|
|
1379
|
+
default=[],
|
|
1380
|
+
metavar='<<allow|reject> [non] <type> [option]...>',
|
|
1381
|
+
help='data attribute monitoring probe filter'
|
|
1382
|
+
if not hide_help else argparse.SUPPRESS)
|
|
1383
|
+
parser.add_argument(
|
|
1384
|
+
'--nr_probe_filters', type=int, nargs='+', metavar='<integer>',
|
|
1385
|
+
help='number of filters for each probe (in order)'
|
|
1386
|
+
if not hide_help else argparse.SUPPRESS)
|
|
1387
|
+
parser.add_argument(
|
|
1388
|
+
'--nr_probes', type=int, nargs='+', metavar='<integer>',
|
|
1389
|
+
help='number of probes for each context (in order)'
|
|
1390
|
+
if not hide_help else argparse.SUPPRESS)
|
|
1391
|
+
|
|
1276
1392
|
parser.add_argument(
|
|
1277
1393
|
'--pause_ctx', type=int, nargs='+', metavar='<context index>',
|
|
1278
1394
|
help='contexts to pause')
|
|
@@ -327,15 +327,26 @@ features_list = [
|
|
|
327
327
|
upstream_status='merged in v7.0-rc1 (4835e2871321f)',
|
|
328
328
|
upstreamed_version='7.0'),
|
|
329
329
|
|
|
330
|
+
# v7.1-rc1 release: Sun Apr 26 14:19:00 2026 -0700
|
|
330
331
|
DamonFeature(name='sysfs/damos_quota_goal_tuner',
|
|
332
|
+
upstream_status='merged in v7.1-rc1 (8719c59c4b928)',
|
|
333
|
+
upstreamed_version='7.1'),
|
|
334
|
+
|
|
335
|
+
DamonFeature(name='sysfs/damos_action_collapse',
|
|
336
|
+
upstream_status='merged in mm.git',
|
|
337
|
+
upstreamed_version='none'),
|
|
338
|
+
DamonFeature(name='sysfs/damos_quota_goal_node_eligible_mem_bp',
|
|
331
339
|
upstream_status='merged in mm.git',
|
|
332
340
|
upstreamed_version='none'),
|
|
333
|
-
|
|
334
341
|
DamonFeature(name='sysfs/ctx_pause',
|
|
335
|
-
upstream_status='
|
|
342
|
+
upstream_status='merged in mm.git',
|
|
336
343
|
upstreamed_version='none'),
|
|
337
344
|
DamonFeature(name='sysfs/damos_quota_fail_charge_ratio',
|
|
338
|
-
upstream_status='
|
|
345
|
+
upstream_status='merged in mm.git',
|
|
346
|
+
upstreamed_version='none'),
|
|
347
|
+
|
|
348
|
+
DamonFeature(name='sysfs/attrs_monitoring',
|
|
349
|
+
upstream_status='hacking on damon/next',
|
|
339
350
|
upstreamed_version='none'),
|
|
340
351
|
|
|
341
352
|
DamonFeature(name='sysfs/damon_sample_control',
|
|
@@ -570,6 +570,52 @@ def write_ops_attrs_dir(dir_path, ops_attrs):
|
|
|
570
570
|
if err is not None:
|
|
571
571
|
return err
|
|
572
572
|
|
|
573
|
+
def write_probe_filter_dir(dir_path, filter):
|
|
574
|
+
err = _damo_fs.write_file(
|
|
575
|
+
os.path.join(dir_path, 'type'), filter.filter_type)
|
|
576
|
+
if err is not None:
|
|
577
|
+
return err
|
|
578
|
+
err = _damo_fs.write_file(os.path.join(dir_path, 'matching'),
|
|
579
|
+
'Y' if filter.matching else 'N')
|
|
580
|
+
if err is not None:
|
|
581
|
+
return err
|
|
582
|
+
err = _damo_fs.write_file(os.path.join(dir_path, 'allow'),
|
|
583
|
+
'Y' if filter.allow else 'N')
|
|
584
|
+
if err is not None:
|
|
585
|
+
return err
|
|
586
|
+
if filter.filter_type == 'memcg':
|
|
587
|
+
err = _damo_fs.write_file(os.path.join(dir_path, 'path'), filter.path)
|
|
588
|
+
if err is not None:
|
|
589
|
+
return err
|
|
590
|
+
return None
|
|
591
|
+
|
|
592
|
+
def write_probe_dir(dir_path, probe):
|
|
593
|
+
filters_dir = os.path.join(dir_path, 'filters')
|
|
594
|
+
err = ensure_nr_file_for(os.path.join(filters_dir, 'nr_filters'),
|
|
595
|
+
probe.filters)
|
|
596
|
+
if err is not None:
|
|
597
|
+
return err
|
|
598
|
+
|
|
599
|
+
for idx, filter in enumerate(probe.filters):
|
|
600
|
+
err = write_probe_filter_dir(
|
|
601
|
+
os.path.join(filters_dir, '%d' % idx), filter)
|
|
602
|
+
if err is not None:
|
|
603
|
+
return err
|
|
604
|
+
return None
|
|
605
|
+
|
|
606
|
+
def write_probes_dir(dir_path, probes):
|
|
607
|
+
if not os.path.isdir(dir_path):
|
|
608
|
+
return None
|
|
609
|
+
err = ensure_nr_file_for(os.path.join(dir_path, 'nr_probes'), probes)
|
|
610
|
+
if err is not None:
|
|
611
|
+
return err
|
|
612
|
+
|
|
613
|
+
for idx, probe in enumerate(probes):
|
|
614
|
+
err = write_probe_dir(os.path.join(dir_path, '%d' % idx), probe)
|
|
615
|
+
if err is not None:
|
|
616
|
+
return err
|
|
617
|
+
return None
|
|
618
|
+
|
|
573
619
|
def write_sample_filter_dir(dir_path, sample_filter):
|
|
574
620
|
err = _damo_fs.write_file(
|
|
575
621
|
os.path.join(dir_path, 'type'), sample_filter.filter_type)
|
|
@@ -672,6 +718,11 @@ def write_monitoring_attrs_dir(dir_path, context):
|
|
|
672
718
|
if err is not None:
|
|
673
719
|
return err
|
|
674
720
|
|
|
721
|
+
err = write_probes_dir(
|
|
722
|
+
os.path.join(dir_path, 'probes'), context.probes)
|
|
723
|
+
if err is not None:
|
|
724
|
+
return err
|
|
725
|
+
|
|
675
726
|
return write_sample_control_dir(
|
|
676
727
|
os.path.join(dir_path, 'sample'), context.sample_control)
|
|
677
728
|
|
|
@@ -930,14 +981,28 @@ def files_content_to_damos_stats(files_content):
|
|
|
930
981
|
int(files_content['qt_exceeds']),
|
|
931
982
|
nr_snapshots=nr_snapshots, max_nr_snapshots=max_nr_snapshots)
|
|
932
983
|
|
|
984
|
+
def files_content_to_probe_hits(files_content):
|
|
985
|
+
hits = []
|
|
986
|
+
for kv in number_sorted_dirs(files_content):
|
|
987
|
+
hits.append(int(kv['hits']))
|
|
988
|
+
return hits
|
|
989
|
+
|
|
933
990
|
def files_content_to_damos_tried_regions(files_content):
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
991
|
+
regions = []
|
|
992
|
+
for kv in number_sorted_dirs(files_content):
|
|
993
|
+
if 'probes' in kv:
|
|
994
|
+
probe_hits = files_content_to_probe_hits(kv['probes'])
|
|
995
|
+
else:
|
|
996
|
+
probe_hits = []
|
|
997
|
+
regions.append(
|
|
998
|
+
_damon.DamonRegion(
|
|
999
|
+
int(kv['start']), int(kv['end']),
|
|
1000
|
+
int(kv['nr_accesses']), _damon.unit_samples,
|
|
1001
|
+
int(kv['age']), _damon.unit_aggr_intervals,
|
|
1002
|
+
int(kv['sz_filter_passed'])
|
|
1003
|
+
if 'sz_filter_passed' in kv else None,
|
|
1004
|
+
probe_hits=probe_hits))
|
|
1005
|
+
return regions
|
|
941
1006
|
|
|
942
1007
|
def files_content_to_damos_dest(files_content):
|
|
943
1008
|
return _damon.DamosDest(
|
|
@@ -985,6 +1050,29 @@ def files_content_to_target(files_content):
|
|
|
985
1050
|
regions = files_content_to_regions(files_content['regions'])
|
|
986
1051
|
return _damon.DamonTarget(pid, regions, obsolete=obsolete)
|
|
987
1052
|
|
|
1053
|
+
def files_content_to_damon_filter(files_content):
|
|
1054
|
+
path = None
|
|
1055
|
+
if 'path' in files_content:
|
|
1056
|
+
files_content.get('path').strip()
|
|
1057
|
+
return _damon.DamonFilter(
|
|
1058
|
+
filter_type=files_content['type'].strip(),
|
|
1059
|
+
matching=files_content['matching'].strip(),
|
|
1060
|
+
allow=files_content['allow'].strip(), path=path)
|
|
1061
|
+
|
|
1062
|
+
def files_content_to_probe(files_content):
|
|
1063
|
+
filters_content = files_content['filters']
|
|
1064
|
+
filters = []
|
|
1065
|
+
for kv in number_sorted_dirs(filters_content):
|
|
1066
|
+
filter = files_content_to_damon_filter(kv)
|
|
1067
|
+
filters.append(filter)
|
|
1068
|
+
return _damon.DamonProbe(filters=filters)
|
|
1069
|
+
|
|
1070
|
+
def files_content_to_probes(files_content):
|
|
1071
|
+
probes = []
|
|
1072
|
+
for kv in number_sorted_dirs(files_content):
|
|
1073
|
+
probes.append(files_content_to_probe(kv))
|
|
1074
|
+
return probes
|
|
1075
|
+
|
|
988
1076
|
def files_content_to_sample_filter(files_content):
|
|
989
1077
|
filter_type = files_content['type'].strip()
|
|
990
1078
|
matching = files_content['matching'].strip()
|
|
@@ -1037,6 +1125,11 @@ def files_content_to_context(files_content):
|
|
|
1037
1125
|
nr_regions = _damon.DamonNrRegionsRange(
|
|
1038
1126
|
int(nr_regions_content['min']),
|
|
1039
1127
|
int(nr_regions_content['max']))
|
|
1128
|
+
if 'probes' in files_content['monitoring_attrs']:
|
|
1129
|
+
probes = files_content_to_probes(
|
|
1130
|
+
files_content['monitoring_attrs']['probes'])
|
|
1131
|
+
else:
|
|
1132
|
+
probes = []
|
|
1040
1133
|
if 'sample' in mon_attrs_content:
|
|
1041
1134
|
sample_control = files_content_to_sample_control(
|
|
1042
1135
|
mon_attrs_content['sample'])
|
|
@@ -1066,7 +1159,7 @@ def files_content_to_context(files_content):
|
|
|
1066
1159
|
|
|
1067
1160
|
return _damon.DamonCtx(ops, targets, intervals, nr_regions, schemes,
|
|
1068
1161
|
ops_attrs=ops_attrs, sample_control=sample_control,
|
|
1069
|
-
pause=pause, addr_unit=addr_unit)
|
|
1162
|
+
pause=pause, addr_unit=addr_unit, probes=probes)
|
|
1070
1163
|
|
|
1071
1164
|
def files_content_to_kdamond(files_content):
|
|
1072
1165
|
contexts_content = files_content['contexts']
|
|
@@ -1339,6 +1432,14 @@ def mk_feature_supports_map():
|
|
|
1339
1432
|
os.path.join(scheme_dir_of(0, 0, 0), 'quotas',
|
|
1340
1433
|
'fail_charge_denom')):
|
|
1341
1434
|
supports_map['sysfs/damos_quota_fail_charge_ratio'] = True
|
|
1435
|
+
# damos_collapse and damos_node_eligible_mem_bp will be upstreamed
|
|
1436
|
+
# together.
|
|
1437
|
+
supports_map['sysfs/damos_action_collapse'] = True
|
|
1438
|
+
supports_map['sysfs/damos_quota_goal_node_eligible_mem_bp'] = True
|
|
1439
|
+
|
|
1440
|
+
if os.path.isdir(
|
|
1441
|
+
os.path.join(ctx_dir_of(0, 0), 'monitoring_attrs', 'probes')):
|
|
1442
|
+
supports_map['sysfs/attrs_monitoring'] = True
|
|
1342
1443
|
|
|
1343
1444
|
if os.path.isdir(os.path.join(ctx_dir_of(0, 0), 'operations_attrs')):
|
|
1344
1445
|
supports_map['sysfs/ops_attrs'] = True
|
|
@@ -246,6 +246,11 @@ region_formatters = [
|
|
|
246
246
|
lambda index, region, snapshot, record, fmt:
|
|
247
247
|
temperature_str(region, fmt.raw_number, fmt),
|
|
248
248
|
'access temperature of the region'),
|
|
249
|
+
Formatter(
|
|
250
|
+
'<probe hits>',
|
|
251
|
+
lambda index, region, snapshot, record, fmt:
|
|
252
|
+
' '.join(['%d' % h for h in region.probe_hits]),
|
|
253
|
+
'data attributese probe hit counts'),
|
|
249
254
|
Formatter(
|
|
250
255
|
'<filters passed bytes>',
|
|
251
256
|
lambda index, region, snapshot, record, fmt:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: damo
|
|
3
|
-
Version: 3.2.
|
|
3
|
+
Version: 3.2.4
|
|
4
4
|
Summary: DAMON user-space tool
|
|
5
5
|
Home-page: https://github.com/damonitor/damo
|
|
6
6
|
Author: SeongJae Park
|
|
@@ -71,7 +71,7 @@ The second and last commands will show the access pattern of your workload,
|
|
|
71
71
|
like below:
|
|
72
72
|
|
|
73
73
|

|
|
74
|
-

|
|
75
75
|
|
|
76
76
|
|
|
77
77
|
FAQs
|
|
@@ -90,7 +90,7 @@ Where can I get more detailed usage?
|
|
|
90
90
|
------------------------------------
|
|
91
91
|
|
|
92
92
|
The below sections provide quick introductions for `damo`'s major features.
|
|
93
|
-
For more detailed usage, please refer to [USAGE.md](https://github.com/damonitor/damo/blob/v3.2.
|
|
93
|
+
For more detailed usage, please refer to [USAGE.md](https://github.com/damonitor/damo/blob/v3.2.4/USAGE.md) file.
|
|
94
94
|
|
|
95
95
|
|
|
96
96
|
What does the version numbers mean?
|
|
@@ -115,7 +115,7 @@ We try our best to make `damo` stable and doesn't introduce regressions to
|
|
|
115
115
|
users. However, nothing goes forever. Sometimes, some features will be
|
|
116
116
|
deprecated. Some features will have longer support more than others.
|
|
117
117
|
|
|
118
|
-
In short, features that documented on [USAGE.md](https://github.com/damonitor/damo/blob/v3.2.
|
|
118
|
+
In short, features that documented on [USAGE.md](https://github.com/damonitor/damo/blob/v3.2.4/USAGE.md) and not explicitly
|
|
119
119
|
marked as experimental will be better supported, and provides at least three
|
|
120
120
|
months of deprecation grace period. Within the grace period, users can ask
|
|
121
121
|
extension of the support. Even after the grace period, please reach out to
|
|
@@ -138,7 +138,7 @@ Quick Intro for Major Features
|
|
|
138
138
|
==============================
|
|
139
139
|
|
|
140
140
|
Below are quick introductions for `damo`'s major features.
|
|
141
|
-
For more detailed usage, please refer to [USAGE.md](https://github.com/damonitor/damo/blob/v3.2.
|
|
141
|
+
For more detailed usage, please refer to [USAGE.md](https://github.com/damonitor/damo/blob/v3.2.4/USAGE.md) file.
|
|
142
142
|
|
|
143
143
|
|
|
144
144
|
Snapshot Data Access Pattern
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|