Ihar Hrachyshka | 2b4735f | 2017-02-10 06:17:37 +0000 | [diff] [blame] | 1 | # This tool lists processes that lock memory pages from swapping to disk. |
| 2 | |
| 3 | import re |
Ihar Hrachyshka | 2b4735f | 2017-02-10 06:17:37 +0000 | [diff] [blame] | 4 | |
| 5 | import psutil |
| 6 | |
| 7 | |
Dirk Mueller | 02f9e8b | 2017-09-10 02:51:10 +0200 | [diff] [blame] | 8 | LCK_SUMMARY_REGEX = re.compile( |
| 9 | "^VmLck:\s+(?P<locked>[\d]+)\s+kB", re.MULTILINE) |
Ihar Hrachyshka | 2b4735f | 2017-02-10 06:17:37 +0000 | [diff] [blame] | 10 | |
| 11 | |
| 12 | def main(): |
| 13 | try: |
Ian Wienand | 9573edb | 2017-03-28 19:37:39 +1100 | [diff] [blame] | 14 | print(_get_report()) |
Ihar Hrachyshka | 2b4735f | 2017-02-10 06:17:37 +0000 | [diff] [blame] | 15 | except Exception as e: |
Ian Wienand | 9573edb | 2017-03-28 19:37:39 +1100 | [diff] [blame] | 16 | print("Failure listing processes locking memory: %s" % str(e)) |
| 17 | raise |
Ihar Hrachyshka | 2b4735f | 2017-02-10 06:17:37 +0000 | [diff] [blame] | 18 | |
| 19 | |
| 20 | def _get_report(): |
| 21 | mlock_users = [] |
| 22 | for proc in psutil.process_iter(): |
Ihar Hrachyshka | 2b4735f | 2017-02-10 06:17:37 +0000 | [diff] [blame] | 23 | # sadly psutil does not expose locked pages info, that's why we |
Dirk Mueller | 02f9e8b | 2017-09-10 02:51:10 +0200 | [diff] [blame] | 24 | # iterate over the /proc/%pid/status files manually |
Ihar Hrachyshka | 2b4735f | 2017-02-10 06:17:37 +0000 | [diff] [blame] | 25 | try: |
Dirk Mueller | 02f9e8b | 2017-09-10 02:51:10 +0200 | [diff] [blame] | 26 | s = open("%s/%d/status" % (psutil.PROCFS_PATH, proc.pid), 'r') |
| 27 | except EnvironmentError: |
| 28 | continue |
| 29 | with s: |
| 30 | for line in s: |
| 31 | result = LCK_SUMMARY_REGEX.search(line) |
| 32 | if result: |
| 33 | locked = int(result.group('locked')) |
| 34 | if locked: |
| 35 | mlock_users.append({'name': proc.name(), |
| 36 | 'pid': proc.pid, |
| 37 | 'locked': locked}) |
Ihar Hrachyshka | 2b4735f | 2017-02-10 06:17:37 +0000 | [diff] [blame] | 38 | |
| 39 | # produce a single line log message with per process mlock stats |
| 40 | if mlock_users: |
| 41 | return "; ".join( |
| 42 | "[%(name)s (pid:%(pid)s)]=%(locked)dKB" % args |
| 43 | # log heavy users first |
| 44 | for args in sorted(mlock_users, key=lambda d: d['locked']) |
| 45 | ) |
| 46 | else: |
| 47 | return "no locked memory" |
| 48 | |
| 49 | |
| 50 | if __name__ == "__main__": |
| 51 | main() |