torvalds/linux

View on GitHub
tools/perf/scripts/python/mem-phys-addr.py

Summary

Maintainability
C
1 day
Test Coverage
# mem-phys-addr.py: Resolve physical address samples
# SPDX-License-Identifier: GPL-2.0
#
# Copyright (c) 2018, Intel Corporation.

from __future__ import division
from __future__ import print_function

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(int(m[0], 16))
            system_ram.append(int(m[1], 16))
        if m[2].strip() == 'Persistent Memory':
            pmem.append(int(m[0], 16))
            pmem.append(int(m[1], 16))

def print_memory_type():
    print("Event: %s" % (event_name))
    print("%-40s  %10s  %10s\n" % ("Memory type", "count", "percentage"), end='')
    print("%-40s  %10s  %10s\n" % ("----------------------------------------",
                    "-----------", "-----------"),
                    end='');
    total = sum(load_mem_type_cnt.values())
    for mem_type, count in sorted(load_mem_type_cnt.most_common(), \
                    key = lambda kv: (kv[1], kv[0]), reverse = True):
        print("%-40s  %10d  %10.1f%%\n" %
            (mem_type, count, 100 * count / total),
            end='')

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 int(m[0], 16) <= phys_addr <= int(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