From patchwork Fri Jan 10 13:15:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: SeongJae Park X-Patchwork-Id: 11327315 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5B1FC6C1 for ; Fri, 10 Jan 2020 13:16:14 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id E832B2072E for ; Fri, 10 Jan 2020 13:16:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=amazon.com header.i=@amazon.com header.b="fLoNBZq0" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E832B2072E Authentication-Results: mail.kernel.org; dmarc=fail (p=quarantine dis=none) header.from=amazon.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 6BAD58E0008; Fri, 10 Jan 2020 08:16:10 -0500 (EST) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 66CA48E0001; Fri, 10 Jan 2020 08:16:10 -0500 (EST) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 533048E0008; Fri, 10 Jan 2020 08:16:10 -0500 (EST) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0087.hostedemail.com [216.40.44.87]) by kanga.kvack.org (Postfix) with ESMTP id 360448E0001 for ; Fri, 10 Jan 2020 08:16:10 -0500 (EST) Received: from smtpin22.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay03.hostedemail.com (Postfix) with SMTP id EA9AC8248047 for ; Fri, 10 Jan 2020 13:16:09 +0000 (UTC) X-FDA: 76361772858.22.mice42_18a64da40b127 X-Spam-Summary: 1,0,0,,d41d8cd98f00b204,prvs=271e9c931=sjpark@amazon.com,:akpm@linux-foundation.org::linux-kernel@vger.kernel.org:corbet@lwn.net:linux-doc@vger.kernel.org:mgorman@suse.de:brendanhiggins@google.com:sj38.park@gmail.com:sjpark@amazon.de,RULES_HIT:30003:30029:30034:30051:30054:30064:30070:30075:30079,0,RBL:72.21.196.25:@amazon.com:.lbl8.mailshell.net-62.18.0.100 66.10.201.10,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:none,Custom_rules:0:0:0,LFtime:30,LUA_SUMMARY:none X-HE-Tag: mice42_18a64da40b127 X-Filterd-Recvd-Size: 35770 Received: from smtp-fw-2101.amazon.com (smtp-fw-2101.amazon.com [72.21.196.25]) by imf02.hostedemail.com (Postfix) with ESMTP for ; Fri, 10 Jan 2020 13:16:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.com; i=@amazon.com; q=dns/txt; s=amazon201209; t=1578662170; x=1610198170; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=dd7hgUMBjiWeB2ID4c80RlACUMmSuALWwx9nnbLEaXU=; b=fLoNBZq0d4UUc4+sIydkXAYPWgyxK9FFhnivNtgIwvqPgHA6Hx+7HIb6 hnMaXG3s8aU4gMm5aRb8zZsMxjNDOldFoc2/tg5Hak2MqIpQppxW6lny9 bGEnKdiqeVEP8cVEHIgbNyLb1EuF8OQhItIVUVfZz2gbzonPwA/c4R/Nr M=; IronPort-SDR: 7IwacRRJeEQAX2GfTXqN2ID4A3eXwVn1DWJj9qufRe6SICV7xG1/4e6hp58Xz+HjjT68sxUov/ bMIlFMFSowTQ== X-IronPort-AV: E=Sophos;i="5.69,417,1571702400"; d="scan'208";a="11883286" Received: from iad12-co-svc-p1-lb1-vlan2.amazon.com (HELO email-inbound-relay-2c-2225282c.us-west-2.amazon.com) ([10.43.8.2]) by smtp-border-fw-out-2101.iad2.amazon.com with ESMTP; 10 Jan 2020 13:16:08 +0000 Received: from EX13MTAUEA001.ant.amazon.com (pdx4-ws-svc-p6-lb7-vlan3.pdx.amazon.com [10.170.41.166]) by email-inbound-relay-2c-2225282c.us-west-2.amazon.com (Postfix) with ESMTPS id 93D56A25E8; Fri, 10 Jan 2020 13:16:06 +0000 (UTC) Received: from EX13D31EUA001.ant.amazon.com (10.43.165.15) by EX13MTAUEA001.ant.amazon.com (10.43.61.243) with Microsoft SMTP Server (TLS) id 15.0.1367.3; Fri, 10 Jan 2020 13:16:05 +0000 Received: from u886c93fd17d25d.ant.amazon.com (10.43.161.115) by EX13D31EUA001.ant.amazon.com (10.43.165.15) with Microsoft SMTP Server (TLS) id 15.0.1367.3; Fri, 10 Jan 2020 13:16:01 +0000 From: SeongJae Park To: CC: , , , , , , , SeongJae Park Subject: [RFC PATCH 3/5] mm/damon: Add minimal user-space tools Date: Fri, 10 Jan 2020 14:15:20 +0100 Message-ID: <20200110131522.29964-4-sjpark@amazon.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200110131522.29964-1-sjpark@amazon.com> References: <20200110131522.29964-1-sjpark@amazon.com> MIME-Version: 1.0 X-Originating-IP: [10.43.161.115] X-ClientProxiedBy: EX13D10UWA001.ant.amazon.com (10.43.160.216) To EX13D31EUA001.ant.amazon.com (10.43.165.15) X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: From: SeongJae Park This commit adds a shallow wrapper python script, ``/tools/damon/damn`` that provides more convenient interface for the user space. Note that it is only aimed to be used for minimal reference of the DAMON's raw interfaces and for debuggings of DAMON itself. Quick Tutorial -------------- To test DAMON on your system, 1. Ensure your kernel is built with CONFIG_DAMON turned on, and debugfs is mounted at ``/sys/kernel/debug/``. 2. ``/tools/damon/damn -h`` Signed-off-by: SeongJae Park --- tools/damon/bin2txt.py | 64 +++++++ tools/damon/damn | 36 ++++ tools/damon/heats.py | 358 ++++++++++++++++++++++++++++++++++++++ tools/damon/nr_regions.py | 116 ++++++++++++ tools/damon/record.py | 182 +++++++++++++++++++ tools/damon/report.py | 45 +++++ tools/damon/wss.py | 121 +++++++++++++ 7 files changed, 922 insertions(+) create mode 100644 tools/damon/bin2txt.py create mode 100644 tools/damon/damn create mode 100644 tools/damon/heats.py create mode 100644 tools/damon/nr_regions.py create mode 100644 tools/damon/record.py create mode 100644 tools/damon/report.py create mode 100644 tools/damon/wss.py diff --git a/tools/damon/bin2txt.py b/tools/damon/bin2txt.py new file mode 100644 index 000000000000..d5ffac60e02c --- /dev/null +++ b/tools/damon/bin2txt.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0 + +import argparse +import os +import struct +import sys + +def parse_time(bindat): + "bindat should be 16 bytes" + sec = struct.unpack('l', bindat[0:8])[0] + nsec = struct.unpack('l', bindat[8:16])[0] + return sec * 1000000000 + nsec; + +def pr_region(f): + saddr = struct.unpack('L', f.read(8))[0] + eaddr = struct.unpack('L', f.read(8))[0] + nr_accesses = struct.unpack('I', f.read(4))[0] + print("%012x-%012x(%10d):\t%d" % + (saddr, eaddr, eaddr - saddr, nr_accesses)) + +def pr_task_info(f): + pid = struct.unpack('L', f.read(8))[0] + print("pid: ", pid) + nr_regions = struct.unpack('I', f.read(4))[0] + print("nr_regions: ", nr_regions) + for r in range(nr_regions): + pr_region(f) + +def set_argparser(parser): + parser.add_argument('--input', '-i', type=str, metavar='', + default='damon.data', help='input file name') + +def main(args=None): + if not args: + parser = argparse.ArgumentParser() + set_argparser(parser) + args = parser.parse_args() + + file_path = args.input + + if not os.path.isfile(file_path): + print('input file (%s) is not exist' % file_path) + exit(1) + + with open(file_path, 'rb') as f: + start_time = None + while True: + timebin = f.read(16) + if len(timebin) != 16: + break + time = parse_time(timebin) + if not start_time: + start_time = time + print("start_time: ", start_time) + print("rel time: %16d" % (time - start_time)) + nr_tasks = struct.unpack('I', f.read(4))[0] + print("nr_tasks: ", nr_tasks) + for t in range(nr_tasks): + pr_task_info(f) + print("") + +if __name__ == '__main__': + main() diff --git a/tools/damon/damn b/tools/damon/damn new file mode 100644 index 000000000000..0b8019db7f28 --- /dev/null +++ b/tools/damon/damn @@ -0,0 +1,36 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0 + +import argparse + +import record +import report + +class SubCmdHelpFormatter(argparse.RawDescriptionHelpFormatter): + def _format_action(self, action): + parts = super(argparse.RawDescriptionHelpFormatter, + self)._format_action(action) + # skip sub parsers help + if action.nargs == argparse.PARSER: + parts = '\n'.join(parts.split('\n')[1:]) + return parts + +parser = argparse.ArgumentParser(formatter_class=SubCmdHelpFormatter) + +subparser = parser.add_subparsers(title='command', dest='command', + metavar='') +subparser.required = True + +parser_record = subparser.add_parser('record', help='record data accesses') +record.set_argparser(parser_record) + +parser_report = subparser.add_parser('report', + help='report the recorded data accesses') +report.set_argparser(parser_report) + +args = parser.parse_args() + +if args.command == 'record': + record.main(args) +elif args.command == 'report': + report.main(args) diff --git a/tools/damon/heats.py b/tools/damon/heats.py new file mode 100644 index 000000000000..48e966c5ca02 --- /dev/null +++ b/tools/damon/heats.py @@ -0,0 +1,358 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0 + +""" +Transform binary trace data into human readable text that can be used for +heatmap drawing, or directly plot the data in a heatmap format. + +Format of the text is: + +