From patchwork Thu Oct 5 12:49:54 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?N=C3=A9lio_Laranjeiro?= X-Patchwork-Id: 29714 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 274B01B27D; Thu, 5 Oct 2017 14:50:57 +0200 (CEST) Received: from mail-wm0-f49.google.com (mail-wm0-f49.google.com [74.125.82.49]) by dpdk.org (Postfix) with ESMTP id 55FBD1B213 for ; Thu, 5 Oct 2017 14:50:44 +0200 (CEST) Received: by mail-wm0-f49.google.com with SMTP id q132so1995862wmd.2 for ; Thu, 05 Oct 2017 05:50:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=dN5G7AZo6Sw6zwZgFn6CTn4hnLt5//NhzRt3goABis4=; b=FwDzfXVADJa+YZkyEZrnBqP72LYFF/ZEKCwihiXZNKd9YPAwFwEsZnC+tnZOHNd+IK lCKUHRvK1NhPWZ2GKaeDcEr16gQTr7TLabPxW5XaDaR393ojciy7n7tt1fzzT7HkUcuu YZ1b1hc+1PWvYYikoRj0bZ05tEqcdf+6TdPr2F+J/eOHFGfw0rOOCeOdM6nnHtu9Tbd+ 6CXyiXYJpe17UzfcXgwnaWBYizsNyDqrTLXG6CZAuDJBux4AHOv/5j0l/9W9lDjR032z pTz1hdV/ohehCaswhFuoztOk1EGcIHd09iU4rf6o9uY8I7AosdYKa/0BOLVCL8yKoui4 hUbw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=dN5G7AZo6Sw6zwZgFn6CTn4hnLt5//NhzRt3goABis4=; b=RkYxry9WDfD1f7lBgbpas4EKpOljmE4hrQohTq1r+tRGevaQ5ySEL+PA4JQ8FHBlPd 2yeENv1FGeCwxtS0Sb59KdtM7VlXiQKEUmRsktC2RdXcOGHBttE3i/S4aEgetoYvnj/i S62CSO5bv+GmZxHrK+YV7cDZjc/453wtMu40I/h4qhjc+lPWfpAGCp7kLy5KF1obBYJP JOFRfYOmKkxTh0Gg/1Y62b5YyT4beMgmZgmwkD++vohHqNSGVpMMUyx3eXRgna9Ns6m6 mw3dt4iVRGk3T1KvVe2G3qSykQAN6u8TmmJncdEjqxq+m5sR935MYDk1Hg6ez34RZaPc 4pGA== X-Gm-Message-State: AHPjjUhF7c5iB8Xb8bqYTF+Uip+bfgulEq2BvBBaOUPcWN8W6wPMluLQ jvSmkpKNE5Fs8Vzc9pM1YKapAXchcg== X-Google-Smtp-Source: AOwi7QCyPqKaKKKTgUHlYmdsIuyqCZCQ259UAvXCiKKJ0pQljnIXzDIcg/JO+s473wgQUFmdt6ZhQA== X-Received: by 10.28.21.205 with SMTP id 196mr19742528wmv.77.1507207843751; Thu, 05 Oct 2017 05:50:43 -0700 (PDT) Received: from ping.dev.6wind.com (host.78.145.23.62.rev.coltfrance.com. [62.23.145.78]) by smtp.gmail.com with ESMTPSA id k9sm26405823wrk.27.2017.10.05.05.50.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 05 Oct 2017 05:50:43 -0700 (PDT) From: Nelio Laranjeiro To: dev@dpdk.org Cc: adrien.mazarguil@6wind.com, yskoh@mellanox.com, ferruh.yigit@intel.com Date: Thu, 5 Oct 2017 14:49:54 +0200 Message-Id: X-Mailer: git-send-email 2.1.4 In-Reply-To: References: In-Reply-To: References: Subject: [dpdk-dev] [PATCH v2 22/30] net/mlx5: fully convert a flow to verbs in validate X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Validation of flows is only making few verifications on the pattern, in some situation the validate action could end by with success whereas the pattern could not be converted correctly. This brings this conversion verification part also to the validate. Signed-off-by: Nelio Laranjeiro Acked-by: Yongseok Koh --- drivers/net/mlx5/mlx5_flow.c | 194 +++++++++++++++++++++++++------------------ 1 file changed, 114 insertions(+), 80 deletions(-) diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index 88d02c9..090a298 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -307,6 +307,7 @@ struct mlx5_flow_parse { struct ibv_flow_attr *ibv_attr; /**< Verbs attribute. */ unsigned int offset; /**< Offset in bytes in the ibv_attr buffer. */ uint32_t inner; /**< Set once VXLAN is encountered. */ + uint32_t create:1; /**< Leave allocated resources on exit. */ uint64_t hash_fields; /**< Fields that participate in the hash. */ struct mlx5_flow_action actions; /**< Parsed action result. */ }; @@ -418,7 +419,7 @@ mlx5_flow_item_validate(const struct rte_flow_item *item, } /** - * Validate a flow supported by the NIC. + * Validate and convert a flow supported by the NIC. * * @param priv * Pointer to private structure. @@ -437,16 +438,24 @@ mlx5_flow_item_validate(const struct rte_flow_item *item, * 0 on success, a negative errno value otherwise and rte_errno is set. */ static int -priv_flow_validate(struct priv *priv, - const struct rte_flow_attr *attr, - const struct rte_flow_item items[], - const struct rte_flow_action actions[], - struct rte_flow_error *error, - struct mlx5_flow_parse *flow) +priv_flow_convert(struct priv *priv, + const struct rte_flow_attr *attr, + const struct rte_flow_item items[], + const struct rte_flow_action actions[], + struct rte_flow_error *error, + struct mlx5_flow_parse *flow) { const struct mlx5_flow_items *cur_item = mlx5_flow_items; (void)priv; + *flow = (struct mlx5_flow_parse){ + .ibv_attr = flow->ibv_attr, + .create = flow->create, + .offset = sizeof(struct ibv_flow_attr), + .actions = { + .mark_id = MLX5_FLOW_MARK_DEFAULT, + }, + }; if (attr->group) { rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR_GROUP, @@ -647,35 +656,6 @@ priv_flow_validate(struct priv *priv, } /** - * Validate a flow supported by the NIC. - * - * @see rte_flow_validate() - * @see rte_flow_ops - */ -int -mlx5_flow_validate(struct rte_eth_dev *dev, - const struct rte_flow_attr *attr, - const struct rte_flow_item items[], - const struct rte_flow_action actions[], - struct rte_flow_error *error) -{ - struct priv *priv = dev->data->dev_private; - int ret; - struct mlx5_flow_parse flow = { - .offset = sizeof(struct ibv_flow_attr), - .actions = { - .mark_id = MLX5_FLOW_MARK_DEFAULT, - .queues_n = 0, - }, - }; - - priv_lock(priv); - ret = priv_flow_validate(priv, attr, items, actions, error, &flow); - priv_unlock(priv); - return ret; -} - -/** * Convert Ethernet item to Verbs specification. * * @param item[in] @@ -1016,6 +996,7 @@ mlx5_flow_create_flag_mark(struct mlx5_flow_parse *flow, uint32_t mark_id) struct ibv_flow_spec_action_tag *tag; unsigned int size = sizeof(struct ibv_flow_spec_action_tag); + assert(flow->actions.mark); tag = (void *)((uintptr_t)flow->ibv_attr + flow->offset); *tag = (struct ibv_flow_spec_action_tag){ .type = IBV_FLOW_SPEC_ACTION_TAG, @@ -1023,6 +1004,7 @@ mlx5_flow_create_flag_mark(struct mlx5_flow_parse *flow, uint32_t mark_id) .tag_id = mlx5_flow_mark_set(mark_id), }; ++flow->ibv_attr->num_of_specs; + flow->offset += size; return 0; } @@ -1167,12 +1149,10 @@ priv_flow_create_action_queue(struct priv *priv, } /** - * Convert a flow. + * Validate a flow. * * @param priv * Pointer to private structure. - * @param list - * Pointer to a TAILQ flow list. * @param[in] attr * Flow rule attributes. * @param[in] pattern @@ -1181,40 +1161,35 @@ priv_flow_create_action_queue(struct priv *priv, * Associated actions (list terminated by the END action). * @param[out] error * Perform verbose error reporting if not NULL. + * @param[in,out] parser + * MLX5 parser structure. * * @return - * A flow on success, NULL otherwise. + * 0 on success, negative errno value on failure. */ -static struct rte_flow * -priv_flow_create(struct priv *priv, - struct mlx5_flows *list, - const struct rte_flow_attr *attr, - const struct rte_flow_item items[], - const struct rte_flow_action actions[], - struct rte_flow_error *error) +static int +priv_flow_validate(struct priv *priv, + const struct rte_flow_attr *attr, + const struct rte_flow_item items[], + const struct rte_flow_action actions[], + struct rte_flow_error *error, + struct mlx5_flow_parse *parser) { - struct rte_flow *rte_flow; - struct mlx5_flow_parse flow = { - .offset = sizeof(struct ibv_flow_attr), - .actions = { - .mark_id = MLX5_FLOW_MARK_DEFAULT, - .queues = { 0 }, - .queues_n = 0, - }, - }; int err; - err = priv_flow_validate(priv, attr, items, actions, error, &flow); + err = priv_flow_convert(priv, attr, items, actions, error, parser); if (err) goto exit; - flow.ibv_attr = rte_malloc(__func__, flow.offset, 0); - flow.offset = sizeof(struct ibv_flow_attr); - if (!flow.ibv_attr) { + if (parser->actions.mark) + parser->offset += sizeof(struct ibv_flow_spec_action_tag); + parser->ibv_attr = rte_malloc(__func__, parser->offset, 0); + if (!parser->ibv_attr) { rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, "cannot allocate ibv_attr memory"); + err = rte_errno; goto exit; } - *flow.ibv_attr = (struct ibv_flow_attr){ + *parser->ibv_attr = (struct ibv_flow_attr){ .type = IBV_FLOW_ATTR_NORMAL, .size = sizeof(struct ibv_flow_attr), .priority = attr->priority, @@ -1222,32 +1197,91 @@ priv_flow_create(struct priv *priv, .port = 0, .flags = 0, }; - flow.inner = 0; - flow.hash_fields = 0; - claim_zero(priv_flow_validate(priv, attr, items, actions, - error, &flow)); - if (flow.actions.mark && !flow.actions.drop) { - mlx5_flow_create_flag_mark(&flow, flow.actions.mark_id); - flow.offset += sizeof(struct ibv_flow_spec_action_tag); - } - if (flow.actions.drop) - rte_flow = - priv_flow_create_action_queue_drop(priv, &flow, error); + err = priv_flow_convert(priv, attr, items, actions, error, parser); + if (err || parser->create) + goto exit; + if (parser->actions.mark) + mlx5_flow_create_flag_mark(parser, parser->actions.mark_id); + return 0; +exit: + if (parser->ibv_attr) + rte_free(parser->ibv_attr); + return err; +} + +/** + * Convert a flow. + * + * @param priv + * Pointer to private structure. + * @param list + * Pointer to a TAILQ flow list. + * @param[in] attr + * Flow rule attributes. + * @param[in] pattern + * Pattern specification (list terminated by the END pattern item). + * @param[in] actions + * Associated actions (list terminated by the END action). + * @param[out] error + * Perform verbose error reporting if not NULL. + * + * @return + * A flow on success, NULL otherwise. + */ +static struct rte_flow * +priv_flow_create(struct priv *priv, + struct mlx5_flows *list, + const struct rte_flow_attr *attr, + const struct rte_flow_item items[], + const struct rte_flow_action actions[], + struct rte_flow_error *error) +{ + struct mlx5_flow_parse parser = { .create = 1, }; + struct rte_flow *flow; + int err; + + err = priv_flow_validate(priv, attr, items, actions, error, &parser); + if (err) + goto exit; + if (parser.actions.drop) + flow = priv_flow_create_action_queue_drop(priv, &parser, error); else - rte_flow = priv_flow_create_action_queue(priv, &flow, error); - if (!rte_flow) + flow = priv_flow_create_action_queue(priv, &parser, error); + if (!flow) goto exit; - if (rte_flow) { - TAILQ_INSERT_TAIL(list, rte_flow, next); - DEBUG("Flow created %p", (void *)rte_flow); - } - return rte_flow; + TAILQ_INSERT_TAIL(list, flow, next); + DEBUG("Flow created %p", (void *)flow); + return flow; exit: - rte_free(flow.ibv_attr); + if (parser.ibv_attr) + rte_free(parser.ibv_attr); return NULL; } /** + * Validate a flow supported by the NIC. + * + * @see rte_flow_validate() + * @see rte_flow_ops + */ +int +mlx5_flow_validate(struct rte_eth_dev *dev, + const struct rte_flow_attr *attr, + const struct rte_flow_item items[], + const struct rte_flow_action actions[], + struct rte_flow_error *error) +{ + struct priv *priv = dev->data->dev_private; + int ret; + struct mlx5_flow_parse parser = { .create = 0, }; + + priv_lock(priv); + ret = priv_flow_validate(priv, attr, items, actions, error, &parser); + priv_unlock(priv); + return ret; +} + +/** * Create a flow. * * @see rte_flow_create()