10e9727dbSSeth Howell#!/usr/bin/env python3 217538bdcSpaul luse# SPDX-License-Identifier: BSD-3-Clause 317538bdcSpaul luse# Copyright (C) 2019 Intel Corporation 417538bdcSpaul luse# All rights reserved. 517538bdcSpaul luse# 60e9727dbSSeth Howell 70e9727dbSSeth Howellimport argparse 80e9727dbSSeth Howellimport os 90e9727dbSSeth Howellfrom enum import Enum 100e9727dbSSeth Howell 110e9727dbSSeth Howell 120e9727dbSSeth Howellclass memory: 130e9727dbSSeth Howell def __init__(self, size): 140e9727dbSSeth Howell self.size = size 150e9727dbSSeth Howell self.heaps = [] 160e9727dbSSeth Howell self.mempools = [] 170e9727dbSSeth Howell self.memzones = [] 180e9727dbSSeth Howell 190e9727dbSSeth Howell def get_size(self): 200e9727dbSSeth Howell return self.size 210e9727dbSSeth Howell 220e9727dbSSeth Howell def add_mempool(self, pool): 230e9727dbSSeth Howell self.mempools.append(pool) 240e9727dbSSeth Howell 250e9727dbSSeth Howell def add_memzone(self, zone): 260e9727dbSSeth Howell self.memzones.append(zone) 270e9727dbSSeth Howell 280e9727dbSSeth Howell def add_heap(self, heap): 290e9727dbSSeth Howell self.heaps.append(heap) 300e9727dbSSeth Howell 310e9727dbSSeth Howell def get_total_heap_size(self): 320e9727dbSSeth Howell size = 0 330e9727dbSSeth Howell for heap in self.heaps: 340e9727dbSSeth Howell size = size + heap.size 350e9727dbSSeth Howell return size 360e9727dbSSeth Howell 370e9727dbSSeth Howell def get_total_mempool_size(self): 380e9727dbSSeth Howell size = 0 390e9727dbSSeth Howell for pool in self.mempools: 400e9727dbSSeth Howell size = size + pool.get_memzone_size_sum() 410e9727dbSSeth Howell return size 420e9727dbSSeth Howell 430e9727dbSSeth Howell def get_total_memzone_size(self): 440e9727dbSSeth Howell size = 0 450e9727dbSSeth Howell for zone in self.memzones: 460e9727dbSSeth Howell size = size + zone.size 470e9727dbSSeth Howell return size 480e9727dbSSeth Howell 490e9727dbSSeth Howell def print_summary(self): 500e9727dbSSeth Howell print("DPDK memory size {} in {} heap(s)" 510e9727dbSSeth Howell .format(B_to_MiB(self.size), len(self.heaps))) 520e9727dbSSeth Howell print("{} heaps totaling size {}".format(len(self.heaps), B_to_MiB(self.get_total_heap_size()))) 530e9727dbSSeth Howell for x in sorted(self.heaps, key=lambda x: x.size, reverse=True): 540e9727dbSSeth Howell x.print_summary(' ') 550e9727dbSSeth Howell print("end heaps----------") 560e9727dbSSeth Howell print("{} mempools totaling size {}".format(len(self.mempools), B_to_MiB(self.get_total_mempool_size()))) 570e9727dbSSeth Howell for x in sorted(self.mempools, key=lambda x: x.get_memzone_size_sum(), reverse=True): 580e9727dbSSeth Howell x.print_summary(' ') 590e9727dbSSeth Howell print("end mempools-------") 600e9727dbSSeth Howell print("{} memzones totaling size {}".format(len(self.memzones), B_to_MiB(self.get_total_memzone_size()))) 610e9727dbSSeth Howell for x in sorted(self.memzones, key=lambda x: x.size, reverse=True): 620e9727dbSSeth Howell x.print_summary(' ') 630e9727dbSSeth Howell print("end memzones-------") 640e9727dbSSeth Howell 650e9727dbSSeth Howell def print_heap_summary(self, heap_id): 660e9727dbSSeth Howell for heap in self.heaps: 670e9727dbSSeth Howell if heap_id == heap.id: 680e9727dbSSeth Howell heap.print_detailed_stats() 690e9727dbSSeth Howell break 700e9727dbSSeth Howell else: 710e9727dbSSeth Howell print("heap id {} is invalid. please see the summary for valid heaps.\n".format(heap_id)) 720e9727dbSSeth Howell 730e9727dbSSeth Howell def print_mempool_summary(self, name): 740e9727dbSSeth Howell for pool in self.mempools: 750e9727dbSSeth Howell if name == pool.name: 760e9727dbSSeth Howell pool.print_detailed_stats() 770e9727dbSSeth Howell break 780e9727dbSSeth Howell else: 790e9727dbSSeth Howell print("mempool name {} is invalid. please see the summary for valid mempools.\n".format(name)) 800e9727dbSSeth Howell 810e9727dbSSeth Howell def print_memzone_summary(self, name): 820e9727dbSSeth Howell for zone in self.memzones: 830e9727dbSSeth Howell if name == zone.name: 840e9727dbSSeth Howell zone.print_detailed_stats("") 850e9727dbSSeth Howell break 860e9727dbSSeth Howell else: 870e9727dbSSeth Howell print("memzone name {} is invalid. please see the summary for valid memzone.\n".format(name)) 880e9727dbSSeth Howell 890e9727dbSSeth Howell def associate_heap_elements_and_memzones(self): 900e9727dbSSeth Howell for zone in self.memzones: 910e9727dbSSeth Howell for heap_obj in self.heaps: 920e9727dbSSeth Howell for element in heap_obj.busy_malloc_elements: 930e9727dbSSeth Howell if element.check_memzone_compatibility(zone): 940e9727dbSSeth Howell heap_obj.busy_memzone_elements.append(element) 950e9727dbSSeth Howell heap_obj.busy_malloc_elements.remove(element) 960e9727dbSSeth Howell 970e9727dbSSeth Howell def associate_memzones_and_mempools(self): 980e9727dbSSeth Howell for pool in self.mempools: 990e9727dbSSeth Howell for zone in self.memzones: 1000e9727dbSSeth Howell if pool.name in zone.name: 1010e9727dbSSeth Howell pool.add_memzone(zone) 1020e9727dbSSeth Howell 1030e9727dbSSeth Howell for pool in self.mempools: 1040e9727dbSSeth Howell for zone in pool.memzones: 1050e9727dbSSeth Howell if zone in self.memzones: 1060e9727dbSSeth Howell self.memzones.remove(zone) 1070e9727dbSSeth Howell 1080e9727dbSSeth Howell 1090e9727dbSSeth Howellclass heap_elem_status(Enum): 1100e9727dbSSeth Howell FREE = 0 1110e9727dbSSeth Howell BUSY = 1 1120e9727dbSSeth Howell 1130e9727dbSSeth Howell 1140e9727dbSSeth Howellclass heap_element: 1150e9727dbSSeth Howell def __init__(self, size, status, addr): 1160e9727dbSSeth Howell self.status = status 1170e9727dbSSeth Howell self.size = size 1180e9727dbSSeth Howell self.addr = addr 1190e9727dbSSeth Howell self.memzone = None 1200e9727dbSSeth Howell 1210e9727dbSSeth Howell def print_summary(self, header): 1220e9727dbSSeth Howell print("{}element at address: {} with size: {:>15}".format(header, hex(self.addr), B_to_MiB(self.size))) 1230e9727dbSSeth Howell 1240e9727dbSSeth Howell def check_memzone_compatibility(self, memzone): 1250e9727dbSSeth Howell ele_fini_addr = self.addr + self.size 1260e9727dbSSeth Howell memzone_fini_addr = memzone.address + memzone.size 1270e9727dbSSeth Howell if (self.addr <= memzone.address and ele_fini_addr >= memzone_fini_addr): 1280e9727dbSSeth Howell self.memzone = memzone 1290e9727dbSSeth Howell return True 1300e9727dbSSeth Howell return False 1310e9727dbSSeth Howell 1320e9727dbSSeth Howell 1330e9727dbSSeth Howellclass heap: 1340e9727dbSSeth Howell def __init__(self, id, size, num_allocations): 1350e9727dbSSeth Howell self.id = id 1360e9727dbSSeth Howell self.size = size 1370e9727dbSSeth Howell self.num_allocations = num_allocations 1380e9727dbSSeth Howell self.free_elements = [] 1390e9727dbSSeth Howell self.busy_malloc_elements = [] 1400e9727dbSSeth Howell self.busy_memzone_elements = [] 1410e9727dbSSeth Howell 1420e9727dbSSeth Howell def add_element(self, element): 1430e9727dbSSeth Howell if element.status == heap_elem_status.FREE: 1440e9727dbSSeth Howell self.free_elements.append(element) 1450e9727dbSSeth Howell else: 1460e9727dbSSeth Howell self.busy_malloc_elements.append(element) 1470e9727dbSSeth Howell 1480e9727dbSSeth Howell def print_element_stats(self, list_to_print, list_type, header): 1490e9727dbSSeth Howell print("{}list of {} elements. size: {}".format(header, list_type, B_to_MiB(self.get_element_size(list_to_print)))) 1500e9727dbSSeth Howell for x in sorted(list_to_print, key=lambda x: x.size, reverse=True): 1510e9727dbSSeth Howell x.print_summary("{} ".format(header)) 1520e9727dbSSeth Howell if x.memzone is not None: 1530e9727dbSSeth Howell x.memzone.print_summary(" {}associated memzone info: ".format(header)) 1540e9727dbSSeth Howell 1550e9727dbSSeth Howell def get_element_size(self, list_to_check): 1560e9727dbSSeth Howell size = 0 1570e9727dbSSeth Howell for element in list_to_check: 1580e9727dbSSeth Howell size = size + element.size 1590e9727dbSSeth Howell return size 1600e9727dbSSeth Howell 1610e9727dbSSeth Howell def print_summary(self, header): 1620e9727dbSSeth Howell print("{}size: {:>15} heap id: {}".format(header, B_to_MiB(self.size), self.id)) 1630e9727dbSSeth Howell 1640e9727dbSSeth Howell def print_detailed_stats(self): 1650e9727dbSSeth Howell print("heap id: {} total size: {} number of busy elements: {} number of free elements: {}" 1660e9727dbSSeth Howell .format(self.id, B_to_MiB(self.size), len(self.busy_malloc_elements), len(self.free_elements))) 1670e9727dbSSeth Howell self.print_element_stats(self.free_elements, "free", " ") 1680e9727dbSSeth Howell self.print_element_stats(self.busy_malloc_elements, "standard malloc", " ") 1690e9727dbSSeth Howell self.print_element_stats(self.busy_memzone_elements, "memzone associated", " ") 1700e9727dbSSeth Howell 1710e9727dbSSeth Howell 1720e9727dbSSeth Howellclass mempool: 1730e9727dbSSeth Howell def __init__(self, name, num_objs, num_populated_objs, obj_size): 1740e9727dbSSeth Howell self.name = name 1750e9727dbSSeth Howell self.num_objs = num_objs 1760e9727dbSSeth Howell self.num_populated_objs = num_populated_objs 1770e9727dbSSeth Howell self.obj_size = obj_size 1780e9727dbSSeth Howell self.memzones = [] 1790e9727dbSSeth Howell 1800e9727dbSSeth Howell def add_memzone(self, memzone): 1810e9727dbSSeth Howell self.memzones.append(memzone) 1820e9727dbSSeth Howell 1830e9727dbSSeth Howell def get_memzone_size_sum(self): 1840e9727dbSSeth Howell size = 0 1850e9727dbSSeth Howell for zone in self.memzones: 1860e9727dbSSeth Howell size = size + zone.size 1870e9727dbSSeth Howell return size 1880e9727dbSSeth Howell 1890e9727dbSSeth Howell def print_summary(self, header): 1900e9727dbSSeth Howell print("{}size: {:>15} name: {}" 1910e9727dbSSeth Howell .format(header, B_to_MiB(self.get_memzone_size_sum()), self.name)) 1920e9727dbSSeth Howell 1930e9727dbSSeth Howell def print_detailed_stats(self): 1940e9727dbSSeth Howell print("size: {:>15} name: {} comprised of {} memzone(s):" 1950e9727dbSSeth Howell .format(B_to_MiB(self.get_memzone_size_sum()), self.name, len(self.memzones))) 1960e9727dbSSeth Howell for x in sorted(self.memzones, key=lambda x: x.size, reverse=True): 1970e9727dbSSeth Howell x.print_detailed_stats(" ") 1980e9727dbSSeth Howell 1990e9727dbSSeth Howell 2000e9727dbSSeth Howellclass memzone: 2010e9727dbSSeth Howell def __init__(self, name, size, address): 2020e9727dbSSeth Howell self.name = name 2030e9727dbSSeth Howell self.size = size 2040e9727dbSSeth Howell self.address = address 2050e9727dbSSeth Howell self.segments = [] 2060e9727dbSSeth Howell 2070e9727dbSSeth Howell def add_segment(self, segment): 2080e9727dbSSeth Howell self.segments.append(segment) 2090e9727dbSSeth Howell 2100e9727dbSSeth Howell def print_summary(self, header): 2110e9727dbSSeth Howell print("{}size: {:>15} name: {}".format(header, B_to_MiB(self.size), self.name)) 2120e9727dbSSeth Howell 2130e9727dbSSeth Howell def print_detailed_stats(self, header): 2140e9727dbSSeth Howell self.print_summary(header) 2150e9727dbSSeth Howell print("{}located at address {}".format(header, hex(self.address))) 2160e9727dbSSeth Howell print("{}spanning {} segment(s):".format(header, len(self.segments))) 2170e9727dbSSeth Howell for x in sorted(self.segments, key=lambda x: x.size, reverse=True): 2180e9727dbSSeth Howell x.print_summary(' ') 2190e9727dbSSeth Howell 2200e9727dbSSeth Howell 2210e9727dbSSeth Howellclass segment: 2220e9727dbSSeth Howell def __init__(self, size, address): 2230e9727dbSSeth Howell self.size = size 2240e9727dbSSeth Howell self.address = address 2250e9727dbSSeth Howell 2260e9727dbSSeth Howell def print_summary(self, header): 2270e9727dbSSeth Howell print("{}address: {} length: {:>15}".format(header, hex(self.address), B_to_MiB(self.size))) 2280e9727dbSSeth Howell 2290e9727dbSSeth Howell 2300e9727dbSSeth Howellclass parse_state(Enum): 2310e9727dbSSeth Howell PARSE_MEMORY_SIZE = 0 2320e9727dbSSeth Howell PARSE_MEMZONES = 1 2330e9727dbSSeth Howell PARSE_MEMZONE_SEGMENTS = 2 2340e9727dbSSeth Howell PARSE_MEMPOOLS = 3 2350e9727dbSSeth Howell PARSE_MEMPOOL_INFO = 4 2360e9727dbSSeth Howell PARSE_HEAPS = 5 2370e9727dbSSeth Howell PARSE_HEAP_ELEMENTS = 6 2380e9727dbSSeth Howell 2390e9727dbSSeth Howell 2400e9727dbSSeth Howelldef B_to_MiB(raw_value): 2410e9727dbSSeth Howell raw_value = raw_value / (1024.0 * 1024.0) 2420e9727dbSSeth Howell 2430e9727dbSSeth Howell return "%6f %s" % (raw_value, "MiB") 2440e9727dbSSeth Howell 2450e9727dbSSeth Howell 2460e9727dbSSeth Howelldef parse_zone(line): 2470e9727dbSSeth Howell zone, info = line.split(':', 1) 2480e9727dbSSeth Howell name, length, addr, trash = info.split(',', 3) 2490e9727dbSSeth Howell 2500e9727dbSSeth Howell trash, name = name.split(':', 1) 2510e9727dbSSeth Howell name = name.replace("<", "") 2520e9727dbSSeth Howell name = name.replace(">", "") 2530e9727dbSSeth Howell trash, length = length.split(':', 1) 2540e9727dbSSeth Howell trash, addr = addr.split(':', 1) 2550e9727dbSSeth Howell 2560e9727dbSSeth Howell return memzone(name, int(length, 0), int(addr, 0)) 2570e9727dbSSeth Howell 2580e9727dbSSeth Howell 2590e9727dbSSeth Howelldef parse_segment(line): 2600e9727dbSSeth Howell trash, addr, iova, length, pagesz = line.split(':') 2610e9727dbSSeth Howell addr, trash = addr.strip().split(' ') 2620e9727dbSSeth Howell length, trash = length.strip().split(' ') 2630e9727dbSSeth Howell 2640e9727dbSSeth Howell return segment(int(length, 0), int(addr, 0)) 2650e9727dbSSeth Howell 2660e9727dbSSeth Howell 2670e9727dbSSeth Howelldef parse_mempool_name(line): 2680e9727dbSSeth Howell name, addr = line.split('@') 2690e9727dbSSeth Howell name = name.replace("<", "") 2700e9727dbSSeth Howell name = name.replace(">", "") 271*2e1c5a72SJim Harris trash, sep, name = name.partition(' ') 2720e9727dbSSeth Howell 2730e9727dbSSeth Howell return name 2740e9727dbSSeth Howell 2750e9727dbSSeth Howell 2760e9727dbSSeth Howelldef parse_mem_stats(stat_path): 2770e9727dbSSeth Howell state = parse_state.PARSE_MEMORY_SIZE 2780e9727dbSSeth Howell with open(stat_path, "r") as stats: 2790e9727dbSSeth Howell 2800e9727dbSSeth Howell line = stats.readline() 2810e9727dbSSeth Howell while line != '': 2820e9727dbSSeth Howell if state == parse_state.PARSE_MEMORY_SIZE: 2830e9727dbSSeth Howell if "DPDK memory size" in line: 2840e9727dbSSeth Howell mem_size = int(line.replace("DPDK memory size ", "")) 2850e9727dbSSeth Howell memory_struct = memory(mem_size) 2860e9727dbSSeth Howell state = parse_state.PARSE_MEMZONES 2870e9727dbSSeth Howell line = stats.readline() 2880e9727dbSSeth Howell 2890e9727dbSSeth Howell if state == parse_state.PARSE_MEMZONES: 2900e9727dbSSeth Howell if line.find("Zone") == 0: 2910e9727dbSSeth Howell zone = parse_zone(line) 29212aefaa0STomasz Zawadzki memory_struct.add_memzone(zone) 2930e9727dbSSeth Howell state = parse_state.PARSE_MEMZONE_SEGMENTS 2940e9727dbSSeth Howell line = stats.readline() 2950e9727dbSSeth Howell 2960e9727dbSSeth Howell if state == parse_state.PARSE_MEMZONE_SEGMENTS: 2970e9727dbSSeth Howell if line.find("Zone") == 0: 2980e9727dbSSeth Howell state = parse_state.PARSE_MEMZONES 2990e9727dbSSeth Howell continue 3000e9727dbSSeth Howell elif line.lstrip().find("addr:") == 0: 3010e9727dbSSeth Howell segment = parse_segment(line) 3020e9727dbSSeth Howell zone.add_segment(segment) 3030e9727dbSSeth Howell elif "DPDK mempools." in line: 3040e9727dbSSeth Howell state = parse_state.PARSE_MEMPOOLS 3050e9727dbSSeth Howell continue 3060e9727dbSSeth Howell line = stats.readline() 3070e9727dbSSeth Howell 3080e9727dbSSeth Howell if state == parse_state.PARSE_MEMPOOLS: 3090e9727dbSSeth Howell mempool_info = {} 3100e9727dbSSeth Howell if line.find("mempool") == 0: 3110e9727dbSSeth Howell mempool_info['name'] = parse_mempool_name(line) 3120e9727dbSSeth Howell state = parse_state.PARSE_MEMPOOL_INFO 3130e9727dbSSeth Howell line = stats.readline() 3140e9727dbSSeth Howell 3150e9727dbSSeth Howell if state == parse_state.PARSE_MEMPOOL_INFO: 3160e9727dbSSeth Howell if line.find("mempool") == 0: 3170e9727dbSSeth Howell try: 3180e9727dbSSeth Howell new_mempool = mempool(mempool_info['name'], int(mempool_info['size'], 0), 3190e9727dbSSeth Howell int(mempool_info['populated_size'], 0), int(mempool_info['total_obj_size'], 0)) 3200e9727dbSSeth Howell memory_struct.add_mempool(new_mempool) 3210e9727dbSSeth Howell except KeyError: 3220e9727dbSSeth Howell print("proper key values not provided for mempool.") 3230e9727dbSSeth Howell state = parse_state.PARSE_MEMPOOLS 3240e9727dbSSeth Howell continue 3250e9727dbSSeth Howell elif "cache" in line: 3260e9727dbSSeth Howell pass 3270e9727dbSSeth Howell elif "DPDK malloc stats." in line: 3280e9727dbSSeth Howell try: 3290e9727dbSSeth Howell new_mempool = mempool(mempool_info['name'], int(mempool_info['size'], 0), 3300e9727dbSSeth Howell int(mempool_info['populated_size'], 0), int(mempool_info['total_obj_size'], 0)) 3310e9727dbSSeth Howell memory_struct.add_mempool(new_mempool) 3320e9727dbSSeth Howell except KeyError: 3330e9727dbSSeth Howell print("proper key values not provided for mempool.") 3340e9727dbSSeth Howell while "DPDK malloc heaps." not in line: 3350e9727dbSSeth Howell line = stats.readline() 3360e9727dbSSeth Howell state = parse_state.PARSE_HEAPS 3370e9727dbSSeth Howell else: 3380e9727dbSSeth Howell try: 3390e9727dbSSeth Howell field, value = line.strip().split('=') 3400e9727dbSSeth Howell mempool_info[field] = value 3410e9727dbSSeth Howell except Exception as e: 3420e9727dbSSeth Howell pass 3430e9727dbSSeth Howell line = stats.readline() 3440e9727dbSSeth Howell 3450e9727dbSSeth Howell if state == parse_state.PARSE_HEAPS: 3460e9727dbSSeth Howell trash, heap_id = line.strip().split(':') 3470e9727dbSSeth Howell line = stats.readline() 3480e9727dbSSeth Howell trash, heap_size = line.split(':') 3490e9727dbSSeth Howell line = stats.readline() 3500e9727dbSSeth Howell trash, num_allocations = line.split(':') 3510e9727dbSSeth Howell if int(heap_size, 0) == 0: 3520e9727dbSSeth Howell pass 3530e9727dbSSeth Howell else: 3540e9727dbSSeth Howell new_heap = heap(heap_id.lstrip(), int(heap_size, 0), int(num_allocations, 0)) 3550e9727dbSSeth Howell memory_struct.add_heap(new_heap) 3560e9727dbSSeth Howell state = parse_state.PARSE_HEAP_ELEMENTS 3570e9727dbSSeth Howell 3580e9727dbSSeth Howell line = stats.readline() 3590e9727dbSSeth Howell 3600e9727dbSSeth Howell if state == parse_state.PARSE_HEAP_ELEMENTS: 3610e9727dbSSeth Howell if line.find("Heap id") == 0: 3620e9727dbSSeth Howell state = parse_state.PARSE_HEAPS 3630e9727dbSSeth Howell continue 3640e9727dbSSeth Howell elif line.find("Malloc element at") == 0: 3650e9727dbSSeth Howell trash, address, status = line.rsplit(maxsplit=2) 3660e9727dbSSeth Howell line = stats.readline() 3670e9727dbSSeth Howell trash, length, trash = line.split(maxsplit=2) 3680e9727dbSSeth Howell line = stats.readline() 3690e9727dbSSeth Howell if "FREE" in status: 3700e9727dbSSeth Howell element = heap_element(int(length, 0), heap_elem_status.FREE, int(address, 0)) 3710e9727dbSSeth Howell else: 3720e9727dbSSeth Howell element = heap_element(int(length, 0), heap_elem_status.BUSY, int(address, 0)) 3730e9727dbSSeth Howell new_heap.add_element(element) 3740e9727dbSSeth Howell line = stats.readline() 3750e9727dbSSeth Howell 3760e9727dbSSeth Howell memory_struct.associate_heap_elements_and_memzones() 3770e9727dbSSeth Howell memory_struct.associate_memzones_and_mempools() 3780e9727dbSSeth Howell return memory_struct 3790e9727dbSSeth Howell 3800e9727dbSSeth Howell 3810e9727dbSSeth Howellif __name__ == "__main__": 3820e9727dbSSeth Howell parser = argparse.ArgumentParser(description='Dumps memory stats for DPDK. If no arguments are provided, it dumps a general summary.') 3830e9727dbSSeth Howell parser.add_argument('-f', dest="stats_file", help='path to a dpdk memory stats file.', default='/tmp/spdk_mem_dump.txt') 3840e9727dbSSeth Howell parser.add_argument('-m', '--heap', dest="heap", help='Print detailed information about the given heap.', default=None) 3850e9727dbSSeth Howell parser.add_argument('-p', '--mempool', dest="mempool", help='Print detailed information about the given mempool.', default=None) 3860e9727dbSSeth Howell parser.add_argument('-z', '--memzone', dest="memzone", help='Print detailed information about the given memzone.', default=None) 3870e9727dbSSeth Howell 3880e9727dbSSeth Howell args = parser.parse_args() 3890e9727dbSSeth Howell 3900e9727dbSSeth Howell if not os.path.exists(args.stats_file): 3910e9727dbSSeth Howell print("Error, specified stats file does not exist. Please make sure you have run the " 3920e9727dbSSeth Howell "env_dpdk_get_mem_stats rpc on the spdk app you want to analyze.") 3930e9727dbSSeth Howell exit(1) 3940e9727dbSSeth Howell 3950e9727dbSSeth Howell mem_info = parse_mem_stats(args.stats_file) 3960e9727dbSSeth Howell 3970e9727dbSSeth Howell summary = True 3980e9727dbSSeth Howell if args.heap is not None: 3990e9727dbSSeth Howell mem_info.print_heap_summary(args.heap) 4000e9727dbSSeth Howell summary = False 4010e9727dbSSeth Howell if args.mempool is not None: 4020e9727dbSSeth Howell mem_info.print_mempool_summary(args.mempool) 4030e9727dbSSeth Howell summary = False 4040e9727dbSSeth Howell if args.memzone is not None: 4050e9727dbSSeth Howell mem_info.print_memzone_summary(args.memzone) 4060e9727dbSSeth Howell summary = False 4070e9727dbSSeth Howell 4080e9727dbSSeth Howell if summary: 4090e9727dbSSeth Howell mem_info.print_summary() 410