get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 27696,
    "url": "https://patches.dpdk.org/api/patches/27696/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1503320296-51122-14-git-send-email-harry.van.haaren@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": "<1503320296-51122-14-git-send-email-harry.van.haaren@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1503320296-51122-14-git-send-email-harry.van.haaren@intel.com",
    "date": "2017-08-21T12:58:14",
    "name": "[dpdk-dev,v2,13/15] service: add component runstate",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "b49a63e2e3359e321a68585adda84d3abb900e60",
    "submitter": {
        "id": 317,
        "url": "https://patches.dpdk.org/api/people/317/?format=api",
        "name": "Van Haaren, Harry",
        "email": "harry.van.haaren@intel.com"
    },
    "delegate": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1503320296-51122-14-git-send-email-harry.van.haaren@intel.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/27696/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/27696/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 801E590FA;\n\tMon, 21 Aug 2017 14:58:48 +0200 (CEST)",
            "from mga05.intel.com (mga05.intel.com [192.55.52.43])\n\tby dpdk.org (Postfix) with ESMTP id 80BD07D7F\n\tfor <dev@dpdk.org>; Mon, 21 Aug 2017 14:58:40 +0200 (CEST)",
            "from fmsmga002.fm.intel.com ([10.253.24.26])\n\tby fmsmga105.fm.intel.com with ESMTP; 21 Aug 2017 05:58:40 -0700",
            "from silpixa00398672.ir.intel.com ([10.237.223.128])\n\tby fmsmga002.fm.intel.com with ESMTP; 21 Aug 2017 05:58:39 -0700"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos; i=\"5.41,409,1498546800\"; d=\"scan'208\";\n\ta=\"1208383374\"",
        "From": "Harry van Haaren <harry.van.haaren@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "Harry van Haaren <harry.van.haaren@intel.com>",
        "Date": "Mon, 21 Aug 2017 13:58:14 +0100",
        "Message-Id": "<1503320296-51122-14-git-send-email-harry.van.haaren@intel.com>",
        "X-Mailer": "git-send-email 2.7.4",
        "In-Reply-To": "<1503320296-51122-1-git-send-email-harry.van.haaren@intel.com>",
        "References": "<1502800360-15782-1-git-send-email-harry.van.haaren@intel.com>\n\t<1503320296-51122-1-git-send-email-harry.van.haaren@intel.com>",
        "Subject": "[dpdk-dev] [PATCH v2 13/15] service: add component runstate",
        "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 flag that the component (or \"backend\")\ncan use to indicate readyness. The service function callback\nwill not be called until the component sets itself as ready.\n\nThe use-case behind adding this feature is eg: a service that\nrequires configuration before it can start. Any service that\nemulates an ethdev will have rte_eth_dev_configure() called,\nand only after that the service will know how many queues/etc\nto allocate. Once that configuration is complete, the service\nmarks itself as ready using rte_service_component_runstate_set().\n\nThis feature request results from prototyping services, and\nrequiring a flag in each service to note \"internal\" readyness.\nInstead that logic is now lifted to the service library.\n\nThe unit tests have been updated to test the component runstate.\n\nSigned-off-by: Harry van Haaren <harry.van.haaren@intel.com>\n---\n lib/librte_eal/bsdapp/eal/rte_eal_version.map      |  1 +\n .../common/include/rte_service_component.h         | 17 +++++++++++\n lib/librte_eal/common/rte_service.c                | 34 +++++++++++++++++-----\n lib/librte_eal/linuxapp/eal/rte_eal_version.map    |  1 +\n test/test/test_service_cores.c                     | 32 +++++++++++++++-----\n 5 files changed, 70 insertions(+), 15 deletions(-)",
    "diff": "diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map\nindex 4b2c36b..05a3de1 100644\n--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map\n+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map\n@@ -214,6 +214,7 @@ EXPERIMENTAL {\n \trte_eal_hotplug_remove;\n \trte_service_component_register;\n \trte_service_component_unregister;\n+\trte_service_component_runstate_set;\n \trte_service_dump;\n \trte_service_get_by_id;\n \trte_service_get_by_name;\ndiff --git a/lib/librte_eal/common/include/rte_service_component.h b/lib/librte_eal/common/include/rte_service_component.h\nindex af632c6..5e4573b 100644\n--- a/lib/librte_eal/common/include/rte_service_component.h\n+++ b/lib/librte_eal/common/include/rte_service_component.h\n@@ -135,6 +135,23 @@ int32_t rte_service_start_with_defaults(void);\n  * @warning\n  * @b EXPERIMENTAL: this API may change without prior notice\n  *\n+ * Set the backend runstate of a component.\n+ *\n+ * This function allows services to be registered at startup, but not yet\n+ * enabled to run by default. When the service has been configured (via the\n+ * usual method; eg rte_eventdev_configure, the service can mark itself as\n+ * ready to run. The differentiation between backend runstate and\n+ * service_runstate is that the backend runstate is set by the service\n+ * component while the service runstate is reserved for application usage.\n+ *\n+ * @retval 0 Success\n+ */\n+int32_t rte_service_component_runstate_set(uint32_t id, uint32_t runstate);\n+\n+/**\n+ * @warning\n+ * @b EXPERIMENTAL: this API may change without prior notice\n+ *\n  * Initialize the service library.\n  *\n  * In order to use the service library, it must be initialized. EAL initializes\ndiff --git a/lib/librte_eal/common/rte_service.c b/lib/librte_eal/common/rte_service.c\nindex 58b53b1..e7ed597 100644\n--- a/lib/librte_eal/common/rte_service.c\n+++ b/lib/librte_eal/common/rte_service.c\n@@ -71,7 +71,8 @@ struct rte_service_spec_impl {\n \trte_atomic32_t execute_lock;\n \n \t/* API set/get-able variables */\n-\tint32_t runstate;\n+\tint8_t app_runstate;\n+\tint8_t comp_runstate;\n \tuint8_t internal_flags;\n \n \t/* per service statistics */\n@@ -273,15 +274,30 @@ rte_service_component_unregister(uint32_t id)\n }\n \n int32_t\n+rte_service_component_runstate_set(uint32_t id, uint32_t runstate)\n+{\n+\tstruct rte_service_spec_impl *s;\n+\tSERVICE_VALID_GET_OR_ERR_RET(id, s, -EINVAL);\n+\n+\tif (runstate)\n+\t\ts->comp_runstate = RUNSTATE_RUNNING;\n+\telse\n+\t\ts->comp_runstate = RUNSTATE_STOPPED;\n+\n+\trte_smp_wmb();\n+\treturn 0;\n+}\n+\n+int32_t\n rte_service_runstate_set(uint32_t id, uint32_t runstate)\n {\n \tstruct rte_service_spec_impl *s;\n \tSERVICE_VALID_GET_OR_ERR_RET(id, s, -EINVAL);\n \n \tif (runstate)\n-\t\ts->runstate = RUNSTATE_RUNNING;\n+\t\ts->app_runstate = RUNSTATE_RUNNING;\n \telse\n-\t\ts->runstate = RUNSTATE_STOPPED;\n+\t\ts->app_runstate = RUNSTATE_STOPPED;\n \n \trte_smp_wmb();\n \treturn 0;\n@@ -292,8 +308,10 @@ rte_service_runstate_get(uint32_t id)\n {\n \tstruct rte_service_spec_impl *s;\n \tSERVICE_VALID_GET_OR_ERR_RET(id, s, -EINVAL);\n-\n-\treturn (s->runstate == RUNSTATE_RUNNING) && (s->num_mapped_cores > 0);\n+\trte_smp_rmb();\n+\treturn (s->app_runstate == RUNSTATE_RUNNING) &&\n+\t\t(s->comp_runstate == RUNSTATE_RUNNING) &&\n+\t\t(s->num_mapped_cores > 0);\n }\n \n static inline void\n@@ -328,7 +346,8 @@ rte_service_runner_func(void *arg)\n \t\t\tif (!service_valid(i))\n \t\t\t\tcontinue;\n \t\t\tstruct rte_service_spec_impl *s = &rte_services[i];\n-\t\t\tif (s->runstate != RUNSTATE_RUNNING ||\n+\t\t\tif (s->comp_runstate != RUNSTATE_RUNNING ||\n+\t\t\t\t\ts->app_runstate != RUNSTATE_RUNNING ||\n \t\t\t\t\t!(service_mask & (UINT64_C(1) << i)))\n \t\t\t\tcontinue;\n \n@@ -596,8 +615,7 @@ rte_service_lcore_stop(uint32_t lcore)\n \tfor (i = 0; i < RTE_SERVICE_NUM_MAX; i++) {\n \t\tint32_t enabled =\n \t\t\tlcore_states[i].service_mask & (UINT64_C(1) << i);\n-\t\tint32_t service_running = rte_services[i].runstate !=\n-\t\t\t\t\t\tRUNSTATE_STOPPED;\n+\t\tint32_t service_running = rte_service_runstate_get(i);\n \t\tint32_t only_core = rte_services[i].num_mapped_cores == 1;\n \n \t\t/* if the core is mapped, and the service is running, and this\ndiff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map\nindex f7a7352..0e1d09b 100644\n--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map\n+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map\n@@ -219,6 +219,7 @@ EXPERIMENTAL {\n \trte_eal_hotplug_remove;\n \trte_service_component_register;\n \trte_service_component_unregister;\n+\trte_service_component_runstate_set;\n \trte_service_dump;\n \trte_service_get_by_id;\n \trte_service_get_by_name;\ndiff --git a/test/test/test_service_cores.c b/test/test/test_service_cores.c\nindex 5ae7b20..ddea7f0 100644\n--- a/test/test/test_service_cores.c\n+++ b/test/test/test_service_cores.c\n@@ -166,9 +166,12 @@ dummy_register(void)\n \t\t\t\"Invalid name\");\n \tsnprintf(service.name, sizeof(service.name), DUMMY_SERVICE_NAME);\n \n-\tTEST_ASSERT_EQUAL(0, rte_service_component_register(&service, NULL),\n+\tuint32_t id;\n+\tTEST_ASSERT_EQUAL(0, rte_service_component_register(&service, &id),\n \t\t\t\"Failed to register valid service\");\n \n+\trte_service_component_runstate_set(id, 1);\n+\n \treturn TEST_SUCCESS;\n }\n \n@@ -470,13 +473,11 @@ service_threaded_test(int mt_safe)\n \tif (mt_safe) {\n \t\tservice.callback = dummy_mt_safe_cb;\n \t\tservice.capabilities |= RTE_SERVICE_CAP_MT_SAFE;\n-\t} else {\n-\t\t/* initialize to pass, see callback comment for details */\n-\t\ttest_params[1] = 1;\n+\t} else\n \t\tservice.callback = dummy_mt_unsafe_cb;\n-\t}\n \n-\tTEST_ASSERT_EQUAL(0, rte_service_component_register(&service, NULL),\n+\tuint32_t id;\n+\tTEST_ASSERT_EQUAL(0, rte_service_component_register(&service, &id),\n \t\t\t\"Register of MT SAFE service failed\");\n \n \tconst uint32_t sid = 0;\n@@ -494,9 +495,26 @@ service_threaded_test(int mt_safe)\n \trte_service_lcore_stop(slcore_1);\n \trte_service_lcore_stop(slcore_2);\n \n+\tTEST_ASSERT_EQUAL(0, test_params[1],\n+\t\t\t\"Service run with component runstate = 0\");\n+\n+\t/* enable backend runstate: the service should run after this */\n+\trte_service_component_runstate_set(id, 1);\n+\n+\t/* initialize to pass, see callback comment for details */\n+\tif (!mt_safe)\n+\t\ttest_params[1] = 1;\n+\n+\trte_service_lcore_start(slcore_1);\n+\trte_service_lcore_start(slcore_2);\n+\n+\t/* wait for the worker threads to run */\n+\trte_delay_ms(500);\n+\trte_service_lcore_stop(slcore_1);\n+\trte_service_lcore_stop(slcore_2);\n+\n \tTEST_ASSERT_EQUAL(1, test_params[1],\n \t\t\t\"MT Safe service not run by two cores concurrently\");\n-\n \tTEST_ASSERT_EQUAL(0, rte_service_runstate_set(sid, 0),\n \t\t\t\"Failed to stop MT Safe service\");\n \n",
    "prefixes": [
        "dpdk-dev",
        "v2",
        "13/15"
    ]
}