projects/linux·blob master · refs

75 lines · 2.6 KiB

1#!/usr/bin/env python3
2# SPDX-License-Identifier: GPL-2.0
3
4import os
5import subprocess
6import time
7
8import _damon_sysfs
9
10def main():
11 # Continuously access a memory region for far longer than the test needs,
12 # so the kdamond always has a live target to monitor while we poll.
13 sz_region = 10 * 1024 * 1024
14 proc = subprocess.Popen(
15 ['./access_memory', '1', '%d' % sz_region, '60000', 'repeat'])
16
17 # A 'stat' scheme with the default (maximally wide) access pattern matches
18 # every monitored region, so its 'nr_tried' stat increases as the kdamond
19 # runs. refresh_ms should make DAMON update the schemes' stats files under
20 # sysfs on its own, without a manual 'update_schemes_stats' request.
21 kdamond = _damon_sysfs.Kdamond(
22 refresh_ms=100,
23 contexts=[_damon_sysfs.DamonCtx(
24 ops='vaddr',
25 targets=[_damon_sysfs.DamonTarget(pid=proc.pid)],
26 schemes=[_damon_sysfs.Damos(action='stat')],
27 )])
28 kdamonds = _damon_sysfs.Kdamonds([kdamond])
29
30 err = kdamonds.start()
31 if err is not None:
32 # Kernels older than the refresh_ms feature have no such file; treat
33 # that as unsupported rather than a failure.
34 if not os.path.exists(os.path.join(kdamond.sysfs_dir(), 'refresh_ms')):
35 proc.terminate()
36 proc.wait()
37 print('kdamond has no refresh_ms file; skipping')
38 exit(_damon_sysfs.ksft_skip)
39 proc.terminate()
40 proc.wait()
41 print('kdamond start failed: %s' % err)
42 exit(1)
43
44 scheme = kdamond.contexts[0].schemes[0]
45 nr_tried_path = os.path.join(scheme.sysfs_dir(), 'stats', 'nr_tried')
46
47 try:
48 # Poll the stat file directly. We never request an update (e.g.
49 # 'update_schemes_stats'), so 'nr_tried' can become non-zero only
50 # through the periodic refresh that refresh_ms enables.
51 nr_tried = 0
52 deadline = time.monotonic() + 10
53 while time.monotonic() < deadline:
54 if proc.poll() is not None:
55 print('the access_memory target exited unexpectedly')
56 exit(1)
57 content, err = _damon_sysfs.read_file(nr_tried_path)
58 if err is not None:
59 print('reading %s failed: %s' % (nr_tried_path, err))
60 exit(1)
61 nr_tried = int(content)
62 if nr_tried > 0:
63 break
64 time.sleep(0.1)
65 finally:
66 kdamonds.stop()
67 proc.terminate()
68 proc.wait()
69
70 if nr_tried == 0:
71 print('refresh_ms did not auto-update the schemes stats')
72 exit(1)
73
74if __name__ == '__main__':
75 main()