get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/30581/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 30581,
    "url": "http://patches.dpdk.org/api/patches/30581/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1508409071-17740-1-git-send-email-harry.van.haaren@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": "<1508409071-17740-1-git-send-email-harry.van.haaren@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1508409071-17740-1-git-send-email-harry.van.haaren@intel.com",
    "date": "2017-10-19T10:31:11",
    "name": "[dpdk-dev,v2] example: add new service cores sample application",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "f1a011bc804067cfa8d6699b73a4435f754ad525",
    "submitter": {
        "id": 317,
        "url": "http://patches.dpdk.org/api/people/317/?format=api",
        "name": "Van Haaren, Harry",
        "email": "harry.van.haaren@intel.com"
    },
    "delegate": null,
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1508409071-17740-1-git-send-email-harry.van.haaren@intel.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/30581/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/30581/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 [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id EC25F1B1C3;\n\tThu, 19 Oct 2017 12:30:41 +0200 (CEST)",
            "from mga04.intel.com (mga04.intel.com [192.55.52.120])\n\tby dpdk.org (Postfix) with ESMTP id E74DD101B\n\tfor <dev@dpdk.org>; Thu, 19 Oct 2017 12:30:39 +0200 (CEST)",
            "from fmsmga004.fm.intel.com ([10.253.24.48])\n\tby fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t19 Oct 2017 03:30:38 -0700",
            "from silpixa00398672.ir.intel.com ([10.237.223.128])\n\tby fmsmga004.fm.intel.com with ESMTP; 19 Oct 2017 03:30:36 -0700"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.43,401,1503385200\"; d=\"scan'208\";a=\"325094547\"",
        "From": "Harry van Haaren <harry.van.haaren@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "thomas@monjalon.net, john.mcnamara@intel.com, gage.eads@intel.com,\n\tHarry van Haaren <harry.van.haaren@intel.com>",
        "Date": "Thu, 19 Oct 2017 11:31:11 +0100",
        "Message-Id": "<1508409071-17740-1-git-send-email-harry.van.haaren@intel.com>",
        "X-Mailer": "git-send-email 2.7.4",
        "In-Reply-To": "<1506345834-137009-1-git-send-email-harry.van.haaren@intel.com>",
        "References": "<1506345834-137009-1-git-send-email-harry.van.haaren@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v2] example: add new service cores sample\n\tapplication",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <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 commit adds a new sample app, which showcases the value\nof running services. In particular it allows the application\nto dynamically schedule services to service-cores.\n\nThe sample app itself registers a number of dummy services,\nand applies different profiles to them at runtime. Note that\nthis sample application does not forward any traffic - it\ndemonstrates advanced usage of the service cores API.\n\nSigned-off-by: Harry van Haaren <harry.van.haaren@intel.com>\n\n---\n\nv2 feedback http://dpdk.org/dev/patchwork/patch/29169/\n- Add to examples Makefile (Thomas)\n- Add new files to MAINTAINERS (Thomas)\n- Added documentation to sample app user guides (Thomas)\n- Reduce service-per-core define to 5, removes extra zeros (Gage)\n- Improve error handling if service mapping fails (Gage)\n\n\n---\n MAINTAINERS                                |   4 +\n doc/guides/sample_app_ug/index.rst         |   1 +\n doc/guides/sample_app_ug/service_cores.rst | 172 ++++++++++++++++++++\n examples/Makefile                          |   1 +\n examples/service_cores/Makefile            |  54 +++++++\n examples/service_cores/main.c              | 247 +++++++++++++++++++++++++++++\n 6 files changed, 479 insertions(+)\n create mode 100644 doc/guides/sample_app_ug/service_cores.rst\n create mode 100644 examples/service_cores/Makefile\n create mode 100644 examples/service_cores/main.c",
    "diff": "diff --git a/MAINTAINERS b/MAINTAINERS\nindex 8df2a7f..44a8c38 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -903,6 +903,10 @@ M: John McNamara <john.mcnamara@intel.com>\n F: examples/rxtx_callbacks/\n F: doc/guides/sample_app_ug/rxtx_callbacks.rst\n \n+M: Harry van Haaren <harry.van.haaren@intel.com>\n+F: examples/service_cores/\n+F: doc/guides/sample_app_ug/service_cores.rst\n+\n M: Bruce Richardson <bruce.richardson@intel.com>\n M: John McNamara <john.mcnamara@intel.com>\n F: examples/skeleton/\ndiff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst\nindex 069d4f1..0c17ebb 100644\n--- a/doc/guides/sample_app_ug/index.rst\n+++ b/doc/guides/sample_app_ug/index.rst\n@@ -58,6 +58,7 @@ Sample Applications User Guides\n     link_status_intr\n     load_balancer\n     server_node_efd\n+    service_cores\n     multi_process\n     qos_metering\n     qos_scheduler\ndiff --git a/doc/guides/sample_app_ug/service_cores.rst b/doc/guides/sample_app_ug/service_cores.rst\nnew file mode 100644\nindex 0000000..07e3929\n--- /dev/null\n+++ b/doc/guides/sample_app_ug/service_cores.rst\n@@ -0,0 +1,172 @@\n+..  BSD LICENSE\n+    Copyright(c) 2017 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+Service Cores Sample Application\n+================================\n+\n+The service cores sample application demonstrates the service cores capabilities\n+of DPDK. The service cores infrastructure is part of the DPDK EAL, and allows\n+any DPDK component to register a service. A service is a work item or task, that\n+requires CPU time to perform its duty.\n+\n+This sample application registers 5 dummy services. These 5 services are used\n+to show how the service_cores API can be used to orchestrate these services to\n+run on different service lcores. This orchestration is done by calling the\n+service cores APIs, however the sample application introduces a \"profile\"\n+concept to contain the service mapping details. Note that the profile concept\n+is application specific, and not a part of the service cores API.\n+\n+\n+Compiling the Application\n+-------------------------\n+\n+#.  Go to the example directory:\n+\n+    .. code-block:: console\n+\n+        export RTE_SDK=/path/to/rte_sdk\n+        cd ${RTE_SDK}/examples/service_cores\n+\n+#.  Set the target (a default target is used if not specified). For example:\n+\n+    .. code-block:: console\n+\n+        export RTE_TARGET=x86_64-native-linuxapp-gcc\n+\n+    See the *DPDK Getting Started* Guide for possible RTE_TARGET values.\n+\n+#.  Build the application:\n+\n+    .. code-block:: console\n+\n+        make\n+\n+Running the Application\n+-----------------------\n+\n+To run the example, just execute the binary. Since the application dynamically\n+adds service cores in the application code itself, there is no requirement to\n+pass a service core-mask as an EAL argument at startup time.\n+\n+.. code-block:: console\n+\n+    $ ./build/service_cores\n+\n+\n+Explanation\n+-----------\n+\n+The following sections provide some explanation of code focusing on\n+registering applications from an applications point of view, and modifying the\n+service core counts and mappings at runtime.\n+\n+\n+Registering a Service\n+~~~~~~~~~~~~~~~~~~~~~\n+\n+The following code section shows how to register a service as an application.\n+Note that the service component header must be included by the application in\n+order to register services: ``rte_service_component.h``, in addition\n+to the ordinary service cores header ``rte_service.h`` which provides\n+the runtime functions to add, remove and remap service cores.\n+\n+.. code-block:: c\n+\n+        struct rte_service_spec service = {\n+                .name = \"service_name\",\n+        };\n+        int ret = rte_service_component_register(services, &id);\n+        if (ret)\n+                return -1;\n+\n+        /* set the service itself to be ready to run. In the case of\n+        * ethdev, eventdev etc PMDs, this will be set when the\n+        * appropriate configure or setup function is called.\n+        */\n+        rte_service_component_runstate_set(id, 1);\n+\n+        /* Collect statistics for the service */\n+        rte_service_set_stats_enable(id, 1);\n+\n+        /* The application sets the service to running state. Note that this\n+         * function enables the service to run - while the 'component' version\n+         * of this function (as above) marks the service itself as ready */\n+        ret = rte_service_runstate_set(id, 1);\n+\n+\n+Controlling A Service Core\n+~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+This section demonstrates how to add a service core. The ``rte_service.h``\n+header file provides the functions for dynamically adding and removing cores.\n+The APIs to add and remove cores use lcore IDs similar to existing DPDK\n+functions.\n+\n+These are the functions to start a service core, and have it run a service:\n+\n+.. code-block:: c\n+\n+        /* the lcore ID to use as a service core */\n+        uint32_t service_core_id = 7;\n+        ret = rte_service_lcore_add(service_core_id);\n+        if(ret)\n+                return -1;\n+\n+        /* service cores are in \"stopped\" state when added, so start it */\n+        ret = rte_service_lcore_start(service_core_id);\n+        if(ret)\n+                return -1;\n+\n+        /* map a service to the service core, causing it to run the service */\n+        uint32_t service_id; /* ID of a registered service */\n+        uint32_t enable = 1; /* 1 maps the service, 0 unmaps */\n+        ret = rte_service_map_lcore_set(service_id, service_core_id, enable);\n+        if(ret)\n+                return -1;\n+\n+\n+Removing A Service Core\n+~~~~~~~~~~~~~~~~~~~~~~~\n+\n+To remove a service core, the steps are similar to adding but in reverse order.\n+Note that it is not allowed to remove a service core if the service is running,\n+and the service-core is the only core running that service (see documentation\n+for ``rte_service_lcore_stop`` function for details).\n+\n+\n+Conclusion\n+~~~~~~~~~~\n+\n+The service cores infrastructure provides DPDK with two main features. The first\n+is to abstract away hardware differences: the service core can CPU cycles to\n+a software fallback implementation, allowing the application to be abstracted\n+from the difference in HW / SW availability. The second feature is a flexible\n+method of registering functions to be run, allowing the running of the\n+functions to be scaled across multiple CPUs. \ndiff --git a/examples/Makefile b/examples/Makefile\nindex 28354ff..266451f 100644\n--- a/examples/Makefile\n+++ b/examples/Makefile\n@@ -83,6 +83,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_METER) += qos_meter\n DIRS-$(CONFIG_RTE_LIBRTE_SCHED) += qos_sched\n DIRS-y += quota_watermark\n DIRS-$(CONFIG_RTE_ETHDEV_RXTX_CALLBACKS) += rxtx_callbacks\n+DIRS-y += service_cores\n DIRS-y += skeleton\n ifeq ($(CONFIG_RTE_LIBRTE_HASH),y)\n DIRS-$(CONFIG_RTE_LIBRTE_VHOST) += tep_termination\ndiff --git a/examples/service_cores/Makefile b/examples/service_cores/Makefile\nnew file mode 100644\nindex 0000000..bd4a345\n--- /dev/null\n+++ b/examples/service_cores/Makefile\n@@ -0,0 +1,54 @@\n+#   BSD LICENSE\n+#\n+#   Copyright(c) 2017 Intel Corporation. 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+ifeq ($(RTE_SDK),)\n+$(error \"Please define RTE_SDK environment variable\")\n+endif\n+\n+# Default target, can be overridden by command line or environment\n+RTE_TARGET ?= x86_64-native-linuxapp-gcc\n+\n+include $(RTE_SDK)/mk/rte.vars.mk\n+\n+# binary name\n+APP = service_cores\n+\n+# all source are stored in SRCS-y\n+SRCS-y := main.c\n+\n+CFLAGS += $(WERROR_FLAGS)\n+\n+# workaround for a gcc bug with noreturn attribute\n+# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12603\n+ifeq ($(CONFIG_RTE_TOOLCHAIN_GCC),y)\n+CFLAGS_main.o += -Wno-return-type\n+endif\n+\n+include $(RTE_SDK)/mk/rte.extapp.mk\ndiff --git a/examples/service_cores/main.c b/examples/service_cores/main.c\nnew file mode 100644\nindex 0000000..8a8f5bd\n--- /dev/null\n+++ b/examples/service_cores/main.c\n@@ -0,0 +1,247 @@\n+/*\n+ *   BSD LICENSE\n+ *\n+ *   Copyright(c) 2017 Intel Corporation. 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 <unistd.h>\n+#include <stdio.h>\n+#include <string.h>\n+#include <stdint.h>\n+#include <errno.h>\n+#include <sys/queue.h>\n+\n+#include <rte_memory.h>\n+#include <rte_memzone.h>\n+#include <rte_launch.h>\n+#include <rte_eal.h>\n+#include <rte_debug.h>\n+#include <rte_cycles.h>\n+\n+/* allow application scheduling of the services */\n+#include <rte_service.h>\n+\n+/* Allow application registration of its own services. An application does not\n+ * have to register services, but it can be useful if it wishes to run a\n+ * function on a core that is otherwise in use as a service core. In this\n+ * example, all services are dummy services registered by the sample app itself.\n+ */\n+#include <rte_service_component.h>\n+\n+#define PROFILE_CORES_MAX 8\n+#define PROFILE_SERVICE_PER_CORE 5\n+\n+/* dummy function to do \"work\" */\n+static int32_t service_func(void *args)\n+{\n+\tRTE_SET_USED(args);\n+\trte_delay_us(2000);\n+\treturn 0;\n+}\n+\n+static struct rte_service_spec services[] = {\n+\t{\"service_1\", service_func, NULL, 0, 0},\n+\t{\"service_2\", service_func, NULL, 0, 0},\n+\t{\"service_3\", service_func, NULL, 0, 0},\n+\t{\"service_4\", service_func, NULL, 0, 0},\n+\t{\"service_5\", service_func, NULL, 0, 0},\n+};\n+#define NUM_SERVICES RTE_DIM(services)\n+\n+/* this struct holds the mapping of a particular core to all services */\n+struct profile_for_core {\n+\tuint32_t mapped_services[PROFILE_SERVICE_PER_CORE];\n+};\n+\n+/* struct that can be applied as the service core mapping. Items in this\n+ * struct will be passed to the ordinary rte_service_* APIs to configure the\n+ * service cores at runtime, based on the requirements.\n+ *\n+ * These profiles can be considered a \"configuration\" for the service cores,\n+ * where switching profile just changes the number of cores and the mappings\n+ * for each of them. As a result, the core requirements and performance of the\n+ * application scales.\n+ */\n+struct profile {\n+\tchar name[64];\n+\tuint32_t num_cores;\n+\tstruct profile_for_core cores[PROFILE_CORES_MAX];\n+};\n+\n+static struct profile profiles[] = {\n+\t/* profile 0: high performance */\n+\t{\n+\t\t.name = \"High Performance\",\n+\t\t.num_cores = 5,\n+\t\t.cores[0] = {.mapped_services = {1, 0, 0, 0, 0} },\n+\t\t.cores[1] = {.mapped_services = {0, 1, 0, 0, 0} },\n+\t\t.cores[2] = {.mapped_services = {0, 0, 1, 0, 0} },\n+\t\t.cores[3] = {.mapped_services = {0, 0, 0, 1, 0} },\n+\t\t.cores[4] = {.mapped_services = {0, 0, 0, 0, 1} },\n+\t},\n+\t/* profile 1: mid performance with single service priority */\n+\t{\n+\t\t.name = \"Mid-High Performance\",\n+\t\t.num_cores = 3,\n+\t\t.cores[0] = {.mapped_services = {1, 1, 0, 0, 0} },\n+\t\t.cores[1] = {.mapped_services = {0, 0, 1, 1, 0} },\n+\t\t.cores[2] = {.mapped_services = {0, 0, 0, 0, 1} },\n+\t\t.cores[3] = {.mapped_services = {0, 0, 0, 0, 0} },\n+\t\t.cores[4] = {.mapped_services = {0, 0, 0, 0, 0} },\n+\t},\n+\t/* profile 2: mid performance with single service priority */\n+\t{\n+\t\t.name = \"Mid-Low Performance\",\n+\t\t.num_cores = 2,\n+\t\t.cores[0] = {.mapped_services = {1, 1, 1, 0, 0} },\n+\t\t.cores[1] = {.mapped_services = {1, 1, 0, 1, 1} },\n+\t\t.cores[2] = {.mapped_services = {0, 0, 0, 0, 0} },\n+\t\t.cores[3] = {.mapped_services = {0, 0, 0, 0, 0} },\n+\t\t.cores[4] = {.mapped_services = {0, 0, 0, 0, 0} },\n+\t},\n+\t/* profile 3: scale down performance on single core */\n+\t{\n+\t\t.name = \"Scale down performance\",\n+\t\t.num_cores = 1,\n+\t\t.cores[0] = {.mapped_services = {1, 1, 1, 1, 1} },\n+\t\t.cores[1] = {.mapped_services = {0, 0, 0, 0, 0} },\n+\t\t.cores[2] = {.mapped_services = {0, 0, 0, 0, 0} },\n+\t\t.cores[3] = {.mapped_services = {0, 0, 0, 0, 0} },\n+\t\t.cores[4] = {.mapped_services = {0, 0, 0, 0, 0} },\n+\t},\n+};\n+#define NUM_PROFILES RTE_DIM(profiles)\n+\n+static int\n+apply_profile(int profile_id)\n+{\n+\tuint32_t i;\n+\tuint32_t s;\n+\tint ret;\n+\tstruct profile *p = &profiles[profile_id];\n+\tconst uint8_t core_off = 1;\n+\n+\tfor (i = 0; i < p->num_cores; i++) {\n+\t\tuint32_t core = i + core_off;\n+\t\tret = rte_service_lcore_add(core);\n+\t\tif (ret && ret != -EALREADY)\n+\t\t\tprintf(\"core %d added ret %d\\n\", core, ret);\n+\n+\t\tret = rte_service_lcore_start(core);\n+\t\tif (ret && ret != -EALREADY)\n+\t\t\tprintf(\"core %d start ret %d\\n\", core, ret);\n+\n+\t\tfor (s = 0; s < NUM_SERVICES; s++) {\n+\t\t\tif (rte_service_map_lcore_set(s, core,\n+\t\t\t\t\tp->cores[i].mapped_services[s]))\n+\t\t\t\tprintf(\"failed to map lcore %d\\n\", core);\n+\t\t}\n+\t}\n+\n+\tfor ( ; i < PROFILE_CORES_MAX; i++) {\n+\t\tuint32_t core = i + core_off;\n+\t\tfor (s = 0; s < NUM_SERVICES; s++) {\n+\t\t\tret = rte_service_map_lcore_set(s, core, 0);\n+\t\t\tif (ret && ret != -EINVAL) {\n+\t\t\t\tprintf(\"%s %d: map lcore set = %d\\n\", __func__,\n+\t\t\t\t\t\t__LINE__, ret);\n+\t\t\t}\n+\t\t}\n+\t\tret = rte_service_lcore_stop(core);\n+\t\tif (ret && ret != -EALREADY) {\n+\t\t\tprintf(\"%s %d: lcore stop = %d\\n\", __func__,\n+\t\t\t\t\t__LINE__, ret);\n+\t\t}\n+\t\tret = rte_service_lcore_del(core);\n+\t\tif (ret && ret != -EINVAL) {\n+\t\t\tprintf(\"%s %d: lcore del = %d\\n\", __func__,\n+\t\t\t\t\t__LINE__, ret);\n+\t\t}\n+\t}\n+}\n+\n+int\n+main(int argc, char **argv)\n+{\n+\tint ret;\n+\n+\tret = rte_eal_init(argc, argv);\n+\tif (ret < 0)\n+\t\trte_panic(\"Cannot init EAL\\n\");\n+\n+\tuint32_t i;\n+\tfor (i = 0; i < NUM_SERVICES; i++) {\n+\t\tservices[i].callback_userdata = 0;\n+\t\tuint32_t id;\n+\t\tret = rte_service_component_register(&services[i], &id);\n+\t\tif (ret)\n+\t\t\trte_exit(-1, \"service register() failed\");\n+\n+\t\t/* set the service itself to be ready to run. In the case of\n+\t\t * ethdev, eventdev etc PMDs, this will be set when the\n+\t\t * appropriate configure or setup function is called.\n+\t\t */\n+\t\trte_service_component_runstate_set(id, 1);\n+\n+\t\t/* Collect statistics for the service */\n+\t\trte_service_set_stats_enable(id, 1);\n+\n+\t\t/* the application sets the service to be active. Note that the\n+\t\t * previous component_runstate_set() is the PMD indicating\n+\t\t * ready, while this function is the application setting the\n+\t\t * service to run. Applications can choose to not run a service\n+\t\t * by setting runstate to 0 at any time.\n+\t\t */\n+\t\tret = rte_service_runstate_set(id, 1);\n+\t\tif (ret)\n+\t\t\treturn -ENOEXEC;\n+\t}\n+\n+\ti = 0;\n+\twhile (1) {\n+\t\tconst char clr[] = { 27, '[', '2', 'J', '\\0' };\n+\t\tconst char topLeft[] = { 27, '[', '1', ';', '1', 'H', '\\0' };\n+\t\tprintf(\"%s%s\", clr, topLeft);\n+\n+\t\tapply_profile(i);\n+\t\tprintf(\"\\n==> Profile: %s\\n\\n\", profiles[i].name);\n+\n+\t\tsleep(1);\n+\t\trte_service_dump(stdout, UINT32_MAX);\n+\n+\t\tsleep(5);\n+\t\trte_service_dump(stdout, UINT32_MAX);\n+\n+\t\ti++;\n+\t\tif (i >= NUM_PROFILES)\n+\t\t\ti = 0;\n+\t}\n+\n+\treturn 0;\n+}\n",
    "prefixes": [
        "dpdk-dev",
        "v2"
    ]
}