get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 62714,
    "url": "http://patches.dpdk.org/api/patches/62714/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1573184965-49691-5-git-send-email-suanmingm@mellanox.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": "<1573184965-49691-5-git-send-email-suanmingm@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1573184965-49691-5-git-send-email-suanmingm@mellanox.com",
    "date": "2019-11-08T03:49:10",
    "name": "[v2,04/19] net/mlx5: support meter profile operations",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "9d604386677664a8ea79eeba7b54c55d018657ff",
    "submitter": {
        "id": 1358,
        "url": "http://patches.dpdk.org/api/people/1358/?format=api",
        "name": "Suanming Mou",
        "email": "suanmingm@mellanox.com"
    },
    "delegate": {
        "id": 3268,
        "url": "http://patches.dpdk.org/api/users/3268/?format=api",
        "username": "rasland",
        "first_name": "Raslan",
        "last_name": "Darawsheh",
        "email": "rasland@nvidia.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1573184965-49691-5-git-send-email-suanmingm@mellanox.com/mbox/",
    "series": [
        {
            "id": 7343,
            "url": "http://patches.dpdk.org/api/series/7343/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=7343",
            "date": "2019-11-08T03:49:07",
            "name": "net/mlx5: support meter",
            "version": 2,
            "mbox": "http://patches.dpdk.org/series/7343/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/62714/comments/",
    "check": "fail",
    "checks": "http://patches.dpdk.org/api/patches/62714/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id BB873A04AB;\n\tFri,  8 Nov 2019 04:49:56 +0100 (CET)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 992C91BF85;\n\tFri,  8 Nov 2019 04:49:41 +0100 (CET)",
            "from git-send-mailer.rdmz.labs.mlnx (unknown [37.142.13.130])\n by dpdk.org (Postfix) with ESMTP id B37521BF52\n for <dev@dpdk.org>; Fri,  8 Nov 2019 04:49:32 +0100 (CET)"
        ],
        "From": "Suanming Mou <suanmingm@mellanox.com>",
        "To": "viacheslavo@mellanox.com,\n\tmatan@mellanox.com",
        "Cc": "orika@mellanox.com,\n\trasland@mellanox.com,\n\tdev@dpdk.org",
        "Date": "Fri,  8 Nov 2019 05:49:10 +0200",
        "Message-Id": "<1573184965-49691-5-git-send-email-suanmingm@mellanox.com>",
        "X-Mailer": "git-send-email 1.8.3.1",
        "In-Reply-To": "<1573184965-49691-1-git-send-email-suanmingm@mellanox.com>",
        "References": "<1573053090-179521-1-git-send-email-suanmingm@mellanox.com>\n <1573184965-49691-1-git-send-email-suanmingm@mellanox.com>",
        "Subject": "[dpdk-dev] [PATCH v2 04/19] net/mlx5: support meter profile\n\toperations",
        "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 <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 <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "This commit add the support of meter profile add and delete operations.\n\nNew internal functions in rte_mtr_ops callback:\n1. meter_profile_add()\n2. meter_profile_delete()\n\nOnly RTE_MTR_SRTCM_RFC2697 algorithm is supported and can be added. To\nadd other algorithm will report an error.\n\nSigned-off-by: Suanming Mou <suanmingm@mellanox.com>\n---\n drivers/net/mlx5/Makefile          |   1 +\n drivers/net/mlx5/mlx5.c            |   1 +\n drivers/net/mlx5/mlx5.h            |   4 +\n drivers/net/mlx5/mlx5_flow.h       |  29 +++++\n drivers/net/mlx5/mlx5_flow_meter.c | 245 ++++++++++++++++++++++++++++++++++++-\n 5 files changed, 278 insertions(+), 2 deletions(-)",
    "diff": "diff --git a/drivers/net/mlx5/Makefile b/drivers/net/mlx5/Makefile\nindex 0065e55..d01fa73 100644\n--- a/drivers/net/mlx5/Makefile\n+++ b/drivers/net/mlx5/Makefile\n@@ -64,6 +64,7 @@ LDLIBS += $(shell $(RTE_SDK)/buildtools/options-ibverbs-static.sh)\n else\n LDLIBS += -libverbs -lmlx5\n endif\n+LDLIBS += -lm\n LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring\n LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs\n LDLIBS += -lrte_bus_pci\ndiff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c\nindex 3b30169..3bebad3 100644\n--- a/drivers/net/mlx5/mlx5.c\n+++ b/drivers/net/mlx5/mlx5.c\n@@ -2403,6 +2403,7 @@ struct mlx5_flow_id_pool *\n \t\tmlx5_nl_mac_addr_sync(eth_dev);\n \tTAILQ_INIT(&priv->flows);\n \tTAILQ_INIT(&priv->ctrl_flows);\n+\tTAILQ_INIT(&priv->flow_meter_profiles);\n \t/* Hint libmlx5 to use PMD allocator for data plane resources */\n \tstruct mlx5dv_ctx_allocators alctr = {\n \t\t.alloc = &mlx5_alloc_verbs_buf,\ndiff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h\nindex f19ea23..dbeab2b 100644\n--- a/drivers/net/mlx5/mlx5.h\n+++ b/drivers/net/mlx5/mlx5.h\n@@ -684,6 +684,9 @@ struct mlx5_proc_priv {\n \t/* Table of UAR registers for each process. */\n };\n \n+/* MTR profile list. */\n+TAILQ_HEAD(mlx5_mtr_profiles, mlx5_flow_meter_profile);\n+\n #define MLX5_PROC_PRIV(port_id) \\\n \t((struct mlx5_proc_priv *)rte_eth_devices[port_id].process_private)\n \n@@ -754,6 +757,7 @@ struct mlx5_priv {\n \t/* Hash table of Rx metadata register copy table. */\n \tuint8_t mtr_sfx_reg; /* Meter prefix-suffix flow match REG_C. */\n \tuint8_t mtr_color_reg; /* Meter color match REG_C. */\n+\tstruct mlx5_mtr_profiles flow_meter_profiles; /* MTR profile list. */\n #ifndef RTE_ARCH_64\n \trte_spinlock_t uar_lock_cq; /* CQs share a common distinct UAR */\n \trte_spinlock_t uar_lock[MLX5_UAR_PAGE_NUM_MAX];\ndiff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h\nindex ac1675456..d755d11 100644\n--- a/drivers/net/mlx5/mlx5_flow.h\n+++ b/drivers/net/mlx5/mlx5_flow.h\n@@ -23,6 +23,7 @@\n \n #include <rte_atomic.h>\n #include <rte_alarm.h>\n+#include <rte_mtr.h>\n \n #include \"mlx5.h\"\n #include \"mlx5_prm.h\"\n@@ -522,6 +523,34 @@ struct mlx5_flow {\n \tbool external; /**< true if the flow is created external to PMD. */\n };\n \n+#define MLX5_MAN_WIDTH 8\n+\n+/* RFC2697 parameter structure. */\n+struct mlx5_flow_meter_srtcm_rfc2697_prm {\n+\t/* green_saturation_value = cbs_mantissa * 2^cbs_exponent */\n+\tuint32_t cbs_exponent:5;\n+\tuint32_t cbs_mantissa:8;\n+\t/* cir = 8G * cir_mantissa * 1/(2^cir_exponent) Bytes/Sec */\n+\tuint32_t cir_exponent:5;\n+\tuint32_t cir_mantissa:8;\n+\t/* yellow _saturation_value = ebs_mantissa * 2^ebs_exponent */\n+\tuint32_t ebs_exponent:5;\n+\tuint32_t ebs_mantissa:8;\n+};\n+\n+/* Flow meter profile structure. */\n+struct mlx5_flow_meter_profile {\n+\tTAILQ_ENTRY(mlx5_flow_meter_profile) next;\n+\t/**< Pointer to the next flow meter structure. */\n+\tuint32_t meter_profile_id; /**< Profile id. */\n+\tstruct rte_mtr_meter_profile profile; /**< Profile detail. */\n+\tunion {\n+\t\tstruct mlx5_flow_meter_srtcm_rfc2697_prm srtcm_prm;\n+\t\t/**< srtcm_rfc2697 struct. */\n+\t};\n+\tuint32_t ref_cnt; /**< Use count. */\n+};\n+\n /* Flow structure. */\n struct rte_flow {\n \tTAILQ_ENTRY(rte_flow) next; /**< Pointer to the next flow structure. */\ndiff --git a/drivers/net/mlx5/mlx5_flow_meter.c b/drivers/net/mlx5/mlx5_flow_meter.c\nindex 9103b6d..b11962f 100644\n--- a/drivers/net/mlx5/mlx5_flow_meter.c\n+++ b/drivers/net/mlx5/mlx5_flow_meter.c\n@@ -4,6 +4,7 @@\n  */\n #include <math.h>\n \n+#include <rte_malloc.h>\n #include <rte_mtr.h>\n #include <rte_mtr_driver.h>\n \n@@ -11,6 +12,150 @@\n #include \"mlx5_flow.h\"\n \n /**\n+ * Find meter profile by id.\n+ *\n+ * @param priv\n+ *   Pointer to mlx5_priv.\n+ * @param meter_profile_id\n+ *   Meter profile id.\n+ *\n+ * @return\n+ *   Pointer to the profile found on success, NULL otherwise.\n+ */\n+static struct mlx5_flow_meter_profile *\n+mlx5_flow_meter_profile_find(struct mlx5_priv *priv, uint32_t meter_profile_id)\n+{\n+\tstruct mlx5_mtr_profiles *fmps = &priv->flow_meter_profiles;\n+\tstruct mlx5_flow_meter_profile *fmp;\n+\n+\tTAILQ_FOREACH(fmp, fmps, next)\n+\t\tif (meter_profile_id == fmp->meter_profile_id)\n+\t\t\treturn fmp;\n+\treturn NULL;\n+}\n+\n+/**\n+ * Calculate mantissa and exponent for cir.\n+ *\n+ * @param[in] cir\n+ *   Value to be calculated.\n+ * @param[out] man\n+ *   Pointer to the mantissa.\n+ * @param[out] exp\n+ *   Pointer to the exp.\n+ */\n+static void\n+mlx5_flow_meter_cir_man_exp_calc(int64_t cir, uint8_t *man, uint8_t *exp)\n+{\n+\tint64_t _cir;\n+\tint64_t delta = INT64_MAX;\n+\tuint8_t _man = 0;\n+\tuint8_t _exp = 0;\n+\tuint64_t m, e;\n+\n+\tfor (m = 0; m <= 0xFF; m++) { /* man width 8 bit */\n+\t\tfor (e = 0; e <= 0x1F; e++) { /* exp width 5bit */\n+\t\t\t_cir = (1000000000ULL * m) >> e;\n+\t\t\tif (llabs(cir - _cir) <= delta) {\n+\t\t\t\tdelta = llabs(cir - _cir);\n+\t\t\t\t_man = m;\n+\t\t\t\t_exp = e;\n+\t\t\t}\n+\t\t}\n+\t}\n+\t*man = _man;\n+\t*exp = _exp;\n+}\n+\n+/**\n+ * Calculate mantissa and exponent for xbs.\n+ *\n+ * @param[in] xbs\n+ *   Value to be calculated.\n+ * @param[out] man\n+ *   Pointer to the mantissa.\n+ * @param[out] exp\n+ *   Pointer to the exp.\n+ */\n+static void\n+mlx5_flow_meter_xbs_man_exp_calc(uint64_t xbs, uint8_t *man, uint8_t *exp)\n+{\n+\tint _exp;\n+\tdouble _man;\n+\n+\t/* Special case xbs == 0 ? both exp and matissa are 0. */\n+\tif (xbs == 0) {\n+\t\t*man = 0;\n+\t\t*exp = 0;\n+\t\treturn;\n+\t}\n+\t/* xbs = xbs_mantissa * 2^xbs_exponent */\n+\t_man = frexp(xbs, &_exp);\n+\t_man = _man * pow(2, MLX5_MAN_WIDTH);\n+\t_exp = _exp - MLX5_MAN_WIDTH;\n+\t*man = (uint8_t)ceil(_man);\n+\t*exp = _exp;\n+}\n+\n+/**\n+ * Fill the prm meter parameter.\n+ *\n+ * @param[in,out] fmp\n+ *   Pointer to meter profie to be converted.\n+ * @param[out] error\n+ *   Pointer to the error structure.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_errno is set.\n+ */\n+static int\n+mlx5_flow_meter_param_fill(struct mlx5_flow_meter_profile *fmp,\n+\t\t\t  struct rte_mtr_error *error)\n+{\n+\tstruct mlx5_flow_meter_srtcm_rfc2697_prm *srtcm = &fmp->srtcm_prm;\n+\tuint8_t man, exp;\n+\n+\tif (fmp->profile.alg != RTE_MTR_SRTCM_RFC2697)\n+\t\treturn -rte_mtr_error_set(error, ENOTSUP,\n+\t\t\t\tRTE_MTR_ERROR_TYPE_METER_PROFILE,\n+\t\t\t\tNULL, \"Metering algorithm not supported.\");\n+\t /* cbs = cbs_mantissa * 2^cbs_exponent */\n+\tmlx5_flow_meter_xbs_man_exp_calc(fmp->profile.srtcm_rfc2697.cbs,\n+\t\t\t\t    &man, &exp);\n+\tsrtcm->cbs_mantissa = man;\n+\tsrtcm->cbs_exponent = exp;\n+\t/* Check if cbs mantissa is too large. */\n+\tif (srtcm->cbs_exponent != exp)\n+\t\treturn -rte_mtr_error_set(error, EINVAL,\n+\t\t\t\t\t  RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL,\n+\t\t\t\t\t  \"Metering profile parameter cbs is\"\n+\t\t\t\t\t  \" invalid.\");\n+\t/* ebs = ebs_mantissa * 2^ebs_exponent */\n+\tmlx5_flow_meter_xbs_man_exp_calc(fmp->profile.srtcm_rfc2697.ebs,\n+\t\t\t\t    &man, &exp);\n+\tsrtcm->ebs_mantissa = man;\n+\tsrtcm->ebs_exponent = exp;\n+\t/* Check if ebs mantissa is too large. */\n+\tif (srtcm->ebs_exponent != exp)\n+\t\treturn -rte_mtr_error_set(error, EINVAL,\n+\t\t\t\t\t  RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL,\n+\t\t\t\t\t  \"Metering profile parameter ebs is\"\n+\t\t\t\t\t  \" invalid.\");\n+\t/* cir = 8G * cir_mantissa * 1/(2^cir_exponent)) Bytes/Sec */\n+\tmlx5_flow_meter_cir_man_exp_calc(fmp->profile.srtcm_rfc2697.cir,\n+\t\t\t\t    &man, &exp);\n+\tsrtcm->cir_mantissa = man;\n+\tsrtcm->cir_exponent = exp;\n+\t/* Check if cir mantissa is too large. */\n+\tif (srtcm->cir_exponent != exp)\n+\t\treturn -rte_mtr_error_set(error, EINVAL,\n+\t\t\t\t\t  RTE_MTR_ERROR_TYPE_MTR_PARAMS, NULL,\n+\t\t\t\t\t  \"Metering profile parameter cir is\"\n+\t\t\t\t\t  \" invalid.\");\n+\treturn 0;\n+}\n+\n+/**\n  * Callback to get MTR capabilities.\n  *\n  * @param[in] dev\n@@ -51,10 +196,106 @@\n \treturn 0;\n }\n \n+/**\n+ * Callback to add MTR profile.\n+ *\n+ * @param[in] dev\n+ *   Pointer to Ethernet device.\n+ * @param[in] meter_profile_id\n+ *   Meter profile id.\n+ * @param[in] profile\n+ *   Pointer to meter profile detail.\n+ * @param[out] error\n+ *   Pointer to the error structure.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_errno is set.\n+ */\n+static int\n+mlx5_flow_meter_profile_add(struct rte_eth_dev *dev,\n+\t\t       uint32_t meter_profile_id,\n+\t\t       struct rte_mtr_meter_profile *profile,\n+\t\t       struct rte_mtr_error *error)\n+{\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tstruct mlx5_mtr_profiles *fmps = &priv->flow_meter_profiles;\n+\tstruct mlx5_flow_meter_profile *fmp;\n+\tint ret;\n+\n+\tif (!priv->mtr_en)\n+\t\treturn -rte_mtr_error_set(error, ENOTSUP,\n+\t\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t\t  \"Meter is not support\");\n+\t/* Meter profile memory allocation. */\n+\tfmp = rte_calloc(__func__, 1, sizeof(struct mlx5_flow_meter_profile),\n+\t\t\t RTE_CACHE_LINE_SIZE);\n+\tif (fmp == NULL)\n+\t\treturn -rte_mtr_error_set(error, ENOMEM,\n+\t\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t  NULL, \"Meter profile memory \"\n+\t\t\t\t\t  \"alloc failed.\");\n+\t/* Fill profile info. */\n+\tfmp->meter_profile_id = meter_profile_id;\n+\tfmp->profile = *profile;\n+\t/* Fill the flow meter parameters for the PRM. */\n+\tret = mlx5_flow_meter_param_fill(fmp, error);\n+\tif (ret)\n+\t\tgoto error;\n+\t/* Add to list. */\n+\tTAILQ_INSERT_TAIL(fmps, fmp, next);\n+\treturn 0;\n+error:\n+\trte_free(fmp);\n+\treturn ret;\n+}\n+\n+/**\n+ * Callback to delete MTR profile.\n+ *\n+ * @param[in] dev\n+ *   Pointer to Ethernet device.\n+ * @param[in] meter_profile_id\n+ *   Meter profile id.\n+ * @param[out] error\n+ *   Pointer to the error structure.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_errno is set.\n+ */\n+static int\n+mlx5_flow_meter_profile_delete(struct rte_eth_dev *dev,\n+\t\t\t  uint32_t meter_profile_id,\n+\t\t\t  struct rte_mtr_error *error)\n+{\n+\tstruct mlx5_priv *priv = dev->data->dev_private;\n+\tstruct mlx5_flow_meter_profile *fmp;\n+\n+\tif (!priv->mtr_en)\n+\t\treturn -rte_mtr_error_set(error, ENOTSUP,\n+\t\t\t\t\t  RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t\t  \"Meter is not support\");\n+\t/* Meter profile must exist. */\n+\tfmp = mlx5_flow_meter_profile_find(priv, meter_profile_id);\n+\tif (fmp == NULL)\n+\t\treturn -rte_mtr_error_set(error, ENOENT,\n+\t\t\t\t\t  RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,\n+\t\t\t\t\t  &meter_profile_id,\n+\t\t\t\t\t  \"Meter profile id invalid.\");\n+\t/* Check profile is unused. */\n+\tif (fmp->ref_cnt)\n+\t\treturn -rte_mtr_error_set(error, EBUSY,\n+\t\t\t\t\t  RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,\n+\t\t\t\t\t  NULL, \"Meter profile in use.\");\n+\t/* Remove from list. */\n+\tTAILQ_REMOVE(&priv->flow_meter_profiles, fmp, next);\n+\trte_free(fmp);\n+\treturn 0;\n+}\n+\n static const struct rte_mtr_ops mlx5_flow_mtr_ops = {\n \t.capabilities_get = mlx5_flow_mtr_cap_get,\n-\t.meter_profile_add = NULL,\n-\t.meter_profile_delete = NULL,\n+\t.meter_profile_add = mlx5_flow_meter_profile_add,\n+\t.meter_profile_delete = mlx5_flow_meter_profile_delete,\n \t.create = NULL,\n \t.destroy = NULL,\n \t.meter_enable = NULL,\n",
    "prefixes": [
        "v2",
        "04/19"
    ]
}