get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 7331,
    "url": "https://patches.dpdk.org/api/patches/7331/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1443629484-31108-1-git-send-email-maciejx.t.gajdzica@intel.com/",
    "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": "<1443629484-31108-1-git-send-email-maciejx.t.gajdzica@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1443629484-31108-1-git-send-email-maciejx.t.gajdzica@intel.com",
    "date": "2015-09-30T16:11:24",
    "name": "[dpdk-dev,1/1] ip_pipeline: added dynamic pipeline reconfiguration",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "e909be2dd545e7795c69fdc09ae15736d3ec549e",
    "submitter": {
        "id": 18,
        "url": "https://patches.dpdk.org/api/people/18/?format=api",
        "name": "Maciej Gajdzica",
        "email": "maciejx.t.gajdzica@intel.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1443629484-31108-1-git-send-email-maciejx.t.gajdzica@intel.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/7331/comments/",
    "check": "pending",
    "checks": "https://patches.dpdk.org/api/patches/7331/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 C40D38DAB;\n\tWed, 30 Sep 2015 18:17:32 +0200 (CEST)",
            "from mga03.intel.com (mga03.intel.com [134.134.136.65])\n\tby dpdk.org (Postfix) with ESMTP id 85E838D36\n\tfor <dev@dpdk.org>; Wed, 30 Sep 2015 18:17:30 +0200 (CEST)",
            "from orsmga002.jf.intel.com ([10.7.209.21])\n\tby orsmga103.jf.intel.com with ESMTP; 30 Sep 2015 09:17:29 -0700",
            "from unknown (HELO stargo) ([10.217.248.233])\n\tby orsmga002.jf.intel.com with SMTP; 30 Sep 2015 09:17:27 -0700",
            "by stargo (sSMTP sendmail emulation);\n\tWed, 30 Sep 2015 18:11:40 +0200"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.17,613,1437462000\"; d=\"scan'208\";a=\"816445855\"",
        "From": "Maciej Gajdzica <maciejx.t.gajdzica@intel.com>",
        "To": "dev@dpdk.org",
        "Date": "Wed, 30 Sep 2015 18:11:24 +0200",
        "Message-Id": "<1443629484-31108-1-git-send-email-maciejx.t.gajdzica@intel.com>",
        "X-Mailer": "git-send-email 1.9.1",
        "Subject": "[dpdk-dev] [PATCH 1/1] ip_pipeline: added dynamic pipeline\n\treconfiguration",
        "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": "Up till now pipeline was bound to thread selected in the initial config.\nThis patch allows binding pipeline to other threads at runtime using CLI\ncommands.\n\nSigned-off-by: Maciej Gajdzica <maciejx.t.gajdzica@intel.com>\n---\n examples/ip_pipeline/Makefile                      |    1 +\n examples/ip_pipeline/app.h                         |    5 +\n examples/ip_pipeline/config_parse.c                |    2 +-\n examples/ip_pipeline/init.c                        |   61 ++++\n examples/ip_pipeline/pipeline.h                    |    6 +\n examples/ip_pipeline/pipeline/pipeline_common_fe.h |    3 +\n examples/ip_pipeline/thread.c                      |  135 +++++++-\n examples/ip_pipeline/thread.h                      |  101 ++++++\n examples/ip_pipeline/thread_fe.c                   |  328 ++++++++++++++++++++\n 9 files changed, 640 insertions(+), 2 deletions(-)\n create mode 100644 examples/ip_pipeline/thread.h\n create mode 100644 examples/ip_pipeline/thread_fe.c",
    "diff": "diff --git a/examples/ip_pipeline/Makefile b/examples/ip_pipeline/Makefile\nindex f3ff1ec..c8e80b5 100644\n--- a/examples/ip_pipeline/Makefile\n+++ b/examples/ip_pipeline/Makefile\n@@ -54,6 +54,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += config_parse_tm.c\n SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += config_check.c\n SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += init.c\n SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += thread.c\n+SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += thread_fe.c\n SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += cpu_core_map.c\n \n SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_common_be.c\ndiff --git a/examples/ip_pipeline/app.h b/examples/ip_pipeline/app.h\nindex 521e3a0..19ddd31 100644\n--- a/examples/ip_pipeline/app.h\n+++ b/examples/ip_pipeline/app.h\n@@ -220,9 +220,11 @@ struct app_pipeline_data {\n \tvoid *be;\n \tvoid *fe;\n \tuint64_t timer_period;\n+\tuint32_t enabled;\n };\n \n struct app_thread_pipeline_data {\n+\tuint32_t pipeline_id;\n \tvoid *be;\n \tpipeline_be_op_run f_run;\n \tpipeline_be_op_timer f_timer;\n@@ -242,6 +244,9 @@ struct app_thread_data {\n \tuint32_t n_custom;\n \n \tuint64_t deadline;\n+\n+\tstruct rte_ring *msgq_in;\n+\tstruct rte_ring *msgq_out;\n };\n \n struct app_eal_params {\ndiff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/config_parse.c\nindex c9b78f9..d2aaadf 100644\n--- a/examples/ip_pipeline/config_parse.c\n+++ b/examples/ip_pipeline/config_parse.c\n@@ -362,7 +362,7 @@ parser_read_uint32(uint32_t *value, const char *p)\n \treturn 0;\n }\n \n-static int\n+int\n parse_pipeline_core(uint32_t *socket,\n \tuint32_t *core,\n \tuint32_t *ht,\ndiff --git a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c\nindex 3f9c68d..1126288 100644\n--- a/examples/ip_pipeline/init.c\n+++ b/examples/ip_pipeline/init.c\n@@ -50,6 +50,7 @@\n #include \"pipeline_firewall.h\"\n #include \"pipeline_flow_classification.h\"\n #include \"pipeline_routing.h\"\n+#include \"thread.h\"\n \n #define APP_NAME_SIZE\t32\n \n@@ -1225,6 +1226,48 @@ app_init_pipelines(struct app_params *app)\n \t}\n }\n \n+static inline struct rte_ring *\n+app_thread_msgq_in_get(struct app_params *app,\n+\t\tuint32_t socket_id, uint32_t core_id, uint32_t ht_id)\n+{\n+\tchar msgq_name[32];\n+\tssize_t param_idx;\n+\n+\tsnprintf(msgq_name, sizeof(msgq_name),\n+\t\t\"MSGQ-REQ-CORE-s%\" PRIu32 \"c%\" PRIu32 \"%s\",\n+\t\tsocket_id,\n+\t\tcore_id,\n+\t\t(ht_id) ? \"h\" : \"\");\n+\tparam_idx = APP_PARAM_FIND(app->msgq_params, msgq_name);\n+\n+\tif (param_idx < 0)\n+\t\treturn NULL;\n+\n+\treturn app->msgq[param_idx];\n+}\n+\n+static inline struct rte_ring *\n+app_thread_msgq_out_get(struct app_params *app,\n+\t\tuint32_t socket_id, uint32_t core_id, uint32_t ht_id)\n+{\n+\tchar msgq_name[32];\n+\tssize_t param_idx;\n+\n+\tsnprintf(msgq_name, sizeof(msgq_name),\n+\t\t\"MSGQ-RSP-CORE-s%\" PRIu32 \"c%\" PRIu32 \"%s\",\n+\t\tsocket_id,\n+\t\tcore_id,\n+\t\t(ht_id) ? \"h\" : \"\");\n+\tparam_idx = APP_PARAM_FIND(app->msgq_params, msgq_name);\n+\n+\n+\tif (param_idx < 0)\n+\t\treturn NULL;\n+\n+\treturn app->msgq[param_idx];\n+\n+}\n+\n static void\n app_init_threads(struct app_params *app)\n {\n@@ -1253,6 +1296,20 @@ app_init_threads(struct app_params *app)\n \n \t\tt = &app->thread_data[lcore_id];\n \n+\t\tt->msgq_in = app_thread_msgq_in_get(app,\n+\t\t\t\tparams->socket_id,\n+\t\t\t\tparams->core_id,\n+\t\t\t\tparams->hyper_th_id);\n+\t\tif (t->msgq_in == NULL)\n+\t\t\trte_panic(\"Init error: Cannot find MSGQ_IN for thread %\" PRId32, lcore_id);\n+\n+\t\tt->msgq_out = app_thread_msgq_out_get(app,\n+\t\t\t\tparams->socket_id,\n+\t\t\t\tparams->core_id,\n+\t\t\t\tparams->hyper_th_id);\n+\t\tif (t->msgq_out == NULL)\n+\t\t\trte_panic(\"Init error: Cannot find MSGQ_OUT for thread %\" PRId32, lcore_id);\n+\n \t\tptype = app_pipeline_type_find(app, params->type);\n \t\tif (ptype == NULL)\n \t\t\trte_panic(\"Init error: Unknown pipeline \"\n@@ -1262,12 +1319,15 @@ app_init_threads(struct app_params *app)\n \t\t\t&t->regular[t->n_regular] :\n \t\t\t&t->custom[t->n_custom];\n \n+\t\tp->pipeline_id = p_id;\n \t\tp->be = data->be;\n \t\tp->f_run = ptype->be_ops->f_run;\n \t\tp->f_timer = ptype->be_ops->f_timer;\n \t\tp->timer_period = data->timer_period;\n \t\tp->deadline = time + data->timer_period;\n \n+\t\tdata->enabled = 1;\n+\n \t\tif (ptype->be_ops->f_run == NULL)\n \t\t\tt->n_regular++;\n \t\telse\n@@ -1288,6 +1348,7 @@ int app_init(struct app_params *app)\n \tapp_init_msgq(app);\n \n \tapp_pipeline_common_cmd_push(app);\n+\tapp_pipeline_thread_cmd_push(app);\n \tapp_pipeline_type_register(app, &pipeline_master);\n \tapp_pipeline_type_register(app, &pipeline_passthrough);\n \tapp_pipeline_type_register(app, &pipeline_flow_classification);\ndiff --git a/examples/ip_pipeline/pipeline.h b/examples/ip_pipeline/pipeline.h\nindex b9a56ea..dab9c36 100644\n--- a/examples/ip_pipeline/pipeline.h\n+++ b/examples/ip_pipeline/pipeline.h\n@@ -84,4 +84,10 @@ pipeline_type_cmds_count(struct pipeline_type *ptype)\n \treturn n_cmds;\n }\n \n+int\n+parse_pipeline_core(uint32_t *socket,\n+\tuint32_t *core,\n+\tuint32_t *ht,\n+\tconst char *entry);\n+\n #endif\ndiff --git a/examples/ip_pipeline/pipeline/pipeline_common_fe.h b/examples/ip_pipeline/pipeline/pipeline_common_fe.h\nindex 693848d..e84aa3a 100644\n--- a/examples/ip_pipeline/pipeline/pipeline_common_fe.h\n+++ b/examples/ip_pipeline/pipeline/pipeline_common_fe.h\n@@ -68,6 +68,9 @@ app_pipeline_data_fe(struct app_params *app, uint32_t id)\n \tif (pipeline_data == NULL)\n \t\treturn NULL;\n \n+\tif (pipeline_data->enabled == 0)\n+\t\treturn NULL;\n+\n \treturn pipeline_data->fe;\n }\n \ndiff --git a/examples/ip_pipeline/thread.c b/examples/ip_pipeline/thread.c\nindex b2a8656..8aabee0 100644\n--- a/examples/ip_pipeline/thread.c\n+++ b/examples/ip_pipeline/thread.c\n@@ -37,8 +37,139 @@\n \n #include \"pipeline_common_be.h\"\n #include \"app.h\"\n+#include \"thread.h\"\n \n-int app_thread(void *arg)\n+static inline void *\n+thread_msg_recv(struct rte_ring *r)\n+{\n+\tvoid *msg;\n+\tint status = rte_ring_sc_dequeue(r, &msg);\n+\n+\tif (status != 0)\n+\t\treturn NULL;\n+\n+\treturn msg;\n+}\n+\n+static inline void\n+thread_msg_send(struct rte_ring *r,\n+\tvoid *msg)\n+{\n+\tint status;\n+\n+\tdo {\n+\t\tstatus = rte_ring_sp_enqueue(r, msg);\n+\t} while (status == -ENOBUFS);\n+}\n+\n+static int\n+thread_pipeline_enable(struct app_thread_data *t,\n+\t\tstruct thread_pipeline_enable_msg_req *req)\n+{\n+\tstruct app_thread_pipeline_data *p;\n+\n+\tp = (req->f_run == NULL) ?\n+\t\t&t->regular[t->n_regular] :\n+\t\t&t->custom[t->n_custom];\n+\n+\tif (t->n_regular >= APP_MAX_THREAD_PIPELINES)\n+\t\treturn -1;\n+\n+\tp->pipeline_id = req->pipeline_id;\n+\tp->be = req->be;\n+\tp->f_run = req->f_run;\n+\tp->f_timer = req->f_timer;\n+\tp->timer_period = req->timer_period;\n+\tp->deadline = 0;\n+\n+\tif (req->f_run == NULL)\n+\t\tt->n_regular++;\n+\telse\n+\t\tt->n_custom++;\n+\n+\treturn 0;\n+}\n+\n+static int\n+thread_pipeline_disable(struct app_thread_data *t,\n+\t\tstruct thread_pipeline_disable_msg_req *req)\n+{\n+\tuint32_t i;\n+\n+\tprintf(\"%p\\n\", req);\n+\tprintf(\"%d %d\\n\", req->type, req->pipeline_id);\n+\n+\tfor (i = 0; i < t->n_regular; i++) {\n+\t\tif (t->regular[i].pipeline_id == req->pipeline_id)\n+\t\t\tbreak;\n+\t}\n+\n+\tif (i < t->n_regular) {\n+\t\tif (i < t->n_regular - 1)\n+\t\t\tmemcpy(&t->regular[i],\n+\t\t\t\t&t->regular[i+1],\n+\t\t\t\t(t->n_regular - i) * sizeof(struct app_thread_pipeline_data));\n+\n+\t\tt->n_regular--;\n+\n+\t\treturn 0;\n+\t}\n+\n+\tfor (i = 0; i < t->n_custom; i++) {\n+\t\tif (t->custom[i].pipeline_id == req->pipeline_id)\n+\t\t\tbreak;\n+\t}\n+\n+\t/* return if pipeline not found */\n+\tif (i >= t->n_custom)\n+\t\treturn -1;\n+\n+\tif (i < t->n_custom - 1)\n+\t\tmemcpy(&t->custom[i],\n+\t\t\t&t->custom[i+1],\n+\t\t\t(t->n_custom - i) * sizeof(struct app_thread_pipeline_data));\n+\n+\tt->n_custom--;\n+\n+\treturn 0;\n+}\n+\n+static int\n+thread_msg_req_handle(struct app_thread_data *t)\n+{\n+\tvoid *msg_ptr;\n+\tstruct thread_msg_req *req;\n+\tstruct thread_msg_rsp *rsp;\n+\n+\tmsg_ptr = thread_msg_recv(t->msgq_in);\n+\treq = msg_ptr;\n+\trsp = msg_ptr;\n+\n+\tif (req != NULL)\n+\t\tswitch (req->type) {\n+\t\tcase THREAD_MSG_REQ_PIPELINE_ENABLE: {\n+\t\t\trsp->status = thread_pipeline_enable(t,\n+\t\t\t\t\t(struct thread_pipeline_enable_msg_req *) req);\n+\t\t\tthread_msg_send(t->msgq_out, rsp);\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\tcase THREAD_MSG_REQ_PIPELINE_DISABLE: {\n+\t\t\trsp->status = thread_pipeline_disable(t,\n+\t\t\t\t\t(struct thread_pipeline_disable_msg_req *) req);\n+\t\t\tprintf(\"THREAD STATUS: %d\\n\", rsp->status);\n+\t\t\tthread_msg_send(t->msgq_out, rsp);\n+\t\t\tbreak;\n+\t\t}\n+\t\tdefault:\n+\t\t\tbreak;\n+\t\t}\n+\n+\treturn 0;\n+}\n+\n+int\n+app_thread(void *arg)\n {\n \tstruct app_params *app = (struct app_params *) arg;\n \tuint32_t core_id = rte_lcore_id(), i, j;\n@@ -103,6 +234,8 @@ int app_thread(void *arg)\n \t\t\t}\n \n \t\t\tt->deadline = t_deadline;\n+\n+\t\t\tthread_msg_req_handle(t);\n \t\t}\n \t}\n \ndiff --git a/examples/ip_pipeline/thread.h b/examples/ip_pipeline/thread.h\nnew file mode 100644\nindex 0000000..878c9e1\n--- /dev/null\n+++ b/examples/ip_pipeline/thread.h\n@@ -0,0 +1,101 @@\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 THREAD_H_\n+#define THREAD_H_\n+\n+#include \"app.h\"\n+#include \"pipeline_be.h\"\n+\n+enum thread_msg_req_type {\n+\tTHREAD_MSG_REQ_PIPELINE_ENABLE = 0,\n+\tTHREAD_MSG_REQ_PIPELINE_DISABLE,\n+\tTHREAD_MSG_REQS\n+};\n+\n+struct thread_msg_req {\n+\tenum thread_msg_req_type type;\n+};\n+\n+struct thread_msg_rsp {\n+\tint status;\n+};\n+\n+/*\n+ * PIPELINE ENABLE\n+ */\n+struct thread_pipeline_enable_msg_req {\n+\tenum thread_msg_req_type type;\n+\n+\tuint32_t pipeline_id;\n+\tvoid *be;\n+\tpipeline_be_op_run f_run;\n+\tpipeline_be_op_timer f_timer;\n+\tuint64_t timer_period;\n+};\n+\n+struct thread_pipeline_enable_msg_rsp {\n+\tint status;\n+};\n+\n+/*\n+ * PIPELINE DISABLE\n+ */\n+struct thread_pipeline_disable_msg_req {\n+\tenum thread_msg_req_type type;\n+\n+\tuint32_t pipeline_id;\n+};\n+\n+struct thread_pipeline_disable_msg_rsp {\n+\tint status;\n+};\n+\n+int\n+app_pipeline_thread_cmd_push(struct app_params *app);\n+\n+int\n+app_pipeline_enable(struct app_params *app,\n+\t\tuint32_t core_id,\n+\t\tuint32_t socket_id,\n+\t\tuint32_t hyper_th_id,\n+\t\tuint32_t pipeline_id);\n+\n+int\n+app_pipeline_disable(struct app_params *app,\n+\t\tuint32_t core_id,\n+\t\tuint32_t socket_id,\n+\t\tuint32_t hyper_th_id,\n+\t\tuint32_t pipeline_id);\n+\n+#endif /* THREAD_H_ */\ndiff --git a/examples/ip_pipeline/thread_fe.c b/examples/ip_pipeline/thread_fe.c\nnew file mode 100644\nindex 0000000..3f05b44\n--- /dev/null\n+++ b/examples/ip_pipeline/thread_fe.c\n@@ -0,0 +1,328 @@\n+#include <rte_common.h>\n+#include <rte_ring.h>\n+#include <rte_malloc.h>\n+#include <cmdline_rdline.h>\n+#include <cmdline_parse.h>\n+#include <cmdline_parse_num.h>\n+#include <cmdline_parse_string.h>\n+#include <cmdline_parse_ipaddr.h>\n+#include <cmdline_parse_etheraddr.h>\n+#include <cmdline_socket.h>\n+#include <cmdline.h>\n+\n+#include \"thread.h\"\n+#include \"pipeline.h\"\n+#include \"pipeline_common_fe.h\"\n+#include \"app.h\"\n+\n+static inline void *\n+thread_msg_send_recv(struct app_params *app,\n+\tuint32_t thread_id,\n+\tvoid *msg,\n+\tuint32_t timeout_ms)\n+{\n+\tstruct rte_ring *r_req = app->thread_data[thread_id].msgq_in;\n+\tstruct rte_ring *r_rsp = app->thread_data[thread_id].msgq_out;\n+\tuint64_t hz = rte_get_tsc_hz();\n+\tvoid *msg_recv;\n+\tuint64_t deadline;\n+\tint status;\n+\n+\t/* send */\n+\tdo {\n+\t\tstatus = rte_ring_sp_enqueue(r_req, (void *) msg);\n+\t} while (status == -ENOBUFS);\n+\n+\t/* recv */\n+\tdeadline = (timeout_ms) ?\n+\t\t(rte_rdtsc() + ((hz * timeout_ms) / 1000)) :\n+\t\tUINT64_MAX;\n+\n+\tdo {\n+\t\tif (rte_rdtsc() > deadline)\n+\t\t\treturn NULL;\n+\n+\t\tstatus = rte_ring_sc_dequeue(r_rsp, &msg_recv);\n+\t} while (status != 0);\n+\n+\treturn msg_recv;\n+}\n+\n+int\n+app_pipeline_enable(struct app_params *app,\n+\t\tuint32_t socket_id,\n+\t\tuint32_t core_id,\n+\t\tuint32_t hyper_th_id,\n+\t\tuint32_t pipeline_id)\n+{\n+\tstruct thread_pipeline_enable_msg_req *req;\n+\tstruct thread_pipeline_enable_msg_rsp *rsp;\n+\n+\tint thread_id;\n+\n+\tstruct app_pipeline_data *p;\n+\tstruct app_pipeline_params *p_params;\n+\tstruct pipeline_type *p_type;\n+\n+\tif (app_pipeline_data(app, pipeline_id) == NULL)\n+\t\treturn -1;\n+\n+\tthread_id = cpu_core_map_get_lcore_id(app->core_map,\n+\t\t\tsocket_id,\n+\t\t\tcore_id,\n+\t\t\thyper_th_id);\n+\n+\tif (thread_id < 0)\n+\t\treturn -1;\n+\n+\treq = app_msg_alloc(app);\n+\tif (req == NULL)\n+\t\treturn -1;\n+\n+\tp = &app->pipeline_data[pipeline_id];\n+\tp_params = &app->pipeline_params[pipeline_id];\n+\tp_type = app_pipeline_type_find(app, p_params->type);\n+\n+\tif (p->enabled == 1)\n+\t\treturn -1;\n+\n+\treq->type = THREAD_MSG_REQ_PIPELINE_ENABLE;\n+\treq->pipeline_id = pipeline_id;\n+\treq->be = p->be;\n+\treq->f_run = p_type->be_ops->f_run;\n+\treq->f_timer = p_type->be_ops->f_timer;\n+\treq->timer_period = p->timer_period;\n+\n+\trsp = thread_msg_send_recv(app, thread_id, req, 5 * MSG_TIMEOUT_DEFAULT);\n+\tif (rsp == NULL)\n+\t\treturn -1;\n+\n+\tif (rsp->status < 0)\n+\t\treturn -1;\n+\n+\tp->enabled = 1;\n+\treturn 0;\n+}\n+\n+\n+int\n+app_pipeline_disable(struct app_params *app,\n+\t\tuint32_t socket_id,\n+\t\tuint32_t core_id,\n+\t\tuint32_t hyper_th_id,\n+\t\tuint32_t pipeline_id)\n+{\n+\tstruct thread_pipeline_disable_msg_req *req;\n+\tstruct thread_pipeline_disable_msg_rsp *rsp;\n+\n+\tint thread_id;\n+\n+\tstruct app_pipeline_data *p;\n+\n+\tif (app_pipeline_data(app, pipeline_id) == NULL)\n+\t\treturn -1;\n+\n+\tthread_id = cpu_core_map_get_lcore_id(app->core_map,\n+\t\t\tsocket_id,\n+\t\t\tcore_id,\n+\t\t\thyper_th_id);\n+\n+\tif (thread_id < 0)\n+\t\treturn -1;\n+\n+\tp = &app->pipeline_data[pipeline_id];\n+\n+\tif (p->enabled == 0)\n+\t\treturn -1;\n+\n+\treq = app_msg_alloc(app);\n+\tif (req == NULL)\n+\t\treturn -1;\n+\n+\treq->type = THREAD_MSG_REQ_PIPELINE_DISABLE;\n+\treq->pipeline_id = pipeline_id;\n+\n+\tprintf(\"%p\\n\", req);\n+\tprintf(\"%d %d\\n\", req->type, req->pipeline_id);\n+\n+\trsp = thread_msg_send_recv(app, thread_id, req, 5 * MSG_TIMEOUT_DEFAULT);\n+\n+\tprintf(\"RSP: %p\\n\", rsp);\n+\tif (rsp == NULL)\n+\t\treturn -1;\n+\n+\tprintf(\"%d\\n\", rsp->status);\n+\tif (rsp->status < 0)\n+\t\treturn -1;\n+\n+\tp->enabled = 0;\n+\treturn 0;\n+}\n+\n+struct cmd_pipeline_enable_result {\n+\tcmdline_fixed_string_t t_string;\n+\tcmdline_fixed_string_t t_id;\n+\tcmdline_fixed_string_t pipeline_string;\n+\tuint32_t pipeline_id;\n+\tcmdline_fixed_string_t enable_string;\n+};\n+\n+static void\n+cmd_pipeline_enable_parsed(\n+\tvoid *parsed_result,\n+\t__attribute__((unused)) struct cmdline *cl,\n+\t void *data)\n+{\n+\tstruct cmd_pipeline_enable_result *params = parsed_result;\n+\tstruct app_params *app = data;\n+\n+\tint status;\n+\n+\tuint32_t core_id, socket_id, hyper_th_id;\n+\n+\tif (parse_pipeline_core(&socket_id,\n+\t\t\t&core_id,\n+\t\t\t&hyper_th_id,\n+\t\t\tparams->t_id) < 0) {\n+\t\tprintf(\"Command failed\\n\");\n+\t\treturn;\n+\t}\n+\n+\tstatus = app_pipeline_enable(app,\n+\t\t\tsocket_id,\n+\t\t\tcore_id,\n+\t\t\thyper_th_id,\n+\t\t\tparams->pipeline_id);\n+\n+\tif (status != 0)\n+\t\tprintf(\"Command failed\\n\");\n+}\n+\n+cmdline_parse_token_string_t cmd_pipeline_enable_t_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_pipeline_enable_result, t_string, \"t\");\n+\n+cmdline_parse_token_string_t cmd_pipeline_enable_t_id =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_pipeline_enable_result, t_id, NULL);\n+\n+cmdline_parse_token_string_t cmd_pipeline_enable_pipeline_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_pipeline_enable_result, pipeline_string,\n+\t\t\"pipeline\");\n+\n+cmdline_parse_token_num_t cmd_pipeline_enable_pipeline_id =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_pipeline_enable_result, pipeline_id, UINT32);\n+\n+cmdline_parse_token_string_t cmd_pipeline_enable_enable_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_pipeline_enable_result, enable_string, \"enable\");\n+\n+cmdline_parse_inst_t cmd_pipeline_enable = {\n+\t.f = cmd_pipeline_enable_parsed,\n+\t.data = NULL,\n+\t.help_str = \"Enable pipeline on specified core\",\n+\t.tokens = {\n+\t\t(void *)&cmd_pipeline_enable_t_string,\n+\t\t(void *)&cmd_pipeline_enable_t_id,\n+\t\t(void *)&cmd_pipeline_enable_pipeline_string,\n+\t\t(void *)&cmd_pipeline_enable_pipeline_id,\n+\t\t(void *)&cmd_pipeline_enable_enable_string,\n+\t\tNULL,\n+\t},\n+};\n+\n+struct cmd_pipeline_disable_result {\n+\tcmdline_fixed_string_t t_string;\n+\tcmdline_fixed_string_t t_id;\n+\tcmdline_fixed_string_t pipeline_string;\n+\tuint32_t pipeline_id;\n+\tcmdline_fixed_string_t disable_string;\n+};\n+\n+static void\n+cmd_pipeline_disable_parsed(\n+\tvoid *parsed_result,\n+\t__attribute__((unused)) struct cmdline *cl,\n+\t void *data)\n+{\n+\tstruct cmd_pipeline_enable_result *params = parsed_result;\n+\tstruct app_params *app = data;\n+\n+\tint status;\n+\n+\tuint32_t core_id, socket_id, hyper_th_id;\n+\n+\tif (parse_pipeline_core(&socket_id,\n+\t\t\t&core_id,\n+\t\t\t&hyper_th_id,\n+\t\t\tparams->t_id) < 0) {\n+\t\tprintf(\"Command failed\\n\");\n+\t\treturn;\n+\t}\n+\n+\tstatus = app_pipeline_disable(app,\n+\t\t\tsocket_id,\n+\t\t\tcore_id,\n+\t\t\thyper_th_id,\n+\t\t\tparams->pipeline_id);\n+\n+\tif (status != 0)\n+\t\tprintf(\"Command failed\\n\");\n+}\n+\n+cmdline_parse_token_string_t cmd_pipeline_disable_t_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_pipeline_disable_result, t_string, \"t\");\n+\n+cmdline_parse_token_string_t cmd_pipeline_disable_t_id =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_pipeline_disable_result, t_id, NULL);\n+\n+cmdline_parse_token_string_t cmd_pipeline_disable_pipeline_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_pipeline_disable_result, pipeline_string,\n+\t\t\"pipeline\");\n+\n+cmdline_parse_token_num_t cmd_pipeline_disable_pipeline_id =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_pipeline_disable_result, pipeline_id, UINT32);\n+\n+cmdline_parse_token_string_t cmd_pipeline_disable_enable_string =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_pipeline_disable_result, disable_string, \"disable\");\n+\n+cmdline_parse_inst_t cmd_pipeline_disable = {\n+\t.f = cmd_pipeline_disable_parsed,\n+\t.data = NULL,\n+\t.help_str = \"Disable pipeline on specified core\",\n+\t.tokens = {\n+\t\t(void *)&cmd_pipeline_disable_t_string,\n+\t\t(void *)&cmd_pipeline_disable_t_id,\n+\t\t(void *)&cmd_pipeline_disable_pipeline_string,\n+\t\t(void *)&cmd_pipeline_disable_pipeline_id,\n+\t\t(void *)&cmd_pipeline_disable_enable_string,\n+\t\tNULL,\n+\t},\n+};\n+\n+static cmdline_parse_ctx_t thread_cmds[] = {\n+\t(cmdline_parse_inst_t *) &cmd_pipeline_enable,\n+\t(cmdline_parse_inst_t *) &cmd_pipeline_disable,\n+\tNULL,\n+};\n+\n+int\n+app_pipeline_thread_cmd_push(struct app_params *app)\n+{\n+\tuint32_t n_cmds, i;\n+\n+\t/* Check for available slots in the application commands array */\n+\tn_cmds = RTE_DIM(thread_cmds) - 1;\n+\tif (n_cmds > APP_MAX_CMDS - app->n_cmds)\n+\t\treturn -ENOMEM;\n+\n+\t/* Push pipeline commands into the application */\n+\tmemcpy(&app->cmds[app->n_cmds],\n+\t\t\tthread_cmds,\n+\t\tn_cmds * sizeof(cmdline_parse_ctx_t *));\n+\n+\tfor (i = 0; i < n_cmds; i++)\n+\t\tapp->cmds[app->n_cmds + i]->data = app;\n+\n+\tapp->n_cmds += n_cmds;\n+\tapp->cmds[app->n_cmds] = NULL;\n+\n+\treturn 0;\n+}\n",
    "prefixes": [
        "dpdk-dev",
        "1/1"
    ]
}