mem-phys-addr.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. # mem-phys-addr.py: Resolve physical address samples
  2. # SPDX-License-Identifier: GPL-2.0
  3. #
  4. # Copyright (c) 2018, Intel Corporation.
  5. from __future__ import division
  6. from __future__ import print_function
  7. import os
  8. import sys
  9. import struct
  10. import re
  11. import bisect
  12. import collections
  13. sys.path.append(os.environ['PERF_EXEC_PATH'] + \
  14. '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
  15. #physical address ranges for System RAM
  16. system_ram = []
  17. #physical address ranges for Persistent Memory
  18. pmem = []
  19. #file object for proc iomem
  20. f = None
  21. #Count for each type of memory
  22. load_mem_type_cnt = collections.Counter()
  23. #perf event name
  24. event_name = None
  25. def parse_iomem():
  26. global f
  27. f = open('/proc/iomem', 'r')
  28. for i, j in enumerate(f):
  29. m = re.split('-|:',j,2)
  30. if m[2].strip() == 'System RAM':
  31. system_ram.append(int(m[0], 16))
  32. system_ram.append(int(m[1], 16))
  33. if m[2].strip() == 'Persistent Memory':
  34. pmem.append(int(m[0], 16))
  35. pmem.append(int(m[1], 16))
  36. def print_memory_type():
  37. print("Event: %s" % (event_name))
  38. print("%-40s %10s %10s\n" % ("Memory type", "count", "percentage"), end='')
  39. print("%-40s %10s %10s\n" % ("----------------------------------------",
  40. "-----------", "-----------"),
  41. end='');
  42. total = sum(load_mem_type_cnt.values())
  43. for mem_type, count in sorted(load_mem_type_cnt.most_common(), \
  44. key = lambda kv: (kv[1], kv[0]), reverse = True):
  45. print("%-40s %10d %10.1f%%\n" %
  46. (mem_type, count, 100 * count / total),
  47. end='')
  48. def trace_begin():
  49. parse_iomem()
  50. def trace_end():
  51. print_memory_type()
  52. f.close()
  53. def is_system_ram(phys_addr):
  54. #/proc/iomem is sorted
  55. position = bisect.bisect(system_ram, phys_addr)
  56. if position % 2 == 0:
  57. return False
  58. return True
  59. def is_persistent_mem(phys_addr):
  60. position = bisect.bisect(pmem, phys_addr)
  61. if position % 2 == 0:
  62. return False
  63. return True
  64. def find_memory_type(phys_addr):
  65. if phys_addr == 0:
  66. return "N/A"
  67. if is_system_ram(phys_addr):
  68. return "System RAM"
  69. if is_persistent_mem(phys_addr):
  70. return "Persistent Memory"
  71. #slow path, search all
  72. f.seek(0, 0)
  73. for j in f:
  74. m = re.split('-|:',j,2)
  75. if int(m[0], 16) <= phys_addr <= int(m[1], 16):
  76. return m[2]
  77. return "N/A"
  78. def process_event(param_dict):
  79. name = param_dict["ev_name"]
  80. sample = param_dict["sample"]
  81. phys_addr = sample["phys_addr"]
  82. global event_name
  83. if event_name == None:
  84. event_name = name
  85. load_mem_type_cnt[find_memory_type(phys_addr)] += 1