Received: by 10.223.148.5 with SMTP id 5csp6028886wrq; Wed, 17 Jan 2018 08:33:06 -0800 (PST) X-Google-Smtp-Source: ACJfBovEj8C8brFoD8U2DfJUXrT5o3cy8BB9VzidlWW6P2jaq32UrGaRoBCElYKvJkK+AY71K/9v X-Received: by 10.98.139.154 with SMTP id e26mr34100137pfl.17.1516206786018; Wed, 17 Jan 2018 08:33:06 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516206785; cv=none; d=google.com; s=arc-20160816; b=ZvgCQ5looJKUNilS4/ffZUmjGwsxImje+22sqCo7SW9daNuZSlw0hYMfvgvskVsvQ2 +hD8jpJAh7waSx3XC+Sue9K7g7ApQSRlK7Sia0Pig2HA4eUAb3w6MiWDWFjJyMTw/ptf ZLwwN0YKc6Oyscpk+XZGZ7TLef0eUVSJxvju7nAB6PASqYzHRTgcdVVUjr+5w54corJ9 q5ijFidvtZpTEmM/PYIlQhyzp5Wcwlg/nz3ldW/LSdmd+ZBZc2Gbg29BUn/hIxzyXY+3 m/7FgWhiCAyHVRs9WabugtvKf+TRH5kmjhjtzaIAyYp1aPx2Ix0CdiI9ZvYJ3EHL10Pk d+Gg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-disposition :content-transfer-encoding:mime-version:robot-unsubscribe:robot-id :git-commit-id:subject:to:references:in-reply-to:reply-to:cc :message-id:from:date:arc-authentication-results; bh=Xp5pr3kNyqsXhneS/75UaLH5LrWU3uvNJ9IZ+/XUKxo=; b=vLLo3/TJcG2WFG6+96QuOtsjjCRg8vtaOLsmw37gMhdwykrHvYjNH97AZP0S/YwAfS A6icLH9G3p4NdMcoc4QmCm5BqPQVMF9VnqMxBEZLjyiSbji7iHpuDDEKvkDRtv5NPeV6 2HaRCiiMBt7JCY9TFOcD3lP3p9tVn9Dz3lzdhSGGneiMibg6BhEdeRAaS7hA7EVIHrsb oz21W8gz05DdjRplo8kuyayIjwcN0FfKUnUfqtBJ4tCmKmoNDt8w6hk41CtJS/xwwQor N2NAwhucB3qghCwe79fBxcIQxpP6JlqPSbBzExD2YB3jMzlK6Q3I+G82/EUogEZ+zCd1 GhJg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l2si594278pgl.823.2018.01.17.08.32.51; Wed, 17 Jan 2018 08:33:05 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754420AbeAQQbs (ORCPT + 99 others); Wed, 17 Jan 2018 11:31:48 -0500 Received: from terminus.zytor.com ([65.50.211.136]:44083 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754399AbeAQQbr (ORCPT ); Wed, 17 Jan 2018 11:31:47 -0500 Received: from terminus.zytor.com (localhost [127.0.0.1]) by terminus.zytor.com (8.15.2/8.15.2) with ESMTP id w0HGQ2TB031600; Wed, 17 Jan 2018 08:26:02 -0800 Received: (from tipbot@localhost) by terminus.zytor.com (8.15.2/8.15.2/Submit) id w0HGQ1lQ031594; Wed, 17 Jan 2018 08:26:01 -0800 Date: Wed, 17 Jan 2018 08:26:01 -0800 X-Authentication-Warning: terminus.zytor.com: tipbot set sender to tipbot@zytor.com using -f From: tip-bot for Kan Liang Message-ID: Cc: dan.j.williams@intel.com, pombredanne@nexb.com, peterz@infradead.org, acme@redhat.com, mingo@kernel.org, ak@linux.intel.com, linux-kernel@vger.kernel.org, eranian@google.com, Kan.liang@intel.com, tglx@linutronix.de, hpa@zytor.com, jolsa@kernel.org Reply-To: linux-kernel@vger.kernel.org, ak@linux.intel.com, mingo@kernel.org, Kan.liang@intel.com, eranian@google.com, pombredanne@nexb.com, dan.j.williams@intel.com, peterz@infradead.org, acme@redhat.com, hpa@zytor.com, jolsa@kernel.org, tglx@linutronix.de In-Reply-To: <1515099595-34770-1-git-send-email-kan.liang@intel.com> References: <1515099595-34770-1-git-send-email-kan.liang@intel.com> To: linux-tip-commits@vger.kernel.org Subject: [tip:perf/core] perf script python: Add script to profile and resolve physical mem type Git-Commit-ID: 41013f0c095980775e0746272873891ca7c28fb1 X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline X-Spam-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED,BAYES_00 autolearn=ham autolearn_force=no version=3.4.1 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on terminus.zytor.com Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: 41013f0c095980775e0746272873891ca7c28fb1 Gitweb: https://git.kernel.org/tip/41013f0c095980775e0746272873891ca7c28fb1 Author: Kan Liang AuthorDate: Thu, 4 Jan 2018 12:59:55 -0800 Committer: Arnaldo Carvalho de Melo CommitDate: Fri, 12 Jan 2018 11:06:57 -0300 perf script python: Add script to profile and resolve physical mem type There could be different types of memory in the system. E.g normal System Memory, Persistent Memory. To understand how the workload maps to those memories, it's important to know the I/O statistics of them. Perf can collect physical addresses, but those are raw data. It still needs extra work to resolve the physical addresses. Provide a script to facilitate the physical addresses resolving and I/O statistics. Profile with MEM_INST_RETIRED.ALL_LOADS or MEM_UOPS_RETIRED.ALL_LOADS event if any of them is available. Look up the /proc/iomem and resolve the physical address. Provide memory type summary. Here is an example output: # perf script report mem-phys-addr Event: mem_inst_retired.all_loads:P Memory type count percentage ---------------------------------------- ----------- ----------- System RAM 74 53.2% Persistent Memory 55 39.6% N/A --- Changes since V2: - Apply the new license rules. - Add comments for globals Changes since V1: - Do not mix DLA and Load Latency. Do not compare the loads and stores. Only profile the loads. - Use event name to replace the RAW event Signed-off-by: Kan Liang Reviewed-by: Andi Kleen Cc: Dan Williams Cc: Jiri Olsa Cc: Peter Zijlstra Cc: Philippe Ombredanne Cc: Stephane Eranian Link: https://lkml.kernel.org/r/1515099595-34770-1-git-send-email-kan.liang@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/scripts/python/bin/mem-phys-addr-record | 19 +++++ tools/perf/scripts/python/bin/mem-phys-addr-report | 3 + tools/perf/scripts/python/mem-phys-addr.py | 95 ++++++++++++++++++++++ .../util/scripting-engines/trace-event-python.c | 2 + 4 files changed, 119 insertions(+) diff --git a/tools/perf/scripts/python/bin/mem-phys-addr-record b/tools/perf/scripts/python/bin/mem-phys-addr-record new file mode 100644 index 0000000..5a87512 --- /dev/null +++ b/tools/perf/scripts/python/bin/mem-phys-addr-record @@ -0,0 +1,19 @@ +#!/bin/bash + +# +# Profiling physical memory by all retired load instructions/uops event +# MEM_INST_RETIRED.ALL_LOADS or MEM_UOPS_RETIRED.ALL_LOADS +# + +load=`perf list | grep mem_inst_retired.all_loads` +if [ -z "$load" ]; then + load=`perf list | grep mem_uops_retired.all_loads` +fi +if [ -z "$load" ]; then + echo "There is no event to count all retired load instructions/uops." + exit 1 +fi + +arg=$(echo $load | tr -d ' ') +arg="$arg:P" +perf record --phys-data -e $arg $@ diff --git a/tools/perf/scripts/python/bin/mem-phys-addr-report b/tools/perf/scripts/python/bin/mem-phys-addr-report new file mode 100644 index 0000000..3f2b847 --- /dev/null +++ b/tools/perf/scripts/python/bin/mem-phys-addr-report @@ -0,0 +1,3 @@ +#!/bin/bash +# description: resolve physical address samples +perf script $@ -s "$PERF_EXEC_PATH"/scripts/python/mem-phys-addr.py diff --git a/tools/perf/scripts/python/mem-phys-addr.py b/tools/perf/scripts/python/mem-phys-addr.py new file mode 100644 index 0000000..ebee2c5 --- /dev/null +++ b/tools/perf/scripts/python/mem-phys-addr.py @@ -0,0 +1,95 @@ +# mem-phys-addr.py: Resolve physical address samples +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) 2018, Intel Corporation. + +from __future__ import division +import os +import sys +import struct +import re +import bisect +import collections + +sys.path.append(os.environ['PERF_EXEC_PATH'] + \ + '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') + +#physical address ranges for System RAM +system_ram = [] +#physical address ranges for Persistent Memory +pmem = [] +#file object for proc iomem +f = None +#Count for each type of memory +load_mem_type_cnt = collections.Counter() +#perf event name +event_name = None + +def parse_iomem(): + global f + f = open('/proc/iomem', 'r') + for i, j in enumerate(f): + m = re.split('-|:',j,2) + if m[2].strip() == 'System RAM': + system_ram.append(long(m[0], 16)) + system_ram.append(long(m[1], 16)) + if m[2].strip() == 'Persistent Memory': + pmem.append(long(m[0], 16)) + pmem.append(long(m[1], 16)) + +def print_memory_type(): + print "Event: %s" % (event_name) + print "%-40s %10s %10s\n" % ("Memory type", "count", "percentage"), + print "%-40s %10s %10s\n" % ("----------------------------------------", \ + "-----------", "-----------"), + total = sum(load_mem_type_cnt.values()) + for mem_type, count in sorted(load_mem_type_cnt.most_common(), \ + key = lambda(k, v): (v, k), reverse = True): + print "%-40s %10d %10.1f%%\n" % (mem_type, count, 100 * count / total), + +def trace_begin(): + parse_iomem() + +def trace_end(): + print_memory_type() + f.close() + +def is_system_ram(phys_addr): + #/proc/iomem is sorted + position = bisect.bisect(system_ram, phys_addr) + if position % 2 == 0: + return False + return True + +def is_persistent_mem(phys_addr): + position = bisect.bisect(pmem, phys_addr) + if position % 2 == 0: + return False + return True + +def find_memory_type(phys_addr): + if phys_addr == 0: + return "N/A" + if is_system_ram(phys_addr): + return "System RAM" + + if is_persistent_mem(phys_addr): + return "Persistent Memory" + + #slow path, search all + f.seek(0, 0) + for j in f: + m = re.split('-|:',j,2) + if long(m[0], 16) <= phys_addr <= long(m[1], 16): + return m[2] + return "N/A" + +def process_event(param_dict): + name = param_dict["ev_name"] + sample = param_dict["sample"] + phys_addr = sample["phys_addr"] + + global event_name + if event_name == None: + event_name = name + load_mem_type_cnt[find_memory_type(phys_addr)] += 1 diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index c1848b5..ea07088 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -499,6 +499,8 @@ static PyObject *get_perf_sample_dict(struct perf_sample *sample, PyLong_FromUnsignedLongLong(sample->time)); pydict_set_item_string_decref(dict_sample, "period", PyLong_FromUnsignedLongLong(sample->period)); + pydict_set_item_string_decref(dict_sample, "phys_addr", + PyLong_FromUnsignedLongLong(sample->phys_addr)); set_sample_read_in_dict(dict_sample, sample, evsel); pydict_set_item_string_decref(dict, "sample", dict_sample);