Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/3487/?format=api
http://patches.dpdk.org/api/patches/3487/?format=api", "web_url": "http://patches.dpdk.org/project/dpdk/patch/1424348324-29932-2-git-send-email-pawelx.wodkowski@intel.com/", "project": { "id": 1, "url": "http://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": "<1424348324-29932-2-git-send-email-pawelx.wodkowski@intel.com>", "list_archive_url": "https://inbox.dpdk.org/dev/1424348324-29932-2-git-send-email-pawelx.wodkowski@intel.com", "date": "2015-02-19T12:18:42", "name": "[dpdk-dev,v5,1/3] librte_headroom: New library for checking core/system/app load", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": true, "hash": "0b4a411130ace78b94e0a9a71f377d1b7441e171", "submitter": { "id": 58, "url": "http://patches.dpdk.org/api/people/58/?format=api", "name": "Wodkowski, PawelX", "email": "pawelx.wodkowski@intel.com" }, "delegate": null, "mbox": "http://patches.dpdk.org/project/dpdk/patch/1424348324-29932-2-git-send-email-pawelx.wodkowski@intel.com/mbox/", "series": [], "comments": "http://patches.dpdk.org/api/patches/3487/comments/", "check": "pending", "checks": "http://patches.dpdk.org/api/patches/3487/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<dev-bounces@dpdk.org>", "X-Original-To": "patchwork@dpdk.org", "Delivered-To": "patchwork@dpdk.org", "Received": [ "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id 3A44FB5A1;\n\tThu, 19 Feb 2015 13:22:35 +0100 (CET)", "from mga14.intel.com (mga14.intel.com [192.55.52.115])\n\tby dpdk.org (Postfix) with ESMTP id 1E208B53A\n\tfor <dev@dpdk.org>; Thu, 19 Feb 2015 13:22:31 +0100 (CET)", "from orsmga002.jf.intel.com ([10.7.209.21])\n\tby fmsmga103.fm.intel.com with ESMTP; 19 Feb 2015 04:14:53 -0800", "from unknown (HELO Sent) ([10.217.248.233])\n\tby orsmga002.jf.intel.com with SMTP; 19 Feb 2015 04:22:29 -0800", "by Sent (sSMTP sendmail emulation); Thu, 19 Feb 2015 13:21:13 +0100" ], "X-ExtLoop1": "1", "X-IronPort-AV": "E=Sophos;i=\"5.09,512,1418112000\"; d=\"scan'208\";a=\"687859191\"", "From": "Pawel Wodkowski <pawelx.wodkowski@intel.com>", "To": "dev@dpdk.org", "Date": "Thu, 19 Feb 2015 13:18:42 +0100", "Message-Id": "<1424348324-29932-2-git-send-email-pawelx.wodkowski@intel.com>", "X-Mailer": "git-send-email 1.9.1", "In-Reply-To": "<1424348324-29932-1-git-send-email-pawelx.wodkowski@intel.com>", "References": "<1424191340-26451-1-git-send-email-pawelx.wodkowski@intel.com>\n\t<1424348324-29932-1-git-send-email-pawelx.wodkowski@intel.com>", "Subject": "[dpdk-dev] [PATCH v5 1/3] librte_headroom: New library for checking\n\tcore/system/app load", "X-BeenThere": "dev@dpdk.org", "X-Mailman-Version": "2.1.15", "Precedence": "list", "List-Id": "patches and discussions about DPDK <dev.dpdk.org>", "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>", "List-Archive": "<http://dpdk.org/ml/archives/dev/>", "List-Post": "<mailto:dev@dpdk.org>", "List-Help": "<mailto:dev-request@dpdk.org?subject=help>", "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>", "Errors-To": "dev-bounces@dpdk.org", "Sender": "\"dev\" <dev-bounces@dpdk.org>" }, "content": "This library provide API to measure time spend in particular parts of\ncode and to calculate optimal polling time.\n\nTo calculate a those statistics application code need to be divided into\nparts (called jobs) that do something. It is up to application to decide\nwhat is considered a job.\n\nSeries of jobs must be surrounded with the rte_headroom_start_loop() and\nrte_headroom_finish_loop() calls. After that, jobs might be started.\nEach job must be surrounded with rte_headroom_start_job() and\nrte_headroom_finish_job() calls.\n\nAfter job finishes its execution, period in which it should be called\nagain is adjusted to minimize time wasted on unnecessary polls/calls.\nAdjustment is based on data provided by job itself (ex: number of\npackets it processed).\n\nAfter all jobs in serie are executed fallowing statistics are updated\nand might be used by application. Statistics can be reset. Some of\nprovided statistic data:\n - total/min/max execution - time spent in executing jobs.\n - total/min/max management - time spent outside execution area. This\nvalue might be used to measure overhead of scheduling jobs. This time\nalso\ncontains overhead of headroom library itself.\n - number of loops that executed at least one job\n - executed jobs\n - time when statistics were reset.\n\nEach job provide total/min/max execution time and execution count\nstatistics.\n\nSigned-off-by: Pawel Wodkowski <pawelx.wodkowski@intel.com>\n---\n config/common_bsdapp | 5 +\n config/common_linuxapp | 5 +\n lib/Makefile | 1 +\n lib/librte_headroom/Makefile | 54 +++++\n lib/librte_headroom/rte_headroom.c | 271 ++++++++++++++++++++++\n lib/librte_headroom/rte_headroom.h | 324 +++++++++++++++++++++++++++\n lib/librte_headroom/rte_headroom_version.map | 19 ++\n 7 files changed, 679 insertions(+)\n create mode 100644 lib/librte_headroom/Makefile\n create mode 100644 lib/librte_headroom/rte_headroom.c\n create mode 100644 lib/librte_headroom/rte_headroom.h\n create mode 100644 lib/librte_headroom/rte_headroom_version.map", "diff": "diff --git a/config/common_bsdapp b/config/common_bsdapp\nindex 57bacb8..aa2e5fd 100644\n--- a/config/common_bsdapp\n+++ b/config/common_bsdapp\n@@ -282,6 +282,11 @@ CONFIG_RTE_LIBRTE_HASH=y\n CONFIG_RTE_LIBRTE_HASH_DEBUG=n\n \n #\n+# Compile librte_headroom\n+#\n+CONFIG_RTE_LIBRTE_HEADROOM=y\n+\n+#\n # Compile librte_lpm\n #\n CONFIG_RTE_LIBRTE_LPM=y\ndiff --git a/config/common_linuxapp b/config/common_linuxapp\nindex d428f84..055a37b 100644\n--- a/config/common_linuxapp\n+++ b/config/common_linuxapp\n@@ -290,6 +290,11 @@ CONFIG_RTE_LIBRTE_HASH=y\n CONFIG_RTE_LIBRTE_HASH_DEBUG=n\n \n #\n+# Compile librte_headroom\n+#\n+CONFIG_RTE_LIBRTE_HEADROOM=y\n+\n+#\n # Compile librte_lpm\n #\n CONFIG_RTE_LIBRTE_LPM=y\ndiff --git a/lib/Makefile b/lib/Makefile\nindex d617d81..4fc2819 100644\n--- a/lib/Makefile\n+++ b/lib/Makefile\n@@ -54,6 +54,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += librte_pmd_vmxnet3\n DIRS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += librte_pmd_xenvirt\n DIRS-$(CONFIG_RTE_LIBRTE_VHOST) += librte_vhost\n DIRS-$(CONFIG_RTE_LIBRTE_HASH) += librte_hash\n+DIRS-$(CONFIG_RTE_LIBRTE_HEADROOM) += librte_headroom\n DIRS-$(CONFIG_RTE_LIBRTE_LPM) += librte_lpm\n DIRS-$(CONFIG_RTE_LIBRTE_ACL) += librte_acl\n DIRS-$(CONFIG_RTE_LIBRTE_NET) += librte_net\ndiff --git a/lib/librte_headroom/Makefile b/lib/librte_headroom/Makefile\nnew file mode 100644\nindex 0000000..faefb3b\n--- /dev/null\n+++ b/lib/librte_headroom/Makefile\n@@ -0,0 +1,54 @@\n+# BSD LICENSE\n+#\n+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.\n+# All rights reserved.\n+#\n+# Redistribution and use in source and binary forms, with or without\n+# modification, are permitted provided that the following conditions\n+# are met:\n+#\n+# * Redistributions of source code must retain the above copyright\n+# notice, this list of conditions and the following disclaimer.\n+# * Redistributions in binary form must reproduce the above copyright\n+# notice, this list of conditions and the following disclaimer in\n+# the documentation and/or other materials provided with the\n+# distribution.\n+# * Neither the name of Intel Corporation nor the names of its\n+# contributors may be used to endorse or promote products derived\n+# from this software without specific prior written permission.\n+#\n+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+# \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+\n+include $(RTE_SDK)/mk/rte.vars.mk\n+\n+# library name\n+LIB = librte_headroom.a\n+\n+CFLAGS += -O3\n+CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR)\n+\n+EXPORT_MAP := rte_headroom_version.map\n+\n+LIBABIVER := 1\n+\n+# all source are stored in SRCS-y\n+SRCS-$(CONFIG_RTE_LIBRTE_HEADROOM) := rte_headroom.c\n+\n+# install this header file\n+SYMLINK-$(CONFIG_RTE_LIBRTE_HEADROOM)-include := rte_headroom.h\n+\n+# this lib needs eal\n+DEPDIRS-$(CONFIG_RTE_LIBRTE_HEADROOM) += lib/librte_eal\n+DEPDIRS-$(CONFIG_RTE_LIBRTE_HEADROOM) += lib/librte_mbuf\n+\n+include $(RTE_SDK)/mk/rte.lib.mk\ndiff --git a/lib/librte_headroom/rte_headroom.c b/lib/librte_headroom/rte_headroom.c\nnew file mode 100644\nindex 0000000..a2cc671\n--- /dev/null\n+++ b/lib/librte_headroom/rte_headroom.c\n@@ -0,0 +1,271 @@\n+/*-\n+ * BSD LICENSE\n+ *\n+ * Copyright(c) 2010-2015 Intel Corporation. All rights reserved.\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or without\n+ * modification, are permitted provided that the following conditions\n+ * are met:\n+ *\n+ * * Redistributions of source code must retain the above copyright\n+ * notice, this list of conditions and the following disclaimer.\n+ * * Redistributions in binary form must reproduce the above copyright\n+ * notice, this list of conditions and the following disclaimer in\n+ * the documentation and/or other materials provided with the\n+ * distribution.\n+ * * Neither the name of Intel Corporation nor the names of its\n+ * contributors may be used to endorse or promote products derived\n+ * from this software without specific prior written permission.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#include <string.h>\n+#include <stdlib.h>\n+\n+#include <rte_log.h>\n+#include <rte_errno.h>\n+#include <rte_common.h>\n+#include <rte_cycles.h>\n+#include <rte_branch_prediction.h>\n+#include <rte_debug.h>\n+#include <rte_eal.h>\n+#include <rte_malloc.h>\n+\n+#include \"rte_headroom.h\"\n+\n+/* Those are steps used to adjust job period.\n+ * Experiments show that for forwarding apps the up step must be less than down\n+ * step to achieve optimal performance.\n+ */\n+#define JOB_UPDATE_STEP_UP 1\n+#define JOB_UPDATE_STEP_DOWN 4\n+\n+/*\n+ * Default update function that implements simple period adjustment.\n+ */\n+static void\n+default_update_function(struct rte_headroom_job *job, int64_t result)\n+{\n+\tint64_t err = job->target - result;\n+\n+\t/* Job is happy. Nothing to do */\n+\tif (err == 0)\n+\t\treturn;\n+\n+\tif (err > 0) {\n+\t\tif (job->period + JOB_UPDATE_STEP_UP < job->max_period)\n+\t\t\tjob->period += JOB_UPDATE_STEP_UP;\n+\t} else {\n+\t\tif (job->min_period + JOB_UPDATE_STEP_DOWN < job->period)\n+\t\t\tjob->period -= JOB_UPDATE_STEP_DOWN;\n+\t}\n+}\n+\n+#define HDR_ADD_TIME_MIN_MAX(obj, type, value) do { \\\n+\ttypeof(value) tmp = (value); \\\n+\t(obj)->type ## _time += tmp; \\\n+\tif (tmp < (obj)->min_ ## type ## _time) \\\n+\t\t(obj)->min_ ## type ## _time = tmp; \\\n+\tif (tmp > (obj)->max_ ## type ## _time) \\\n+\t\t(obj)->max_ ## type ## _time = tmp; \\\n+} while (0)\n+\n+#define HDR_RESET_TIME_MIN_MAX(obj, type) do { \\\n+\t(obj)->type ## _time = 0; \\\n+\t(obj)->min_ ## type ## _time = UINT64_MAX; \\\n+\t(obj)->max_ ## type ## _time = 0; \\\n+} while (0)\n+\n+int\n+rte_headroom_init(struct rte_headroom *hdr)\n+{\n+\tif (hdr == NULL)\n+\t\treturn -EINVAL;\n+\n+\t/* Init only needed parameters. Zero out everything else. */\n+\tmemset(hdr, 0, sizeof(struct rte_headroom));\n+\n+\trte_headroom_reset_stats(hdr);\n+\n+\treturn 0;\n+}\n+\n+void\n+rte_headroom_start_loop(struct rte_headroom *hdr)\n+{\n+\tuint64_t now;\n+\n+\thdr->loop_executed_jobs = 0;\n+\n+\trte_mb();\n+\tnow = rte_get_timer_cycles();\n+\tHDR_ADD_TIME_MIN_MAX(hdr, management, now - hdr->state_time);\n+\thdr->state_time = now;\n+}\n+\n+void\n+rte_headroom_finish_loop(struct rte_headroom *hdr)\n+{\n+\tuint64_t now;\n+\n+\tif (likely(hdr->loop_executed_jobs))\n+\t\thdr->loop_cnt++;\n+\n+\trte_mb();\n+\tnow = rte_get_timer_cycles();\n+\tHDR_ADD_TIME_MIN_MAX(hdr, management, now - hdr->state_time);\n+\thdr->state_time = now;\n+}\n+\n+void\n+rte_headroom_set_job_target(struct rte_headroom_job *job, int64_t target)\n+{\n+\tjob->target = target;\n+}\n+\n+int\n+rte_headroom_start_job(struct rte_headroom *hdr, struct rte_headroom_job *job)\n+{\n+\tuint64_t now;\n+\n+\t/* Some sanity check. */\n+\tif (unlikely(hdr == NULL || job == NULL || job->headroom != NULL))\n+\t\treturn -EINVAL;\n+\n+\t/* Link job with headroom object. */\n+\tjob->headroom = hdr;\n+\n+\trte_mb();\n+\tnow = rte_get_timer_cycles();\n+\tHDR_ADD_TIME_MIN_MAX(hdr, management, now - hdr->state_time);\n+\thdr->state_time = now;\n+\n+\treturn 0;\n+}\n+\n+int\n+rte_headroom_finish_job(struct rte_headroom_job *job, int64_t job_value)\n+{\n+\tstruct rte_headroom *hdr;\n+\tuint64_t now, exec_time;\n+\tint need_update;\n+\n+\t/* Some sanity check. */\n+\tif (unlikely(job == NULL || job->headroom == NULL))\n+\t\treturn -EINVAL;\n+\n+\tneed_update = job->target != job_value;\n+\t/* Adjust period only if job is unhappy of its current period. */\n+\tif (need_update)\n+\t\t(*job->update_period_cb)(job, job_value);\n+\n+\thdr = job->headroom;\n+\n+\t/* Update execution time is considered as runtime so get time after it is\n+\t * executed. */\n+\trte_mb();\n+\tnow = rte_get_timer_cycles();\n+\texec_time = now - hdr->state_time;\n+\tHDR_ADD_TIME_MIN_MAX(job, exec, exec_time);\n+\tHDR_ADD_TIME_MIN_MAX(hdr, exec, exec_time);\n+\n+\thdr->state_time = now;\n+\n+\thdr->loop_executed_jobs++;\n+\thdr->job_exec_cnt++;\n+\n+\tjob->exec_cnt++;\n+\tjob->headroom = NULL;\n+\n+\treturn need_update;\n+}\n+\n+void\n+rte_headroom_job_set_period(struct rte_headroom_job *job, uint64_t period,\n+\t\tuint8_t saturate)\n+{\n+\tif (saturate != 0) {\n+\t\tif (period < job->min_period)\n+\t\t\tperiod = job->min_period;\n+\t\telse if (period > job->max_period)\n+\t\t\tperiod = job->max_period;\n+\t}\n+\n+\tjob->period = period;\n+}\n+\n+void\n+rte_headroom_set_min_period(struct rte_headroom_job *job, uint64_t period)\n+{\n+\tjob->min_period = period;\n+\tif (job->period < period)\n+\t\tjob->period = period;\n+}\n+\n+void\n+rte_headroom_set_max_period(struct rte_headroom_job *job, uint64_t period)\n+{\n+\tjob->max_period = period;\n+\tif (job->period > period)\n+\t\tjob->period = period;\n+}\n+\n+int\n+rte_headroom_job_init(struct rte_headroom_job *job, const char *name,\n+\t\tuint64_t min_period, uint64_t max_period, uint64_t initial_period,\n+\t\tint64_t target)\n+{\n+\tif (job == NULL)\n+\t\treturn -EINVAL;\n+\n+\tjob->period = initial_period;\n+\tjob->min_period = min_period;\n+\tjob->max_period = max_period;\n+\tjob->target = target;\n+\tjob->update_period_cb = &default_update_function;\n+\trte_headroom_reset_job_stats(job);\n+\tsnprintf(job->name, RTE_DIM(job->name), \"%s\", name == NULL ? \"\" : name);\n+\tjob->headroom = NULL;\n+\n+\treturn 0;\n+}\n+\n+void\n+rte_headroom_set_update_period_function(struct rte_headroom_job *job,\n+\t\trte_headroom_update_fn_t update_period_cb)\n+{\n+\tif (update_period_cb == NULL)\n+\t\tupdate_period_cb = default_update_function;\n+\n+\tjob->update_period_cb = update_period_cb;\n+}\n+\n+void\n+rte_headroom_reset_job_stats(struct rte_headroom_job *job)\n+{\n+\tHDR_RESET_TIME_MIN_MAX(job, exec);\n+\tjob->exec_cnt = 0;\n+}\n+\n+void\n+rte_headroom_reset_stats(struct rte_headroom *hdr)\n+{\n+\tHDR_RESET_TIME_MIN_MAX(hdr, exec);\n+\tHDR_RESET_TIME_MIN_MAX(hdr, management);\n+\thdr->start_time = rte_get_timer_cycles();\n+\thdr->state_time = hdr->start_time;\n+\thdr->job_exec_cnt = 0;\n+\thdr->loop_cnt = 0;\n+}\ndiff --git a/lib/librte_headroom/rte_headroom.h b/lib/librte_headroom/rte_headroom.h\nnew file mode 100644\nindex 0000000..2232c13\n--- /dev/null\n+++ b/lib/librte_headroom/rte_headroom.h\n@@ -0,0 +1,324 @@\n+/*-\n+ * BSD LICENSE\n+ *\n+ * Copyright(c) 2010-2015 Intel Corporation. All rights reserved.\n+ * All rights reserved.\n+ *\n+ * Redistribution and use in source and binary forms, with or without\n+ * modification, are permitted provided that the following conditions\n+ * are met:\n+ *\n+ * * Redistributions of source code must retain the above copyright\n+ * notice, this list of conditions and the following disclaimer.\n+ * * Redistributions in binary form must reproduce the above copyright\n+ * notice, this list of conditions and the following disclaimer in\n+ * the documentation and/or other materials provided with the\n+ * distribution.\n+ * * Neither the name of Intel Corporation nor the names of its\n+ * contributors may be used to endorse or promote products derived\n+ * from this software without specific prior written permission.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#ifndef HEADROOM_H_\n+#define HEADROOM_H_\n+\n+#include <stdint.h>\n+\n+#include <rte_memory.h>\n+#include <rte_memcpy.h>\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+#endif\n+\n+#define RTE_HEADROOM_JOB_NAMESIZE 32\n+#define RTE_HEADROOM_NAMESIZE 32\n+#define RTE_HEADROOM_MZ_PREFIX \"HDR_\"\n+\n+/* Forward declarations. */\n+struct rte_headroom;\n+struct rte_headroom_job;\n+\n+/**\n+ * This function should calculate new period and set it using\n+ * rte_headroom_set_period() function. Time spent in this function will be\n+ * added to job's runtime.\n+ *\n+ * @param job\n+ * The job data structure handler.\n+ * @param job_result\n+ * Result of calling job callback.\n+ */\n+typedef void (*rte_headroom_update_fn_t)(struct rte_headroom_job *job,\n+\t\tint64_t job_result);\n+\n+struct rte_headroom_job {\n+\tuint64_t period;\n+\t/**< Estimated period of execution. */\n+\n+\tuint64_t min_period;\n+\t/**< Minimum period. */\n+\n+\tuint64_t max_period;\n+\t/**< Maximum period. */\n+\n+\tint64_t target;\n+\t/**< Desired value for this job. */\n+\n+\trte_headroom_update_fn_t update_period_cb;\n+\t/**< Period update callback. */\n+\n+\tuint64_t exec_time;\n+\t/**< Total time (sum) that this job was executing. */\n+\n+\tuint64_t min_exec_time;\n+\t/**< Minimum execute time. */\n+\n+\tuint64_t max_exec_time;\n+\t/**< Minimum execute time. */\n+\n+\tuint64_t exec_cnt;\n+\t/**< Execute count. */\n+\n+\tchar name[RTE_HEADROOM_JOB_NAMESIZE];\n+\t/**< Name of this job */\n+\n+\tstruct rte_headroom *headroom;\n+\t/**< Headroom object that is executing this job. */\n+} __rte_cache_aligned;\n+\n+struct rte_headroom {\n+\t/** Viariable holding time at different points:\n+\t * -# loop start time if loop was started but no job executed yet.\n+\t * -# job start time if job is currently executing.\n+\t * -# job finish time if job finished its execution.\n+\t * -# loop finish time if loop finished its execution. */\n+\tuint64_t state_time;\n+\n+\tuint64_t loop_executed_jobs;\n+\t/**< Count of executed jobs in this loop. */\n+\n+\t/* Statistics start. */\n+\n+\tuint64_t exec_time;\n+\t/**< Total time taken to execute jobs, not including management time. */\n+\n+\tuint64_t min_exec_time;\n+\t/**< Minimum loop execute time. */\n+\n+\tuint64_t max_exec_time;\n+\t/**< Minimum loop execute time. */\n+\n+\t/**\n+\t * Sum of time that is not the execute time (ex: from job finish to next\n+\t * job start).\n+\t *\n+\t * This time might be considered as overhead of headroom library + job\n+\t * scheduling.\n+\t */\n+\tuint64_t management_time;\n+\n+\tuint64_t min_management_time;\n+\t/**< Minimum management time */\n+\n+\tuint64_t max_management_time;\n+\t/**< Maximum management time */\n+\n+\tuint64_t start_time;\n+\t/**< Time since last reset stats. */\n+\n+\tuint64_t job_exec_cnt;\n+\t/**< Total count of executed jobs. */\n+\n+\tuint64_t loop_cnt;\n+\t/**< Total count of executed loops with at least one executed job. */\n+} __rte_cache_aligned;\n+\n+/**\n+ * Initialize given headroom object with default values.\n+ *\n+ * @param hdr\n+ * Headroom object to initialize.\n+ *\n+ * @return\n+ * 0 on success\n+ * -EINVAL if *hdr* is NULL\n+ */\n+int\n+rte_headroom_init(struct rte_headroom *hdr);\n+\n+/**\n+ * Mark that new set of jobs start executing.\n+ *\n+ * @param hdr\n+ * Headroom object.\n+ */\n+void\n+rte_headroom_start_loop(struct rte_headroom *hdr);\n+\n+/**\n+ * Mark that there is no more jobs ready to execute in this turn. Calculate\n+ * stats for this loop turn.\n+ *\n+ * @param hdr\n+ * Headroom object.\n+ */\n+void\n+rte_headroom_finish_loop(struct rte_headroom *hdr);\n+\n+/**\n+ * Initialize given job stats object.\n+ *\n+ * @param job\n+ * Job object.\n+ * @param name\n+ * Optional job name.\n+ * @param min_period\n+ * Minimum period that this job can accept.\n+ * @param max_period\n+ * Maximum period that this job can accept.\n+ * @param initial_period\n+ * Initial period. It will be checked against *min_period* and *max_period*.\n+ * @param target\n+ * Target value that this job try to achieve.\n+ *\n+ * @return\n+ * 0 on success\n+ * -EINVAL if *job* is NULL\n+ */\n+int\n+rte_headroom_job_init(struct rte_headroom_job *job, const char *name,\n+\t\tuint64_t min_period, uint64_t max_period, uint64_t initial_period,\n+\t\tint64_t target);\n+\n+/**\n+ * Set job desired target value. Difference between target and job callback\n+ * return value must be used to properly adjust job execute period value.\n+ *\n+ * @param job\n+ * The job object.\n+ * @param target\n+ * New target.\n+ */\n+void\n+rte_headroom_set_job_target(struct rte_headroom_job *job, int64_t target);\n+\n+/**\n+ * Mark that *job* is starting of its execution in context of *hdr* object.\n+ *\n+ * @param hdr\n+ * Headroom object context.\n+ * @param job\n+ * Job object.\n+ * @return\n+ * 0 on success\n+ * -EINVAL if *hdr* or *job* is NULL or *job* is executing in another headroom\n+ * context already,\n+ */\n+int\n+rte_headroom_start_job(struct rte_headroom *hdr, struct rte_headroom_job *job);\n+\n+/**\n+ * Mark that *job* finished its execution. Context in which it was executing will\n+ * receive stat update. After this function call *job* object is ready to be\n+ * executed in other headroom context.\n+ *\n+ * @param job\n+ * Job object.\n+ * @param job_value\n+ * Job value. Job should pass in this parameter a value that it try to optimize\n+ * for example the number of packets it processed.\n+ *\n+ * @return\n+ * 0 if job's period was not updated (job target equals *job_value*)\n+ * 1 if job's period was updated\n+ * -EINVAL if job is NULL or job was not started (it have no headroom context).\n+ */\n+int\n+rte_headroom_finish_job(struct rte_headroom_job *job, int64_t job_value);\n+\n+/**\n+ * Set execute period of given job.\n+ *\n+ * @param job\n+ * The job object.\n+ * @param period\n+ * New period value.\n+ * @param saturate\n+ * If zero, skip period saturation to min, max range.\n+ */\n+void\n+rte_headroom_job_set_period(struct rte_headroom_job *job, uint64_t period,\n+\t\tuint8_t saturate);\n+/**\n+ * Set minimum execute period of given job. Current period will be checked\n+ * against new minimum value.\n+ *\n+ * @param job\n+ * The job object.\n+ * @param period\n+ * New minimum period value.\n+ */\n+void\n+rte_headroom_set_min_period(struct rte_headroom_job *job, uint64_t period);\n+/**\n+ * Set maximum execute period of given job. Current period will be checked\n+ * against new maximum value.\n+ *\n+ * @param job\n+ * The job object.\n+ * @param period\n+ * New maximum period value.\n+ */\n+void\n+rte_headroom_set_max_period(struct rte_headroom_job *job, uint64_t period);\n+\n+/**\n+ * Set update period callback that is invoked after job finish.\n+ *\n+ * If application wants to do more sophisticated calculations than default\n+ * it can provide this handler.\n+ *\n+ * @param job\n+ * Job object.\n+ * @param update_pedriod_cb\n+ * Callback to set. If NULL restore default update function.\n+ */\n+void\n+rte_headroom_set_update_period_function(struct rte_headroom_job *job,\n+\t\trte_headroom_update_fn_t update_period_cb);\n+\n+/**\n+ * Function resets job statistics.\n+ *\n+ * @param job\n+ * Job which statistics will be reset.\n+ */\n+void\n+rte_headroom_reset_job_stats(struct rte_headroom_job *job);\n+/**\n+ * Function resets headroom statistics.\n+ *\n+ * @param hdr\n+ * Headroom which statistics will be reset.\n+ */\n+void\n+rte_headroom_reset_stats(struct rte_headroom *hdr);\n+\n+#ifdef __cplusplus\n+}\n+#endif\n+\n+#endif /* HEADROOM_H_ */\ndiff --git a/lib/librte_headroom/rte_headroom_version.map b/lib/librte_headroom/rte_headroom_version.map\nnew file mode 100644\nindex 0000000..3c66812\n--- /dev/null\n+++ b/lib/librte_headroom/rte_headroom_version.map\n@@ -0,0 +1,19 @@\n+DPDK_2.0 {\n+\tglobal:\n+\n+\trte_headroom_init;\n+\trte_headroom_start_loop;\n+\trte_headroom_finish_loop;\n+\trte_headroom_job_init;\n+\trte_headroom_set_job_target;\n+\trte_headroom_start_job;\n+\trte_headroom_finish_job;\n+\trte_headroom_job_set_period;\n+\trte_headroom_set_min_period;\n+\trte_headroom_set_max_period;\n+\trte_headroom_set_update_period_function;\n+\trte_headroom_reset_job_stats;\n+\trte_headroom_reset_stats;\n+\n+\tlocal: *;\n+};\n", "prefixes": [ "dpdk-dev", "v5", "1/3" ] }{ "id": 3487, "url": "