From patchwork Thu Jun 28 13:09:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiri Pirko X-Patchwork-Id: 936139 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=resnulli.us Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=resnulli-us.20150623.gappssmtp.com header.i=@resnulli-us.20150623.gappssmtp.com header.b="BPsj7UUy"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41GgCJ0NPXz9s29 for ; Thu, 28 Jun 2018 23:11:24 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965984AbeF1NLV (ORCPT ); Thu, 28 Jun 2018 09:11:21 -0400 Received: from mail-wr0-f194.google.com ([209.85.128.194]:46488 "EHLO mail-wr0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965752AbeF1NKq (ORCPT ); Thu, 28 Jun 2018 09:10:46 -0400 Received: by mail-wr0-f194.google.com with SMTP id t6-v6so5452359wrq.13 for ; Thu, 28 Jun 2018 06:10:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=resnulli-us.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=D5HIGrF+rdxa6FYk/aTAVu6S2FAKTcmRubAyWkIddlA=; b=BPsj7UUywPtVL+3D0/W4KroU3LthMdvtKCH4qcOBoAabnLn1ry5J2muGTTyBUs+cvI 6MBrj9Vo7XCv96tRqRZD6dDxZlmFBVCY8yS9Ehyu/jB5I98MFmhPTWtpr02yK5TrCr9J 1DT1AeIGpvct5vbXjGy600/+gv/JvEnldpGpMvgaM7trBO8HUENA5+4tvvKiB7fLv8Ex nxrq7Ew++QjiLPRp0nRrqUY43Zi9FD1y5oMduxqUXNVpTEG1FaKsFwZcnzydAEpnHWCS PMRfhBzvU5lZNW8e3BTi+aMjB/S/KcimxYKzyy9Ywj0DYMWpHqjJGbKRdQjahrec+UZo XRbA== 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; bh=D5HIGrF+rdxa6FYk/aTAVu6S2FAKTcmRubAyWkIddlA=; b=MkoXEgtHEJwysVVi51hXQE4qdjU7gyBTzCUA577IzYMZRWTawKkymNR3MFdTwESeM1 cRsQMSMpbRBpu94BV7Ty0kXziJjGOncy/F94n1QY2sGzS7JvFB29XMMuYXQuwBFVSxl3 LfIJSeAYrvv7HK/TNu0M4jJqj+fcdoSEO0c2o95DoCmlHMrMAxIo2a6ioQwQ62zIFgaY YHdZrpbbFHnpAd3EC4VUPsYGQMJ1OnT6LwX0Wli9zTXPV1nPrluNlX4BuwjicGnOiFsR 7HKNr6+g2ZPjWfUwbdQI8LBB870B6WX6cBxtHvMLMdwANd2ubFMVIU/Qw161ZghKdB+o cWsQ== X-Gm-Message-State: APt69E22Y/jR3PIReDIG4JTb55/swTVuXtqtFlyJvfyuhq0jjasTISjh kJrUnjhg1c0tROfu8D8OoXDN1+S5 X-Google-Smtp-Source: AAOMgpe2r8XzVE/1E55D8QDE7bV6tpEANLd/k/9OFOLe+QQ84I/mqT/JVrMFMuv9St64ZCXtW9tfzA== X-Received: by 2002:adf:b243:: with SMTP id y3-v6mr8288695wra.168.1530191444821; Thu, 28 Jun 2018 06:10:44 -0700 (PDT) Received: from localhost (jirka.pirko.cz. [84.16.102.26]) by smtp.gmail.com with ESMTPSA id q14-v6sm8663102wmd.20.2018.06.28.06.10.44 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 28 Jun 2018 06:10:44 -0700 (PDT) From: Jiri Pirko To: netdev@vger.kernel.org Cc: davem@davemloft.net, jhs@mojatatu.com, xiyou.wangcong@gmail.com, jakub.kicinski@netronome.com, simon.horman@netronome.com, john.hurley@netronome.com, dsahern@gmail.com, mlxsw@mellanox.com, sridhar.samudrala@intel.com Subject: [patch net-next v2 7/9] mlxsw: spectrum: Implement chain template hinting Date: Thu, 28 Jun 2018 15:09:05 +0200 Message-Id: <20180628130907.951-8-jiri@resnulli.us> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20180628130907.951-1-jiri@resnulli.us> References: <20180628130907.951-1-jiri@resnulli.us> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Jiri Pirko Since cld_flower provides information about the filter template for specific chain, use this information in order to prepare a region. Use the template to find out what elements are going to be used and pass that down to mlxsw_sp_acl_tcam_group_add(). Later on, when the first filter is inserted, the mlxsw_sp_acl_tcam_group_use_patterns() function would use this element usage information instead of looking up a pattern. Signed-off-by: Jiri Pirko --- drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 5 +++ drivers/net/ethernet/mellanox/mlxsw/spectrum.h | 12 +++++- drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c | 12 ++++-- .../ethernet/mellanox/mlxsw/spectrum_acl_tcam.c | 25 ++++++++++-- .../net/ethernet/mellanox/mlxsw/spectrum_flower.c | 44 ++++++++++++++++++++-- 5 files changed, 86 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c index 52437363766a..155db238e65a 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c @@ -1441,6 +1441,11 @@ mlxsw_sp_setup_tc_cls_flower(struct mlxsw_sp_acl_block *acl_block, return 0; case TC_CLSFLOWER_STATS: return mlxsw_sp_flower_stats(mlxsw_sp, acl_block, f); + case TC_CLSFLOWER_TMPLT_CREATE: + return mlxsw_sp_flower_tmplt_create(mlxsw_sp, acl_block, f); + case TC_CLSFLOWER_TMPLT_DESTROY: + mlxsw_sp_flower_tmplt_destroy(mlxsw_sp, acl_block, f); + return 0; default: return -EOPNOTSUPP; } diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h index 4a519d8edec8..b0a8e611e730 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h @@ -459,7 +459,8 @@ enum mlxsw_sp_acl_profile { struct mlxsw_sp_acl_profile_ops { size_t ruleset_priv_size; int (*ruleset_add)(struct mlxsw_sp *mlxsw_sp, - void *priv, void *ruleset_priv); + void *priv, void *ruleset_priv, + struct mlxsw_afk_element_usage *tmplt_elusage); void (*ruleset_del)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv); int (*ruleset_bind)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv, struct mlxsw_sp_port *mlxsw_sp_port, @@ -514,7 +515,8 @@ mlxsw_sp_acl_ruleset_lookup(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_ruleset * mlxsw_sp_acl_ruleset_get(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_block *block, u32 chain_index, - enum mlxsw_sp_acl_profile profile); + enum mlxsw_sp_acl_profile profile, + struct mlxsw_afk_element_usage *tmplt_elusage); void mlxsw_sp_acl_ruleset_put(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_ruleset *ruleset); u16 mlxsw_sp_acl_ruleset_group_id(struct mlxsw_sp_acl_ruleset *ruleset); @@ -594,6 +596,12 @@ void mlxsw_sp_flower_destroy(struct mlxsw_sp *mlxsw_sp, int mlxsw_sp_flower_stats(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_block *block, struct tc_cls_flower_offload *f); +int mlxsw_sp_flower_tmplt_create(struct mlxsw_sp *mlxsw_sp, + struct mlxsw_sp_acl_block *block, + struct tc_cls_flower_offload *f); +void mlxsw_sp_flower_tmplt_destroy(struct mlxsw_sp *mlxsw_sp, + struct mlxsw_sp_acl_block *block, + struct tc_cls_flower_offload *f); /* spectrum_qdisc.c */ int mlxsw_sp_tc_qdisc_init(struct mlxsw_sp_port *mlxsw_sp_port); diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c index 79b1fa27a9a4..ea42605c451d 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c @@ -319,7 +319,8 @@ int mlxsw_sp_acl_block_unbind(struct mlxsw_sp *mlxsw_sp, static struct mlxsw_sp_acl_ruleset * mlxsw_sp_acl_ruleset_create(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_block *block, u32 chain_index, - const struct mlxsw_sp_acl_profile_ops *ops) + const struct mlxsw_sp_acl_profile_ops *ops, + struct mlxsw_afk_element_usage *tmplt_elusage) { struct mlxsw_sp_acl *acl = mlxsw_sp->acl; struct mlxsw_sp_acl_ruleset *ruleset; @@ -339,7 +340,8 @@ mlxsw_sp_acl_ruleset_create(struct mlxsw_sp *mlxsw_sp, if (err) goto err_rhashtable_init; - err = ops->ruleset_add(mlxsw_sp, acl->priv, ruleset->priv); + err = ops->ruleset_add(mlxsw_sp, acl->priv, ruleset->priv, + tmplt_elusage); if (err) goto err_ops_ruleset_add; @@ -421,7 +423,8 @@ mlxsw_sp_acl_ruleset_lookup(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_ruleset * mlxsw_sp_acl_ruleset_get(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_block *block, u32 chain_index, - enum mlxsw_sp_acl_profile profile) + enum mlxsw_sp_acl_profile profile, + struct mlxsw_afk_element_usage *tmplt_elusage) { const struct mlxsw_sp_acl_profile_ops *ops; struct mlxsw_sp_acl *acl = mlxsw_sp->acl; @@ -436,7 +439,8 @@ mlxsw_sp_acl_ruleset_get(struct mlxsw_sp *mlxsw_sp, mlxsw_sp_acl_ruleset_ref_inc(ruleset); return ruleset; } - return mlxsw_sp_acl_ruleset_create(mlxsw_sp, block, chain_index, ops); + return mlxsw_sp_acl_ruleset_create(mlxsw_sp, block, chain_index, ops, + tmplt_elusage); } void mlxsw_sp_acl_ruleset_put(struct mlxsw_sp *mlxsw_sp, diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c index ad1b548e3cac..d6e4e00dfd3d 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c @@ -157,6 +157,8 @@ struct mlxsw_sp_acl_tcam_group { struct mlxsw_sp_acl_tcam_group_ops *ops; const struct mlxsw_sp_acl_tcam_pattern *patterns; unsigned int patterns_count; + bool tmplt_elusage_set; + struct mlxsw_afk_element_usage tmplt_elusage; }; struct mlxsw_sp_acl_tcam_region { @@ -216,13 +218,19 @@ mlxsw_sp_acl_tcam_group_add(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_tcam *tcam, struct mlxsw_sp_acl_tcam_group *group, const struct mlxsw_sp_acl_tcam_pattern *patterns, - unsigned int patterns_count) + unsigned int patterns_count, + struct mlxsw_afk_element_usage *tmplt_elusage) { int err; group->tcam = tcam; group->patterns = patterns; group->patterns_count = patterns_count; + if (tmplt_elusage) { + group->tmplt_elusage_set = true; + memcpy(&group->tmplt_elusage, tmplt_elusage, + sizeof(group->tmplt_elusage)); + } INIT_LIST_HEAD(&group->region_list); err = mlxsw_sp_acl_tcam_group_id_get(tcam, &group->id); if (err) @@ -431,6 +439,15 @@ mlxsw_sp_acl_tcam_group_use_patterns(struct mlxsw_sp_acl_tcam_group *group, const struct mlxsw_sp_acl_tcam_pattern *pattern; int i; + /* In case the template is set, we don't have to look up the pattern + * and just use the template. + */ + if (group->tmplt_elusage_set) { + memcpy(out, &group->tmplt_elusage, sizeof(*out)); + WARN_ON(!mlxsw_afk_element_usage_subset(elusage, out)); + return; + } + for (i = 0; i < group->patterns_count; i++) { pattern = &group->patterns[i]; mlxsw_afk_element_usage_fill(out, pattern->elements, @@ -1019,14 +1036,16 @@ struct mlxsw_sp_acl_tcam_flower_rule { static int mlxsw_sp_acl_tcam_flower_ruleset_add(struct mlxsw_sp *mlxsw_sp, - void *priv, void *ruleset_priv) + void *priv, void *ruleset_priv, + struct mlxsw_afk_element_usage *tmplt_elusage) { struct mlxsw_sp_acl_tcam_flower_ruleset *ruleset = ruleset_priv; struct mlxsw_sp_acl_tcam *tcam = priv; return mlxsw_sp_acl_tcam_group_add(mlxsw_sp, tcam, &ruleset->group, mlxsw_sp_acl_tcam_patterns, - MLXSW_SP_ACL_TCAM_PATTERNS_COUNT); + MLXSW_SP_ACL_TCAM_PATTERNS_COUNT, + tmplt_elusage); } static void diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c index 89dbf569dff5..f34b410e5048 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c @@ -401,7 +401,7 @@ int mlxsw_sp_flower_replace(struct mlxsw_sp *mlxsw_sp, ruleset = mlxsw_sp_acl_ruleset_get(mlxsw_sp, block, f->common.chain_index, - MLXSW_SP_ACL_PROFILE_FLOWER); + MLXSW_SP_ACL_PROFILE_FLOWER, NULL); if (IS_ERR(ruleset)) return PTR_ERR(ruleset); @@ -445,7 +445,7 @@ void mlxsw_sp_flower_destroy(struct mlxsw_sp *mlxsw_sp, ruleset = mlxsw_sp_acl_ruleset_get(mlxsw_sp, block, f->common.chain_index, - MLXSW_SP_ACL_PROFILE_FLOWER); + MLXSW_SP_ACL_PROFILE_FLOWER, NULL); if (IS_ERR(ruleset)) return; @@ -471,7 +471,7 @@ int mlxsw_sp_flower_stats(struct mlxsw_sp *mlxsw_sp, ruleset = mlxsw_sp_acl_ruleset_get(mlxsw_sp, block, f->common.chain_index, - MLXSW_SP_ACL_PROFILE_FLOWER); + MLXSW_SP_ACL_PROFILE_FLOWER, NULL); if (WARN_ON(IS_ERR(ruleset))) return -EINVAL; @@ -493,3 +493,41 @@ int mlxsw_sp_flower_stats(struct mlxsw_sp *mlxsw_sp, mlxsw_sp_acl_ruleset_put(mlxsw_sp, ruleset); return err; } + +int mlxsw_sp_flower_tmplt_create(struct mlxsw_sp *mlxsw_sp, + struct mlxsw_sp_acl_block *block, + struct tc_cls_flower_offload *f) +{ + struct mlxsw_sp_acl_ruleset *ruleset; + struct mlxsw_sp_acl_rule_info rulei; + int err; + + memset(&rulei, 0, sizeof(rulei)); + err = mlxsw_sp_flower_parse(mlxsw_sp, block, &rulei, f); + if (err) + return err; + ruleset = mlxsw_sp_acl_ruleset_get(mlxsw_sp, block, + f->common.chain_index, + MLXSW_SP_ACL_PROFILE_FLOWER, + &rulei.values.elusage); + if (IS_ERR(ruleset)) + return PTR_ERR(ruleset); + /* keep the reference to the ruleset */ + return 0; +} + +void mlxsw_sp_flower_tmplt_destroy(struct mlxsw_sp *mlxsw_sp, + struct mlxsw_sp_acl_block *block, + struct tc_cls_flower_offload *f) +{ + struct mlxsw_sp_acl_ruleset *ruleset; + + ruleset = mlxsw_sp_acl_ruleset_get(mlxsw_sp, block, + f->common.chain_index, + MLXSW_SP_ACL_PROFILE_FLOWER, NULL); + if (IS_ERR(ruleset)) + return; + /* put the reference to the ruleset kept in create */ + mlxsw_sp_acl_ruleset_put(mlxsw_sp, ruleset); + mlxsw_sp_acl_ruleset_put(mlxsw_sp, ruleset); +}