Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/94659/?format=api
https://patches.dpdk.org/api/patches/94659/?format=api", "web_url": "https://patches.dpdk.org/project/dpdk/patch/20210621152515.408384-1-mdr@ashroe.eu/", "project": { "id": 1, "url": "https://patches.dpdk.org/api/projects/1/?format=api", "name": "DPDK", "link_name": "dpdk", "list_id": "dev.dpdk.org", "list_email": "dev@dpdk.org", "web_url": "http://core.dpdk.org", "scm_url": "git://dpdk.org/dpdk", "webscm_url": "http://git.dpdk.org/dpdk", "list_archive_url": "https://inbox.dpdk.org/dev", "list_archive_url_format": "https://inbox.dpdk.org/dev/{}", "commit_url_format": "" }, "msgid": "<20210621152515.408384-1-mdr@ashroe.eu>", "list_archive_url": "https://inbox.dpdk.org/dev/20210621152515.408384-1-mdr@ashroe.eu", "date": "2021-06-21T15:25:15", "name": "[v3] devtools: script to track map symbols", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": true, "hash": "c144e2e9a9ca88f566542490760b7230544e50b8", "submitter": { "id": 1310, "url": "https://patches.dpdk.org/api/people/1310/?format=api", "name": "Ray Kinsella", "email": "mdr@ashroe.eu" }, "delegate": null, "mbox": "https://patches.dpdk.org/project/dpdk/patch/20210621152515.408384-1-mdr@ashroe.eu/mbox/", "series": [ { "id": 17428, "url": "https://patches.dpdk.org/api/series/17428/?format=api", "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=17428", "date": "2021-06-21T15:25:15", "name": "[v3] devtools: script to track map symbols", "version": 3, "mbox": "https://patches.dpdk.org/series/17428/mbox/" } ], "comments": "https://patches.dpdk.org/api/patches/94659/comments/", "check": "fail", "checks": "https://patches.dpdk.org/api/patches/94659/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<dev-bounces@dpdk.org>", "X-Original-To": "patchwork@inbox.dpdk.org", "Delivered-To": "patchwork@inbox.dpdk.org", "Received": [ "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id D21C3A0547;\n\tMon, 21 Jun 2021 17:33:27 +0200 (CEST)", "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id B95E3411B9;\n\tMon, 21 Jun 2021 17:33:27 +0200 (CEST)", "from mga05.intel.com (mga05.intel.com [192.55.52.43])\n by mails.dpdk.org (Postfix) with ESMTP id 36D8B41199\n for <dev@dpdk.org>; Mon, 21 Jun 2021 17:33:26 +0200 (CEST)", "from orsmga001.jf.intel.com ([10.7.209.18])\n by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 21 Jun 2021 08:33:25 -0700", "from silpixa00396680.ir.intel.com (HELO\n silpixa00396680.ger.corp.intel.com) ([10.237.223.54])\n by orsmga001.jf.intel.com with ESMTP; 21 Jun 2021 08:33:22 -0700" ], "IronPort-SDR": [ "\n dYjLC5FEScPrs6SRDLia0irggDLz6bsIAprUwhDmi/88Jy/FCmrbkxumFy7aD+BwLTkQN3vdR4\n tklWFxhQI1Yw==", "\n F9T2ZAAeUMdKiLBd79Uac3umuH5XtvIaEolwlgZTIqOqjXjIY8zNqZUmj1bQqMNwocD0zX1hME\n nfnSOgzYyyiA==" ], "X-IronPort-AV": [ "E=McAfee;i=\"6200,9189,10022\"; a=\"292498741\"", "E=Sophos;i=\"5.83,289,1616482800\"; d=\"scan'208\";a=\"292498741\"", "E=Sophos;i=\"5.83,289,1616482800\"; d=\"scan'208\";a=\"486530427\"" ], "X-ExtLoop1": "1", "From": "Ray Kinsella <mdr@ashroe.eu>", "To": "dev@dpdk.org", "Cc": "stephen@networkplumber.org, ferruh.yigit@intel.com, thomas@monjalon.net,\n ktraynor@redhat.com, bruce.richardson@intel.com, mdr@ashroe.eu", "Date": "Mon, 21 Jun 2021 16:25:15 +0100", "Message-Id": "<20210621152515.408384-1-mdr@ashroe.eu>", "X-Mailer": "git-send-email 2.26.2", "In-Reply-To": "<20210618163659.85933-1-mdr@ashroe.eu>", "References": "<20210618163659.85933-1-mdr@ashroe.eu>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Subject": "[dpdk-dev] [PATCH v3] devtools: script to track map symbols", "X-BeenThere": "dev@dpdk.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "DPDK patches and discussions <dev.dpdk.org>", "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>", "List-Archive": "<http://mails.dpdk.org/archives/dev/>", "List-Post": "<mailto:dev@dpdk.org>", "List-Help": "<mailto:dev-request@dpdk.org?subject=help>", "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>", "Errors-To": "dev-bounces@dpdk.org", "Sender": "\"dev\" <dev-bounces@dpdk.org>" }, "content": "Script to track growth of stable and experimental symbols\nover releases since v19.11.\n\nSigned-off-by: Ray Kinsella <mdr@ashroe.eu>\n---\nv2: reworked to fix pylint errors\nv3: sent with the current in-reply-to\n\n devtools/count_symbols.py | 262 ++++++++++++++++++++++++++++++++++++++\n 1 file changed, 262 insertions(+)\n create mode 100755 devtools/count_symbols.py", "diff": "diff --git a/devtools/count_symbols.py b/devtools/count_symbols.py\nnew file mode 100755\nindex 0000000000..30be09754f\n--- /dev/null\n+++ b/devtools/count_symbols.py\n@@ -0,0 +1,262 @@\n+#!/usr/bin/env python3\n+# SPDX-License-Identifier: BSD-3-Clause\n+# Copyright(c) 2021 Intel Corporation\n+'''Tool to count the number of symbols in each DPDK release'''\n+from pathlib import Path\n+import sys\n+import os\n+import subprocess\n+import argparse\n+import re\n+import datetime\n+\n+try:\n+ from parsley import makeGrammar\n+except ImportError:\n+ print('This script uses the package Parsley to parse C Mapfiles.\\n'\n+ 'This can be installed with \\\"pip install parsley\".')\n+ sys.exit()\n+\n+MAP_GRAMMAR = r\"\"\"\n+\n+ws = (' ' | '\\r' | '\\n' | '\\t')*\n+\n+ABI_VER = ({})\n+DPDK_VER = ('DPDK_' ABI_VER)\n+ABI_NAME = ('INTERNAL' | 'EXPERIMENTAL' | DPDK_VER)\n+comment = '#' (~'\\n' anything)+ '\\n'\n+symbol = (~(';' | '}}' | '#') anything )+:c ';' -> ''.join(c)\n+global = 'global:'\n+local = 'local: *;'\n+symbols = comment* symbol:s ws comment* -> s\n+\n+abi = (abi_section+):m -> dict(m)\n+abi_section = (ws ABI_NAME:e ws '{{' ws global* (~local ws symbols)*:s ws local* ws '}}' ws DPDK_VER* ';' ws) -> (e,s)\n+\"\"\"\n+\n+def get_abi_versions():\n+ '''Returns a string of possible dpdk abi versions'''\n+\n+ year = datetime.date.today().year - 2000\n+ tags = \" |\".join(['\\'{}\\''.format(i) \\\n+ for i in reversed(range(21, year + 1)) ])\n+ tags = tags + ' | \\'20.0.1\\' | \\'20.0\\' | \\'20\\''\n+\n+ return tags\n+\n+def get_dpdk_releases():\n+ '''Returns a list of dpdk release tags names since v19.11'''\n+\n+ year = datetime.date.today().year - 2000\n+ year_range = \"|\".join(\"{}\".format(i) for i in range(19,year + 1))\n+ pattern = re.compile(r'^\\\"v(' + year_range + r')\\.\\d{2}\\\"$')\n+\n+ cmd = ['git', 'for-each-ref', '--sort=taggerdate', '--format', '\"%(tag)\"']\n+ try:\n+ result = subprocess.run(cmd, \\\n+ stdout=subprocess.PIPE, \\\n+ stderr=subprocess.PIPE,\n+ check=True)\n+ except subprocess.CalledProcessError:\n+ print(\"Failed to interogate git for release tags\")\n+ sys.exit()\n+\n+ tags = result.stdout.decode('utf-8').split('\\n')\n+\n+ # find the non-rcs between now and v19.11\n+ tags = [ tag.replace('\\\"','') \\\n+ for tag in reversed(tags) \\\n+ if pattern.match(tag) ][:-3]\n+\n+ return tags\n+\n+def fix_directory_name(path):\n+ '''Prepend librte to the source directory name'''\n+ mapfilepath1 = str(path.parent.name)\n+ mapfilepath2 = str(path.parents[1])\n+ mapfilepath = mapfilepath2 + '/librte_' + mapfilepath1\n+\n+ return mapfilepath\n+\n+def directory_renamed(path, rel):\n+ '''Fix removal of the librte_ from the directory names'''\n+\n+ mapfilepath = fix_directory_name(path)\n+ tagfile = '{}:{}/{}'.format(rel, mapfilepath, path.name)\n+\n+ try:\n+ result = subprocess.run(['git', 'show', tagfile], \\\n+ stdout=subprocess.PIPE, \\\n+ stderr=subprocess.PIPE,\n+ check=True)\n+ except subprocess.CalledProcessError:\n+ result = None\n+\n+ return result\n+\n+def mapfile_renamed(path, rel):\n+ '''Fix renaming of map files'''\n+ newfile = None\n+\n+ result = subprocess.run(['git', 'ls-tree', \\\n+ rel, str(path.parent) + '/'], \\\n+ stdout=subprocess.PIPE, \\\n+ stderr=subprocess.PIPE,\n+ check=True)\n+ dentries = result.stdout.decode('utf-8')\n+ dentries = dentries.split('\\n')\n+\n+ # filter entries looking for the map file\n+ dentries = [dentry for dentry in dentries if dentry.endswith('.map')]\n+ if len(dentries) > 1 or len(dentries) == 0:\n+ return None\n+\n+ dparts = dentries[0].split('/')\n+ newfile = dparts[len(dparts) - 1]\n+\n+ if newfile is not None:\n+ tagfile = '{}:{}/{}'.format(rel, path.parent, newfile)\n+\n+ try:\n+ result = subprocess.run(['git', 'show', tagfile], \\\n+ stdout=subprocess.PIPE, \\\n+ stderr=subprocess.PIPE,\n+ check=True)\n+ except subprocess.CalledProcessError:\n+ result = None\n+\n+ else:\n+ result = None\n+\n+ return result\n+\n+def mapfile_and_directory_renamed(path, rel):\n+ '''Fix renaming of the map file & the source directory'''\n+ mapfilepath = Path(\"{}/{}\".format(fix_directory_name(path),path.name))\n+\n+ return mapfile_renamed(mapfilepath, rel)\n+\n+def get_terminal_rows():\n+ '''Find the number of rows in the terminal'''\n+\n+ rows, _ = os.popen('stty size', 'r').read().split()\n+ return int(rows)\n+\n+class FormatOutput():\n+ '''Format the output to supported formats'''\n+ output_fmt = \"\"\n+ column_fmt = \"\"\n+\n+ def __init__(self, format_output, dpdk_releases):\n+ self.OUTPUT_FORMATS[format_output](self,dpdk_releases)\n+ self.column_titles = ['mapfile'] + dpdk_releases\n+\n+ self.terminal_rows = get_terminal_rows()\n+ self.row = 0\n+\n+ def set_terminal_output(self,dpdk_rel):\n+ '''Set the output format to Tabbed Seperated Values'''\n+\n+ self.output_fmt = '{:<50}' + \\\n+ ''.join(['{:<6}{:<6}'] * (len(dpdk_rel)))\n+ self.column_fmt = '{:50}' + \\\n+ ''.join(['{:<12}'] * (len(dpdk_rel)))\n+\n+ def set_csv_output(self,dpdk_rel):\n+ '''Set the output format to Comma Seperated Values'''\n+\n+ self.output_fmt = '{},' + \\\n+ ','.join(['{},{}'] * (len(dpdk_rel)))\n+ self.column_fmt = '{},' + \\\n+ ','.join(['{},'] * (len(dpdk_rel)))\n+\n+ def print_columns(self):\n+ '''Print column rows with release names'''\n+ print(self.column_fmt.format(*self.column_titles))\n+ self.row += 1\n+\n+ def print_row(self,symbols):\n+ '''Print row of symbol values'''\n+ print(self.output_fmt.format(*symbols))\n+ self.row += 1\n+\n+ if((self.terminal_rows>0) and ((self.row % self.terminal_rows) == 0)):\n+ self.print_columns()\n+\n+ OUTPUT_FORMATS = { None: set_terminal_output, \\\n+ 'terminal': set_terminal_output, \\\n+ 'csv': set_csv_output }\n+\n+SRC_DIRECTORIES = 'drivers, lib'\n+IGNORE_SECTIONS = ['EXPERIMENTAL','INTERNAL']\n+FIX_STRATEGIES = [directory_renamed, \\\n+ mapfile_renamed, \\\n+ mapfile_and_directory_renamed]\n+\n+def count_release_symbols(map_parser, release, mapfile_path):\n+ '''Count the symbols for a given release and mapfile'''\n+ csym = [0] * 2\n+ abi_sections = None\n+\n+ tagfile = '{}:{}'.format(release,mapfile_path)\n+ try:\n+ result = subprocess.run(['git', 'show', tagfile], \\\n+ stdout=subprocess.PIPE, \\\n+ stderr=subprocess.PIPE,\n+ check=True)\n+ except subprocess.CalledProcessError:\n+ result = None\n+\n+ for fix_strategy in FIX_STRATEGIES:\n+ if result is not None:\n+ break\n+ result = fix_strategy(mapfile_path, release)\n+\n+ if result is not None:\n+ mapfile = result.stdout.decode('utf-8')\n+ abi_sections = map_parser(mapfile).abi()\n+\n+ if abi_sections is not None:\n+ # which versions are present, and we care about\n+ found_ver = [ver \\\n+ for ver in abi_sections \\\n+ if ver not in IGNORE_SECTIONS]\n+\n+ for ver in found_ver:\n+ csym[0] += len(abi_sections[ver])\n+\n+ # count experimental symbols\n+ if 'EXPERIMENTAL' in abi_sections:\n+ csym[1] = len(abi_sections['EXPERIMENTAL'])\n+\n+ return csym\n+\n+def main():\n+ '''Main entry point'''\n+\n+ parser = argparse.ArgumentParser(description='Count symbols in DPDK Libs')\n+ parser.add_argument('--format-output', choices=['terminal','csv'], \\\n+ default='terminal')\n+ parser.add_argument('--directory', choices=SRC_DIRECTORIES,\n+ default=SRC_DIRECTORIES)\n+ args = parser.parse_args()\n+\n+ dpdk_releases = get_dpdk_releases()\n+ format_output = FormatOutput(args.format_output, dpdk_releases)\n+\n+ map_grammar = MAP_GRAMMAR.format(get_abi_versions())\n+ map_parser = makeGrammar(map_grammar, {})\n+\n+ format_output.print_columns()\n+ for src_dir in args.directory.split(','):\n+ for path in Path(src_dir).rglob('*.map'):\n+ relsym = [str(path)]\n+\n+ for release in dpdk_releases:\n+ csym = count_release_symbols(map_parser, release, path)\n+ relsym += csym\n+\n+ format_output.print_row(relsym)\n+\n+if __name__ == '__main__':\n+ main()\n", "prefixes": [ "v3" ] }{ "id": 94659, "url": "