From patchwork Mon Oct 9 14:44:58 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: 29977 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 38C7C1B2A0; Mon, 9 Oct 2017 16:46:01 +0200 (CEST) Received: from mail-wm0-f54.google.com (mail-wm0-f54.google.com [74.125.82.54]) by dpdk.org (Postfix) with ESMTP id 665CD1B221 for ; Mon, 9 Oct 2017 16:45:44 +0200 (CEST) Received: by mail-wm0-f54.google.com with SMTP id b189so23125044wmd.4 for ; Mon, 09 Oct 2017 07:45: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=Yp2czo3UUoISsTGdFDD+b0MElUmRCPckGklw+se4tQo=; b=fR03F4VJo9rCHer4/4AtuxWKzlYsJxRBrc1VobZuEmVg6yIj+485qfMdDsSVaIa/yB 6kpiN7/fo6Je6QBPtRyqOLPXH3i3UGnGulb0HQ5kp/Pia21wTTvA0BQPq1FUnJsetSuz fz83i3viVg2k5FQ2ITq8G1PdS4HaXMtJmFt9f2nFmBjK7YrFEE0TvYxTrj5H0SpVCYqT 0d7ng/5FqR9FS51rfMU62+34IYCD1IG2RdJds0kbaTpd21/lyu9/3Y197ecBrI+EX3MU QxnqsaGEfJvvNB9uDSX1rsxfnr891nbd7u00Y9L8KqrbvYyXBIdU1EhW14aV3ev9et10 o1yw== 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=Yp2czo3UUoISsTGdFDD+b0MElUmRCPckGklw+se4tQo=; b=S/dlWsvFa3pxrfIiWOTNq1scfNwq3SI0lpvDYvJnwW6rfsFiPbBhIppkQfCrrWZqo5 FuT+pyv59CpO5zoc5Zj+/ihF26MrqnzRtFvh1HE6OVOFQ2uIzb2M4PVIeYfMB05U9B2z TKnQsxzk6r0CBiQToqZpoKTYTlmCh3FsUa63h5wOf3VqRjZ79zj9yOD1Kw91ib+DbSMa hchD2IvJ8/kY7vhwwl931ZNDRaKDved3np8xfdUp+hS72YILP08fhNzYGOyYDa1Nk/b3 ipVV0R1iC2DH2mmp7hucI5M478+q1o7RsyS5USw43c+I7yQLv2Yp3QJD+ObpzityLTtv FxnQ== X-Gm-Message-State: AMCzsaW60wKQ5syapQPAVx3RT8YQaSbpTeTJW4PyyxSDRx831/KYb28c 9XMXlhigyMghQNirjLExnyfva6AtgQ== X-Google-Smtp-Source: AOwi7QDYqJHAFiHPsa/4v229nw57pOVfzixNJ3c1QsyvOt6z+quelrnRgPZcEgpVtoNX7VOisv/8cg== X-Received: by 10.28.29.68 with SMTP id d65mr8986044wmd.93.1507560343831; Mon, 09 Oct 2017 07:45: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 x15sm6791495wma.32.2017.10.09.07.45.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 09 Oct 2017 07:45:43 -0700 (PDT) From: Nelio Laranjeiro To: dev@dpdk.org Cc: adrien.mazarguil@6wind.com, yskoh@mellanox.com, ferruh.yigit@intel.com Date: Mon, 9 Oct 2017 16:44:58 +0200 Message-Id: X-Mailer: git-send-email 2.1.4 In-Reply-To: References: In-Reply-To: References: Subject: [dpdk-dev] [PATCH v3 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 83c75f4..13bd250 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()