xref: /linux/tools/testing/selftests/damon/damon_nr_regions.py (revision 3a39d672e7f48b8d6b91a09afa4b55352773b4b5)
1#!/usr/bin/env python3
2# SPDX-License-Identifier: GPL-2.0
3
4import subprocess
5import time
6
7import _damon_sysfs
8
9def test_nr_regions(real_nr_regions, min_nr_regions, max_nr_regions):
10    '''
11    Create process of the given 'real_nr_regions' regions, monitor it using
12    DAMON with given '{min,max}_nr_regions' monitoring parameter.
13
14    Exit with non-zero return code if the given {min,max}_nr_regions is not
15    kept.
16    '''
17    sz_region = 10 * 1024 * 1024
18    proc = subprocess.Popen(['./access_memory_even', '%d' % real_nr_regions,
19                             '%d' % sz_region])
20
21    # stat every monitored regions
22    kdamonds = _damon_sysfs.Kdamonds([_damon_sysfs.Kdamond(
23            contexts=[_damon_sysfs.DamonCtx(
24                monitoring_attrs=_damon_sysfs.DamonAttrs(
25                    min_nr_regions=min_nr_regions,
26                    max_nr_regions=max_nr_regions),
27                ops='vaddr',
28                targets=[_damon_sysfs.DamonTarget(pid=proc.pid)],
29                schemes=[_damon_sysfs.Damos(action='stat',
30                    )] # schemes
31                )] # contexts
32            )]) # kdamonds
33
34    err = kdamonds.start()
35    if err is not None:
36        proc.terminate()
37        print('kdamond start failed: %s' % err)
38        exit(1)
39
40    collected_nr_regions = []
41    while proc.poll() is None:
42        time.sleep(0.1)
43        err = kdamonds.kdamonds[0].update_schemes_tried_regions()
44        if err is not None:
45            proc.terminate()
46            print('tried regions update failed: %s' % err)
47            exit(1)
48
49        scheme = kdamonds.kdamonds[0].contexts[0].schemes[0]
50        if scheme.tried_regions is None:
51            proc.terminate()
52            print('tried regions is not collected')
53            exit(1)
54
55        nr_tried_regions = len(scheme.tried_regions)
56        if nr_tried_regions <= 0:
57            proc.terminate()
58            print('tried regions is not created')
59            exit(1)
60        collected_nr_regions.append(nr_tried_regions)
61        if len(collected_nr_regions) > 10:
62            break
63    proc.terminate()
64    kdamonds.stop()
65
66    test_name = 'nr_regions test with %d/%d/%d real/min/max nr_regions' % (
67            real_nr_regions, min_nr_regions, max_nr_regions)
68    if (collected_nr_regions[0] < min_nr_regions or
69        collected_nr_regions[-1] > max_nr_regions):
70        print('fail %s' % test_name)
71        print('number of regions that collected are:')
72        for nr in collected_nr_regions:
73            print(nr)
74        exit(1)
75    print('pass %s ' % test_name)
76
77def main():
78    # test min_nr_regions larger than real nr regions
79    test_nr_regions(10, 20, 100)
80
81    # test max_nr_regions smaller than real nr regions
82    test_nr_regions(15, 3, 10)
83
84    # test online-tuned max_nr_regions that smaller than real nr regions
85    sz_region = 10 * 1024 * 1024
86    proc = subprocess.Popen(['./access_memory_even', '14', '%d' % sz_region])
87
88    # stat every monitored regions
89    kdamonds = _damon_sysfs.Kdamonds([_damon_sysfs.Kdamond(
90            contexts=[_damon_sysfs.DamonCtx(
91                monitoring_attrs=_damon_sysfs.DamonAttrs(
92                    min_nr_regions=10, max_nr_regions=1000),
93                ops='vaddr',
94                targets=[_damon_sysfs.DamonTarget(pid=proc.pid)],
95                schemes=[_damon_sysfs.Damos(action='stat',
96                    )] # schemes
97                )] # contexts
98            )]) # kdamonds
99
100    err = kdamonds.start()
101    if err is not None:
102        proc.terminate()
103        print('kdamond start failed: %s' % err)
104        exit(1)
105
106    # wait until the real regions are found
107    time.sleep(3)
108
109    attrs = kdamonds.kdamonds[0].contexts[0].monitoring_attrs
110    attrs.min_nr_regions = 3
111    attrs.max_nr_regions = 7
112    err = kdamonds.kdamonds[0].commit()
113    if err is not None:
114        proc.terminate()
115        print('commit failed: %s' % err)
116        exit(1)
117    # wait for next merge operation is executed
118    time.sleep(0.3)
119
120    err = kdamonds.kdamonds[0].update_schemes_tried_regions()
121    if err is not None:
122        proc.terminate()
123        print('tried regions update failed: %s' % err)
124        exit(1)
125
126    scheme = kdamonds.kdamonds[0].contexts[0].schemes[0]
127    if scheme.tried_regions is None:
128        proc.terminate()
129        print('tried regions is not collected')
130        exit(1)
131
132    nr_tried_regions = len(scheme.tried_regions)
133    if nr_tried_regions <= 0:
134        proc.terminate()
135        print('tried regions is not created')
136        exit(1)
137    proc.terminate()
138
139    if nr_tried_regions > 7:
140        print('fail online-tuned max_nr_regions: %d > 7' % nr_tried_regions)
141        exit(1)
142    print('pass online-tuned max_nr_regions')
143
144if __name__ == '__main__':
145    main()
146