get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 53074,
    "url": "http://patches.dpdk.org/api/patches/53074/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/425d28112308bc9a026d2de0b2844f1487d1d6e1.1556195690.git.anatoly.burakov@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": "<425d28112308bc9a026d2de0b2844f1487d1d6e1.1556195690.git.anatoly.burakov@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/425d28112308bc9a026d2de0b2844f1487d1d6e1.1556195690.git.anatoly.burakov@intel.com",
    "date": "2019-04-25T12:45:15",
    "name": "[19.08,2/6] ipc: handle unsupported ipc in action register",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "8c0c9cc01590718cbe81f6e447651534ad3fb683",
    "submitter": {
        "id": 4,
        "url": "http://patches.dpdk.org/api/people/4/?format=api",
        "name": "Anatoly Burakov",
        "email": "anatoly.burakov@intel.com"
    },
    "delegate": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/425d28112308bc9a026d2de0b2844f1487d1d6e1.1556195690.git.anatoly.burakov@intel.com/mbox/",
    "series": [
        {
            "id": 4465,
            "url": "http://patches.dpdk.org/api/series/4465/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=4465",
            "date": "2019-04-25T12:45:14",
            "name": "[19.08,1/6] ipc: handle unsupported ipc in init",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/4465/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/53074/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/53074/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 EEE9E1B597;\n\tThu, 25 Apr 2019 14:45:26 +0200 (CEST)",
            "from mga06.intel.com (mga06.intel.com [134.134.136.31])\n\tby dpdk.org (Postfix) with ESMTP id 9F4881B581\n\tfor <dev@dpdk.org>; Thu, 25 Apr 2019 14:45:23 +0200 (CEST)",
            "from orsmga002.jf.intel.com ([10.7.209.21])\n\tby orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t25 Apr 2019 05:45:23 -0700",
            "from silpixa00399498.ir.intel.com (HELO\n\tsilpixa00399498.ger.corp.intel.com) ([10.237.223.125])\n\tby orsmga002.jf.intel.com with ESMTP; 25 Apr 2019 05:45:21 -0700"
        ],
        "X-Amp-Result": "SKIPPED(no attachment in message)",
        "X-Amp-File-Uploaded": "False",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.60,393,1549958400\"; d=\"scan'208\";a=\"153666966\"",
        "From": "Anatoly Burakov <anatoly.burakov@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "Matan Azrad <matan@mellanox.com>, Shahaf Shuler <shahafs@mellanox.com>, \n\tYongseok Koh <yskoh@mellanox.com>, Keith Wiles <keith.wiles@intel.com>, \n\tReshma Pattan <reshma.pattan@intel.com>, herakliusz.lipiec@intel.com",
        "Date": "Thu, 25 Apr 2019 13:45:15 +0100",
        "Message-Id": "<425d28112308bc9a026d2de0b2844f1487d1d6e1.1556195690.git.anatoly.burakov@intel.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": [
            "<b0b218f0265ee9814de64f284d0d2d896ab01fa1.1556195690.git.anatoly.burakov@intel.com>",
            "<b0b218f0265ee9814de64f284d0d2d896ab01fa1.1556195690.git.anatoly.burakov@intel.com>"
        ],
        "References": [
            "<b0b218f0265ee9814de64f284d0d2d896ab01fa1.1556195690.git.anatoly.burakov@intel.com>",
            "<b0b218f0265ee9814de64f284d0d2d896ab01fa1.1556195690.git.anatoly.burakov@intel.com>"
        ],
        "Subject": "[dpdk-dev] [PATCH 19.08 2/6] ipc: handle unsupported ipc in action\n\tregister",
        "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": "Currently, IPC API will silently ignore unsupported IPC.\nFix the API call and its callers to explicitly handle\nunsupported IPC cases.\n\nFor primary processes, it is OK to not have IPC because\nthere may not be any secondary processes in the first place,\nand there are valid use cases that disable IPC support, so\nall primary process usages are fixed up to ignore IPC\nfailures.\n\nFor secondary processes, IPC will be crucial, so leave all\nof the error handling as is.\n\nSigned-off-by: Anatoly Burakov <anatoly.burakov@intel.com>\n---\n drivers/bus/vdev/vdev.c                     |  5 +++++\n drivers/net/mlx4/mlx4.c                     | 12 +++++++++---\n drivers/net/mlx4/mlx4.h                     |  4 ++--\n drivers/net/mlx4/mlx4_mp.c                  | 15 +++++++++++----\n drivers/net/mlx5/mlx5.c                     | 12 +++++++++---\n drivers/net/mlx5/mlx5.h                     |  4 ++--\n drivers/net/mlx5/mlx5_mp.c                  | 15 +++++++++++----\n drivers/net/tap/rte_eth_tap.c               |  2 +-\n lib/librte_eal/common/eal_common_proc.c     |  6 ++++++\n lib/librte_eal/common/hotplug_mp.c          |  4 +++-\n lib/librte_eal/common/include/rte_eal.h     |  3 +++\n lib/librte_eal/common/malloc_mp.c           |  4 +++-\n lib/librte_eal/linux/eal/eal_vfio_mp_sync.c |  8 ++++++--\n lib/librte_pdump/rte_pdump.c                |  5 ++++-\n 14 files changed, 75 insertions(+), 24 deletions(-)",
    "diff": "diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c\nindex 04f76a63f..a89ea2353 100644\n--- a/drivers/bus/vdev/vdev.c\n+++ b/drivers/bus/vdev/vdev.c\n@@ -409,6 +409,10 @@ vdev_scan(void)\n \n \tif (rte_mp_action_register(VDEV_MP_KEY, vdev_action) < 0 &&\n \t    rte_errno != EEXIST) {\n+\t\t/* for primary, unsupported IPC is not an error */\n+\t\tif (rte_eal_process_type() == RTE_PROC_PRIMARY &&\n+\t\t\t\trte_errno == ENOTSUP)\n+\t\t\tgoto scan;\n \t\tVDEV_LOG(ERR, \"Failed to add vdev mp action\");\n \t\treturn -1;\n \t}\n@@ -436,6 +440,7 @@ vdev_scan(void)\n \t\t/* Fall through to allow private vdevs in secondary process */\n \t}\n \n+scan:\n \t/* call custom scan callbacks if any */\n \trte_spinlock_lock(&vdev_custom_scan_lock);\n \tTAILQ_FOREACH(custom_scan, &vdev_custom_scans, next) {\ndiff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c\nindex 17dfcd5a3..3cfa07de3 100644\n--- a/drivers/net/mlx4/mlx4.c\n+++ b/drivers/net/mlx4/mlx4.c\n@@ -693,6 +693,7 @@ mlx4_init_once(void)\n {\n \tstruct mlx4_shared_data *sd;\n \tstruct mlx4_local_data *ld = &mlx4_local_data;\n+\tint ret = 0;\n \n \tif (mlx4_init_shared_data())\n \t\treturn -rte_errno;\n@@ -707,21 +708,26 @@ mlx4_init_once(void)\n \t\trte_rwlock_init(&sd->mem_event_rwlock);\n \t\trte_mem_event_callback_register(\"MLX4_MEM_EVENT_CB\",\n \t\t\t\t\t\tmlx4_mr_mem_event_cb, NULL);\n-\t\tmlx4_mp_init_primary();\n+\t\tret = mlx4_mp_init_primary();\n+\t\tif (ret)\n+\t\t\tgoto out;\n \t\tsd->init_done = true;\n \t\tbreak;\n \tcase RTE_PROC_SECONDARY:\n \t\tif (ld->init_done)\n \t\t\tbreak;\n-\t\tmlx4_mp_init_secondary();\n+\t\tret = mlx4_mp_init_secondary();\n+\t\tif (ret)\n+\t\t\tgoto out;\n \t\t++sd->secondary_cnt;\n \t\tld->init_done = true;\n \t\tbreak;\n \tdefault:\n \t\tbreak;\n \t}\n+out:\n \trte_spinlock_unlock(&sd->lock);\n-\treturn 0;\n+\treturn ret;\n }\n \n /**\ndiff --git a/drivers/net/mlx4/mlx4.h b/drivers/net/mlx4/mlx4.h\nindex 6224b3be1..d0769bbc9 100644\n--- a/drivers/net/mlx4/mlx4.h\n+++ b/drivers/net/mlx4/mlx4.h\n@@ -239,9 +239,9 @@ void mlx4_mp_req_start_rxtx(struct rte_eth_dev *dev);\n void mlx4_mp_req_stop_rxtx(struct rte_eth_dev *dev);\n int mlx4_mp_req_mr_create(struct rte_eth_dev *dev, uintptr_t addr);\n int mlx4_mp_req_verbs_cmd_fd(struct rte_eth_dev *dev);\n-void mlx4_mp_init_primary(void);\n+int mlx4_mp_init_primary(void);\n void mlx4_mp_uninit_primary(void);\n-void mlx4_mp_init_secondary(void);\n+int mlx4_mp_init_secondary(void);\n void mlx4_mp_uninit_secondary(void);\n \n #endif /* RTE_PMD_MLX4_H_ */\ndiff --git a/drivers/net/mlx4/mlx4_mp.c b/drivers/net/mlx4/mlx4_mp.c\nindex 183622453..ebc57a99e 100644\n--- a/drivers/net/mlx4/mlx4_mp.c\n+++ b/drivers/net/mlx4/mlx4_mp.c\n@@ -316,11 +316,18 @@ mlx4_mp_req_verbs_cmd_fd(struct rte_eth_dev *dev)\n /**\n  * Initialize by primary process.\n  */\n-void\n+int\n mlx4_mp_init_primary(void)\n {\n+\tint ret;\n+\n \tassert(rte_eal_process_type() == RTE_PROC_PRIMARY);\n-\trte_mp_action_register(MLX4_MP_NAME, mp_primary_handle);\n+\n+\t/* primary is allowed to not support IPC */\n+\tret = rte_mp_action_register(MLX4_MP_NAME, mp_primary_handle);\n+\tif (ret && rte_errno != ENOTSUP)\n+\t\treturn -1;\n+\treturn 0;\n }\n \n /**\n@@ -336,11 +343,11 @@ mlx4_mp_uninit_primary(void)\n /**\n  * Initialize by secondary process.\n  */\n-void\n+int\n mlx4_mp_init_secondary(void)\n {\n \tassert(rte_eal_process_type() == RTE_PROC_SECONDARY);\n-\trte_mp_action_register(MLX4_MP_NAME, mp_secondary_handle);\n+\treturn rte_mp_action_register(MLX4_MP_NAME, mp_secondary_handle);\n }\n \n /**\ndiff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c\nindex 46ca08a4d..271d79d8f 100644\n--- a/drivers/net/mlx5/mlx5.c\n+++ b/drivers/net/mlx5/mlx5.c\n@@ -990,6 +990,7 @@ mlx5_init_once(void)\n {\n \tstruct mlx5_shared_data *sd;\n \tstruct mlx5_local_data *ld = &mlx5_local_data;\n+\tint ret = 0;\n \n \tif (mlx5_init_shared_data())\n \t\treturn -rte_errno;\n@@ -1004,21 +1005,26 @@ mlx5_init_once(void)\n \t\trte_rwlock_init(&sd->mem_event_rwlock);\n \t\trte_mem_event_callback_register(\"MLX5_MEM_EVENT_CB\",\n \t\t\t\t\t\tmlx5_mr_mem_event_cb, NULL);\n-\t\tmlx5_mp_init_primary();\n+\t\tret = mlx5_mp_init_primary();\n+\t\tif (ret)\n+\t\t\tgoto out;\n \t\tsd->init_done = true;\n \t\tbreak;\n \tcase RTE_PROC_SECONDARY:\n \t\tif (ld->init_done)\n \t\t\tbreak;\n-\t\tmlx5_mp_init_secondary();\n+\t\tret = mlx5_mp_init_secondary();\n+\t\tif (ret)\n+\t\t\tgoto out;\n \t\t++sd->secondary_cnt;\n \t\tld->init_done = true;\n \t\tbreak;\n \tdefault:\n \t\tbreak;\n \t}\n+out:\n \trte_spinlock_unlock(&sd->lock);\n-\treturn 0;\n+\treturn ret;\n }\n \n /**\ndiff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h\nindex 0a6d7f1d5..0b3418b4a 100644\n--- a/drivers/net/mlx5/mlx5.h\n+++ b/drivers/net/mlx5/mlx5.h\n@@ -540,9 +540,9 @@ void mlx5_mp_req_start_rxtx(struct rte_eth_dev *dev);\n void mlx5_mp_req_stop_rxtx(struct rte_eth_dev *dev);\n int mlx5_mp_req_mr_create(struct rte_eth_dev *dev, uintptr_t addr);\n int mlx5_mp_req_verbs_cmd_fd(struct rte_eth_dev *dev);\n-void mlx5_mp_init_primary(void);\n+int mlx5_mp_init_primary(void);\n void mlx5_mp_uninit_primary(void);\n-void mlx5_mp_init_secondary(void);\n+int mlx5_mp_init_secondary(void);\n void mlx5_mp_uninit_secondary(void);\n \n /* mlx5_nl.c */\ndiff --git a/drivers/net/mlx5/mlx5_mp.c b/drivers/net/mlx5/mlx5_mp.c\nindex cea74adb6..dc99231fe 100644\n--- a/drivers/net/mlx5/mlx5_mp.c\n+++ b/drivers/net/mlx5/mlx5_mp.c\n@@ -320,11 +320,18 @@ mlx5_mp_req_verbs_cmd_fd(struct rte_eth_dev *dev)\n /**\n  * Initialize by primary process.\n  */\n-void\n+int\n mlx5_mp_init_primary(void)\n {\n+\tint ret;\n+\n \tassert(rte_eal_process_type() == RTE_PROC_PRIMARY);\n-\trte_mp_action_register(MLX5_MP_NAME, mp_primary_handle);\n+\n+\t/* primary is allowed to not support IPC */\n+\tret = rte_mp_action_register(MLX5_MP_NAME, mp_primary_handle);\n+\tif (ret && rte_errno != ENOTSUP)\n+\t\treturn -1;\n+\treturn 0;\n }\n \n /**\n@@ -340,11 +347,11 @@ mlx5_mp_uninit_primary(void)\n /**\n  * Initialize by secondary process.\n  */\n-void\n+int\n mlx5_mp_init_secondary(void)\n {\n \tassert(rte_eal_process_type() == RTE_PROC_SECONDARY);\n-\trte_mp_action_register(MLX5_MP_NAME, mp_secondary_handle);\n+\treturn rte_mp_action_register(MLX5_MP_NAME, mp_secondary_handle);\n }\n \n /**\ndiff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c\nindex 7f74b5dc9..3e82f5138 100644\n--- a/drivers/net/tap/rte_eth_tap.c\n+++ b/drivers/net/tap/rte_eth_tap.c\n@@ -2273,7 +2273,7 @@ rte_pmd_tap_probe(struct rte_vdev_device *dev)\n \t/* Register IPC feed callback */\n \tif (!tap_devices_count) {\n \t\tret = rte_mp_action_register(TAP_MP_KEY, tap_mp_sync_queues);\n-\t\tif (ret < 0) {\n+\t\tif (ret < 0 && rte_errno != ENOTSUP) {\n \t\t\tTAP_LOG(ERR, \"tap: Failed to register IPC callback: %s\",\n \t\t\t\tstrerror(rte_errno));\n \t\t\tgoto leave;\ndiff --git a/lib/librte_eal/common/eal_common_proc.c b/lib/librte_eal/common/eal_common_proc.c\nindex a4581e3b4..a40aa2c1b 100644\n--- a/lib/librte_eal/common/eal_common_proc.c\n+++ b/lib/librte_eal/common/eal_common_proc.c\n@@ -205,6 +205,12 @@ rte_mp_action_register(const char *name, rte_mp_t action)\n \tif (validate_action_name(name))\n \t\treturn -1;\n \n+\tif (internal_config.no_shconf) {\n+\t\tRTE_LOG(DEBUG, EAL, \"No shared files mode enabled, IPC is disabled\\n\");\n+\t\trte_errno = ENOTSUP;\n+\t\treturn -1;\n+\t}\n+\n \tentry = malloc(sizeof(struct action_entry));\n \tif (entry == NULL) {\n \t\trte_errno = ENOMEM;\ndiff --git a/lib/librte_eal/common/hotplug_mp.c b/lib/librte_eal/common/hotplug_mp.c\nindex 4052a5c7f..60cd1402d 100644\n--- a/lib/librte_eal/common/hotplug_mp.c\n+++ b/lib/librte_eal/common/hotplug_mp.c\n@@ -4,6 +4,7 @@\n #include <string.h>\n \n #include <rte_eal.h>\n+#include <rte_errno.h>\n #include <rte_alarm.h>\n #include <rte_string_fns.h>\n #include <rte_devargs.h>\n@@ -440,7 +441,8 @@ int rte_mp_dev_hotplug_init(void)\n \tif (rte_eal_process_type() == RTE_PROC_PRIMARY) {\n \t\tret = rte_mp_action_register(EAL_DEV_MP_ACTION_REQUEST,\n \t\t\t\t\thandle_secondary_request);\n-\t\tif (ret != 0) {\n+\t\t/* primary is allowed to not support IPC */\n+\t\tif (ret != 0 && rte_errno != ENOTSUP) {\n \t\t\tRTE_LOG(ERR, EAL, \"Couldn't register '%s' action\\n\",\n \t\t\t\tEAL_DEV_MP_ACTION_REQUEST);\n \t\t\treturn ret;\ndiff --git a/lib/librte_eal/common/include/rte_eal.h b/lib/librte_eal/common/include/rte_eal.h\nindex f9288666e..7f807aa8e 100644\n--- a/lib/librte_eal/common/include/rte_eal.h\n+++ b/lib/librte_eal/common/include/rte_eal.h\n@@ -248,6 +248,9 @@ typedef int (*rte_mp_async_reply_t)(const struct rte_mp_msg *request,\n  * to response the messages from the corresponding component in its primary\n  * process or secondary processes.\n  *\n+ * @note IPC may be unsupported in certain circumstances, so caller should check\n+ *    for ENOTSUP error.\n+ *\n  * @param name\n  *   The name argument plays as the nonredundant key to find the action.\n  *\ndiff --git a/lib/librte_eal/common/malloc_mp.c b/lib/librte_eal/common/malloc_mp.c\nindex b470565e0..1374eabc2 100644\n--- a/lib/librte_eal/common/malloc_mp.c\n+++ b/lib/librte_eal/common/malloc_mp.c\n@@ -722,7 +722,9 @@ int\n register_mp_requests(void)\n {\n \tif (rte_eal_process_type() == RTE_PROC_PRIMARY) {\n-\t\tif (rte_mp_action_register(MP_ACTION_REQUEST, handle_request)) {\n+\t\t/* it's OK for primary to not support IPC */\n+\t\tif (rte_mp_action_register(MP_ACTION_REQUEST, handle_request) &&\n+\t\t\t\trte_errno != ENOTSUP) {\n \t\t\tRTE_LOG(ERR, EAL, \"Couldn't register '%s' action\\n\",\n \t\t\t\tMP_ACTION_REQUEST);\n \t\t\treturn -1;\ndiff --git a/lib/librte_eal/linux/eal/eal_vfio_mp_sync.c b/lib/librte_eal/linux/eal/eal_vfio_mp_sync.c\nindex 2a47f29d5..5f2a5fc1d 100644\n--- a/lib/librte_eal/linux/eal/eal_vfio_mp_sync.c\n+++ b/lib/librte_eal/linux/eal/eal_vfio_mp_sync.c\n@@ -6,6 +6,7 @@\n #include <string.h>\n \n #include <rte_compat.h>\n+#include <rte_errno.h>\n #include <rte_log.h>\n #include <rte_vfio.h>\n #include <rte_eal.h>\n@@ -110,8 +111,11 @@ vfio_mp_primary(const struct rte_mp_msg *msg, const void *peer)\n int\n vfio_mp_sync_setup(void)\n {\n-\tif (rte_eal_process_type() == RTE_PROC_PRIMARY)\n-\t\treturn rte_mp_action_register(EAL_VFIO_MP, vfio_mp_primary);\n+\tif (rte_eal_process_type() == RTE_PROC_PRIMARY) {\n+\t\tint ret = rte_mp_action_register(EAL_VFIO_MP, vfio_mp_primary);\n+\t\tif (ret && rte_errno != ENOTSUP)\n+\t\t\treturn -1;\n+\t}\n \n \treturn 0;\n }\ndiff --git a/lib/librte_pdump/rte_pdump.c b/lib/librte_pdump/rte_pdump.c\nindex 14744b9ff..cd24dd010 100644\n--- a/lib/librte_pdump/rte_pdump.c\n+++ b/lib/librte_pdump/rte_pdump.c\n@@ -408,7 +408,10 @@ pdump_server(const struct rte_mp_msg *mp_msg, const void *peer)\n int\n rte_pdump_init(void)\n {\n-\treturn rte_mp_action_register(PDUMP_MP, pdump_server);\n+\tint ret = rte_mp_action_register(PDUMP_MP, pdump_server);\n+\tif (ret && rte_errno != ENOTSUP)\n+\t\treturn -1;\n+\treturn 0;\n }\n \n int\n",
    "prefixes": [
        "19.08",
        "2/6"
    ]
}