get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 49404,
    "url": "https://patches.dpdk.org/api/patches/49404/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20190103160432.147027-1-cristian.dumitrescu@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": "<20190103160432.147027-1-cristian.dumitrescu@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20190103160432.147027-1-cristian.dumitrescu@intel.com",
    "date": "2019-01-03T16:04:32",
    "name": "net/softnic: add support for service cores",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "c581059ac76637af75a4c42d354bc9d53fbeaf2b",
    "submitter": {
        "id": 19,
        "url": "https://patches.dpdk.org/api/people/19/?format=api",
        "name": "Cristian Dumitrescu",
        "email": "cristian.dumitrescu@intel.com"
    },
    "delegate": {
        "id": 10018,
        "url": "https://patches.dpdk.org/api/users/10018/?format=api",
        "username": "cristian_dumitrescu",
        "first_name": "Cristian",
        "last_name": "Dumitrescu",
        "email": "cristian.dumitrescu@intel.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20190103160432.147027-1-cristian.dumitrescu@intel.com/mbox/",
    "series": [
        {
            "id": 3001,
            "url": "https://patches.dpdk.org/api/series/3001/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=3001",
            "date": "2019-01-03T16:04:32",
            "name": "net/softnic: add support for service cores",
            "version": 1,
            "mbox": "https://patches.dpdk.org/series/3001/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/49404/comments/",
    "check": "warning",
    "checks": "https://patches.dpdk.org/api/patches/49404/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 04CCE1B3A2;\n\tThu,  3 Jan 2019 17:04:37 +0100 (CET)",
            "from mga18.intel.com (mga18.intel.com [134.134.136.126])\n\tby dpdk.org (Postfix) with ESMTP id 84BD61B39F\n\tfor <dev@dpdk.org>; Thu,  3 Jan 2019 17:04:35 +0100 (CET)",
            "from orsmga001.jf.intel.com ([10.7.209.18])\n\tby orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t03 Jan 2019 08:04:34 -0800",
            "from silpixa00382658.ir.intel.com (HELO\n\tsilpixa00382658.ger.corp.intel.com) ([10.237.223.75])\n\tby orsmga001.jf.intel.com with ESMTP; 03 Jan 2019 08:04:33 -0800"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.56,435,1539673200\"; d=\"scan'208\";a=\"123820643\"",
        "From": "Cristian Dumitrescu <cristian.dumitrescu@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "Jasvinder Singh <jasvinder.singh@intel.com>",
        "Date": "Thu,  3 Jan 2019 16:04:32 +0000",
        "Message-Id": "<20190103160432.147027-1-cristian.dumitrescu@intel.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "Subject": "[dpdk-dev] [PATCH] net/softnic: add support for service cores",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n\t<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\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Add support to run the Soft NIC device on service cores, based on the\nvalue of the sc parameter:\n\n0: The current Soft NIC device is run explicitly by the application. The\n   firmware creates one or several pipelines for this dev and maps them\n   to CPU cores that should not be service cores. The app is required to\n   call rte_pmd_softnic_run() to make this dev work.\n\n1 (default): The current device is run on the service cores transparently\n   to the app. The firmware creates one or several pipelines for this dev\n   current device and maps them to CPU cores that should be service cores.\n   Each of these service cores is calling rte_pmd_softnic_run()\n   in order to make this dev work with no app intervention.\n\nSigned-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>\nSigned-off-by: Jasvinder Singh <jasvinder.singh@intel.com>\n---\n drivers/net/softnic/rte_eth_softnic.c         |  11 ++\n drivers/net/softnic/rte_eth_softnic.h         |  20 +++\n .../net/softnic/rte_eth_softnic_internals.h   |   6 +-\n .../net/softnic/rte_eth_softnic_pipeline.c    |  13 ++\n drivers/net/softnic/rte_eth_softnic_thread.c  | 139 ++++++++++++++----\n 5 files changed, 161 insertions(+), 28 deletions(-)",
    "diff": "diff --git a/drivers/net/softnic/rte_eth_softnic.c b/drivers/net/softnic/rte_eth_softnic.c\nindex 14d4a1030..32b001fd3 100644\n--- a/drivers/net/softnic/rte_eth_softnic.c\n+++ b/drivers/net/softnic/rte_eth_softnic.c\n@@ -22,6 +22,7 @@\n #define PMD_PARAM_FIRMWARE                                 \"firmware\"\n #define PMD_PARAM_CONN_PORT                                \"conn_port\"\n #define PMD_PARAM_CPU_ID                                   \"cpu_id\"\n+#define PMD_PARAM_SC                                       \"sc\"\n #define PMD_PARAM_TM_N_QUEUES                              \"tm_n_queues\"\n #define PMD_PARAM_TM_QSIZE0                                \"tm_qsize0\"\n #define PMD_PARAM_TM_QSIZE1                                \"tm_qsize1\"\n@@ -32,6 +33,7 @@ static const char * const pmd_valid_args[] = {\n \tPMD_PARAM_FIRMWARE,\n \tPMD_PARAM_CONN_PORT,\n \tPMD_PARAM_CPU_ID,\n+\tPMD_PARAM_SC,\n \tPMD_PARAM_TM_N_QUEUES,\n \tPMD_PARAM_TM_QSIZE0,\n \tPMD_PARAM_TM_QSIZE1,\n@@ -426,6 +428,7 @@ pmd_parse_args(struct pmd_params *p, const char *params)\n \tmemset(p, 0, sizeof(*p));\n \tp->firmware = SOFTNIC_FIRMWARE;\n \tp->cpu_id = SOFTNIC_CPU_ID;\n+\tp->sc = SOFTNIC_SC;\n \tp->tm.n_queues = SOFTNIC_TM_N_QUEUES;\n \tp->tm.qsize[0] = SOFTNIC_TM_QUEUE_SIZE;\n \tp->tm.qsize[1] = SOFTNIC_TM_QUEUE_SIZE;\n@@ -456,6 +459,14 @@ pmd_parse_args(struct pmd_params *p, const char *params)\n \t\t\tgoto out_free;\n \t}\n \n+\t/* Service cores (optional) */\n+\tif (rte_kvargs_count(kvlist, PMD_PARAM_SC) == 1) {\n+\t\tret = rte_kvargs_process(kvlist, PMD_PARAM_SC,\n+\t\t\t&get_uint32, &p->sc);\n+\t\tif (ret < 0)\n+\t\t\tgoto out_free;\n+\t}\n+\n \t/* TM number of queues (optional) */\n \tif (rte_kvargs_count(kvlist, PMD_PARAM_TM_N_QUEUES) == 1) {\n \t\tret = rte_kvargs_process(kvlist, PMD_PARAM_TM_N_QUEUES,\ndiff --git a/drivers/net/softnic/rte_eth_softnic.h b/drivers/net/softnic/rte_eth_softnic.h\nindex 048dfe6bf..e8ba2bcaa 100644\n--- a/drivers/net/softnic/rte_eth_softnic.h\n+++ b/drivers/net/softnic/rte_eth_softnic.h\n@@ -26,6 +26,26 @@ extern \"C\" {\n #define SOFTNIC_CPU_ID                                     0\n #endif\n \n+/**\n+ * Service cores:\n+ *\n+ * 0 = The current device is run explicitly by the application. The firmware\n+ *     creates one or several pipelines for the current device and maps them to\n+ *     CPU cores that should not be service cores. The application is required\n+ *     to call rte_pmd_softnic_run() for the current device on each of these CPU\n+ *     cores in order to make the current device work.\n+ *\n+ * 1 = The current device is run on the service cores transparently to the\n+ *     application. The firmware creates one or several pipelines for the\n+ *     current device and maps them to CPU cores that should be service cores.\n+ *     Each of these service cores is calling rte_pmd_softnic_run() for the\n+ *     current device in order to make the current device work. The application\n+ *     is not allowed to call rte_pmd_softnic_run() for the current device.\n+ */\n+#ifndef SOFTNIC_SC\n+#define SOFTNIC_SC                                         1\n+#endif\n+\n /** Traffic Manager: Number of scheduler queues. */\n #ifndef SOFTNIC_TM_N_QUEUES\n #define SOFTNIC_TM_N_QUEUES                                (64 * 1024)\ndiff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h\nindex 31698b9f0..3bc1de852 100644\n--- a/drivers/net/softnic/rte_eth_softnic_internals.h\n+++ b/drivers/net/softnic/rte_eth_softnic_internals.h\n@@ -38,6 +38,7 @@ struct pmd_params {\n \tconst char *firmware;\n \tuint16_t conn_port;\n \tuint32_t cpu_id;\n+\tint sc; /**< Service cores. */\n \n \t/** Traffic Management (TM) */\n \tstruct {\n@@ -547,7 +548,7 @@ struct softnic_thread {\n \tstruct rte_ring *msgq_req;\n \tstruct rte_ring *msgq_rsp;\n \n-\tuint32_t enabled;\n+\tuint32_t service_id;\n };\n \n /**\n@@ -843,6 +844,9 @@ softnic_pipeline_free(struct pmd_internals *p);\n void\n softnic_pipeline_disable_all(struct pmd_internals *p);\n \n+uint32_t\n+softnic_pipeline_thread_count(struct pmd_internals *p, uint32_t thread_id);\n+\n struct pipeline *\n softnic_pipeline_find(struct pmd_internals *p, const char *name);\n \ndiff --git a/drivers/net/softnic/rte_eth_softnic_pipeline.c b/drivers/net/softnic/rte_eth_softnic_pipeline.c\nindex 5e180f8f7..308fd1534 100644\n--- a/drivers/net/softnic/rte_eth_softnic_pipeline.c\n+++ b/drivers/net/softnic/rte_eth_softnic_pipeline.c\n@@ -108,6 +108,19 @@ softnic_pipeline_disable_all(struct pmd_internals *p)\n \t\t\t\tpipeline->name);\n }\n \n+uint32_t\n+softnic_pipeline_thread_count(struct pmd_internals *p, uint32_t thread_id)\n+{\n+\tstruct pipeline *pipeline;\n+\tuint32_t count = 0;\n+\n+\tTAILQ_FOREACH(pipeline, &p->pipeline_list, node)\n+\t\tif ((pipeline->enabled) && (pipeline->thread_id == thread_id))\n+\t\t\tcount++;\n+\n+\treturn count;\n+}\n+\n struct pipeline *\n softnic_pipeline_find(struct pmd_internals *p,\n \tconst char *name)\ndiff --git a/drivers/net/softnic/rte_eth_softnic_thread.c b/drivers/net/softnic/rte_eth_softnic_thread.c\nindex 4572adfa6..68c1f50a6 100644\n--- a/drivers/net/softnic/rte_eth_softnic_thread.c\n+++ b/drivers/net/softnic/rte_eth_softnic_thread.c\n@@ -7,6 +7,7 @@\n #include <rte_common.h>\n #include <rte_cycles.h>\n #include <rte_lcore.h>\n+#include <rte_service_component.h>\n #include <rte_ring.h>\n \n #include <rte_table_acl.h>\n@@ -41,7 +42,7 @@ softnic_thread_init(struct pmd_internals *softnic)\n {\n \tuint32_t i;\n \n-\tRTE_LCORE_FOREACH_SLAVE(i) {\n+\tfor (i = 0; i < RTE_MAX_LCORE; i++) {\n \t\tchar ring_name[NAME_MAX];\n \t\tstruct rte_ring *msgq_req, *msgq_rsp;\n \t\tstruct softnic_thread *t = &softnic->thread[i];\n@@ -80,7 +81,7 @@ softnic_thread_init(struct pmd_internals *softnic)\n \t\t/* Master thread records */\n \t\tt->msgq_req = msgq_req;\n \t\tt->msgq_rsp = msgq_rsp;\n-\t\tt->enabled = 1;\n+\t\tt->service_id = UINT32_MAX;\n \n \t\t/* Data plane thread records */\n \t\tt_data->n_pipelines = 0;\n@@ -95,6 +96,25 @@ softnic_thread_init(struct pmd_internals *softnic)\n \treturn 0;\n }\n \n+static inline int\n+thread_is_valid(struct pmd_internals *softnic, uint32_t thread_id)\n+{\n+\tstruct rte_config *cfg = rte_eal_get_configuration();\n+\tenum rte_lcore_role_t role;\n+\n+\tif ((thread_id >= RTE_MAX_LCORE) ||\n+\t\t(thread_id == cfg->master_lcore))\n+\t\treturn 0; /* FALSE */\n+\n+\trole = cfg->lcore_role[thread_id];\n+\n+\tif ((softnic->params.sc && (role == ROLE_SERVICE)) ||\n+\t\t(!softnic->params.sc && (role == ROLE_RTE)))\n+\t\treturn 1; /* TRUE */\n+\n+\treturn 0; /* FALSE */\n+}\n+\n static inline int\n thread_is_running(uint32_t thread_id)\n {\n@@ -104,6 +124,73 @@ thread_is_running(uint32_t thread_id)\n \treturn (thread_state == RUNNING)? 1 : 0;\n }\n \n+static inline int\n+thread_sc_service_up(struct pmd_internals *softnic, uint32_t thread_id)\n+{\n+\tstruct rte_service_spec service_params;\n+\tstruct softnic_thread *t = &softnic->thread[thread_id];\n+\tint status;\n+\tuint16_t port_id;\n+\n+\t/* service params */\n+\trte_eth_dev_get_port_by_name(softnic->params.name, &port_id);\n+\tsnprintf(service_params.name, sizeof(service_params.name), \"%s_%d\",\n+\t\tsoftnic->params.name,\n+\t\tthread_id);\n+\tservice_params.callback = (rte_service_func)rte_pmd_softnic_run;\n+\tservice_params.callback_userdata = (void *)((uint64_t)port_id);\n+\tservice_params.capabilities = 0;\n+\tservice_params.socket_id = (int)softnic->params.cpu_id;\n+\n+\t/* service register */\n+\tstatus = rte_service_component_register(&service_params, &t->service_id);\n+\tif (status)\n+\t\treturn status;\n+\n+\tstatus = rte_service_component_runstate_set(t->service_id, 1);\n+\tif (status) {\n+\t\trte_service_component_unregister(t->service_id);\n+\t\tt->service_id = UINT32_MAX;\n+\t\treturn status;\n+\t}\n+\n+\tstatus = rte_service_runstate_set(t->service_id, 1);\n+\tif (status) {\n+\t\trte_service_component_runstate_set(t->service_id, 0);\n+\t\trte_service_component_unregister(t->service_id);\n+\t\tt->service_id = UINT32_MAX;\n+\t\treturn status;\n+\t}\n+\n+\t/* service map to thread */\n+\tstatus = rte_service_map_lcore_set(t->service_id, thread_id, 1);\n+\tif (status) {\n+\t\trte_service_runstate_set(t->service_id, 0);\n+\t\trte_service_component_runstate_set(t->service_id, 0);\n+\t\trte_service_component_unregister(t->service_id);\n+\t\tt->service_id = UINT32_MAX;\n+\t\treturn status;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static inline void\n+thread_sc_service_down(struct pmd_internals *softnic, uint32_t thread_id)\n+{\n+\tstruct softnic_thread *t = &softnic->thread[thread_id];\n+\n+\t/* service unmap from thread */\n+\trte_service_map_lcore_set(t->service_id, thread_id, 0);\n+\n+\t/* service unregister */\n+\trte_service_runstate_set(t->service_id, 0);\n+\trte_service_component_runstate_set(t->service_id, 0);\n+\trte_service_component_unregister(t->service_id);\n+\n+\tt->service_id = UINT32_MAX;\n+}\n+\n /**\n  * Pipeline is running when:\n  *    (A) Pipeline is mapped to a data plane thread AND\n@@ -200,32 +287,34 @@ softnic_thread_pipeline_enable(struct pmd_internals *softnic,\n \tconst char *pipeline_name)\n {\n \tstruct pipeline *p = softnic_pipeline_find(softnic, pipeline_name);\n-\tstruct softnic_thread *t;\n \tstruct thread_msg_req *req;\n \tstruct thread_msg_rsp *rsp;\n-\tuint32_t i;\n+\tuint32_t n_pipelines, i;\n \tint status;\n \n \t/* Check input params */\n-\tif ((thread_id >= RTE_MAX_LCORE) ||\n+\tif (!thread_is_valid(softnic, thread_id) ||\n \t\t(p == NULL) ||\n \t\t(p->n_ports_in == 0) ||\n \t\t(p->n_ports_out == 0) ||\n-\t\t(p->n_tables == 0))\n+\t\t(p->n_tables == 0) ||\n+\t\tp->enabled)\n \t\treturn -1;\n \n-\tt = &softnic->thread[thread_id];\n-\tif ((t->enabled == 0) ||\n-\t\tp->enabled)\n+\tn_pipelines = softnic_pipeline_thread_count(softnic, thread_id);\n+\tif (n_pipelines >= THREAD_PIPELINES_MAX)\n \t\treturn -1;\n \n+\tif (softnic->params.sc && (n_pipelines == 0)) {\n+\t\tstatus = thread_sc_service_up(softnic, thread_id);\n+\t\tif (status)\n+\t\t\treturn status;\n+\t}\n+\n \tif (!thread_is_running(thread_id)) {\n \t\tstruct softnic_thread_data *td = &softnic->thread_data[thread_id];\n \t\tstruct pipeline_data *tdp = &td->pipeline_data[td->n_pipelines];\n \n-\t\tif (td->n_pipelines >= THREAD_PIPELINES_MAX)\n-\t\t\treturn -1;\n-\n \t\t/* Data plane thread */\n \t\ttd->p[td->n_pipelines] = p->p;\n \n@@ -292,26 +381,20 @@ softnic_thread_pipeline_disable(struct pmd_internals *softnic,\n \tconst char *pipeline_name)\n {\n \tstruct pipeline *p = softnic_pipeline_find(softnic, pipeline_name);\n-\tstruct softnic_thread *t;\n \tstruct thread_msg_req *req;\n \tstruct thread_msg_rsp *rsp;\n+\tuint32_t n_pipelines;\n \tint status;\n \n \t/* Check input params */\n-\tif ((thread_id >= RTE_MAX_LCORE) ||\n-\t\t(p == NULL))\n-\t\treturn -1;\n-\n-\tt = &softnic->thread[thread_id];\n-\tif (t->enabled == 0)\n+\tif (!thread_is_valid(softnic, thread_id) ||\n+\t\t(p == NULL) ||\n+\t\t(p->enabled && (p->thread_id != thread_id)))\n \t\treturn -1;\n \n \tif (p->enabled == 0)\n \t\treturn 0;\n \n-\tif (p->thread_id != thread_id)\n-\t\treturn -1;\n-\n \tif (!thread_is_running(thread_id)) {\n \t\tstruct softnic_thread_data *td = &softnic->thread_data[thread_id];\n \t\tuint32_t i;\n@@ -341,6 +424,9 @@ softnic_thread_pipeline_disable(struct pmd_internals *softnic,\n \t\t\tbreak;\n \t\t}\n \n+\t\tif (softnic->params.sc && (td->n_pipelines == 0))\n+\t\t\tthread_sc_service_down(softnic, thread_id);\n+\n \t\treturn 0;\n \t}\n \n@@ -370,6 +456,10 @@ softnic_thread_pipeline_disable(struct pmd_internals *softnic,\n \n \tp->enabled = 0;\n \n+\tn_pipelines = softnic_pipeline_thread_count(softnic, thread_id);\n+\tif (softnic->params.sc && (n_pipelines == 0))\n+\t\tthread_sc_service_down(softnic, thread_id);\n+\n \treturn 0;\n }\n \n@@ -409,11 +499,6 @@ thread_msg_handle_pipeline_enable(struct softnic_thread_data *t,\n \tuint32_t i;\n \n \t/* Request */\n-\tif (t->n_pipelines >= THREAD_PIPELINES_MAX) {\n-\t\trsp->status = -1;\n-\t\treturn rsp;\n-\t}\n-\n \tt->p[t->n_pipelines] = req->pipeline_enable.p;\n \n \tp->p = req->pipeline_enable.p;\n",
    "prefixes": []
}