From patchwork Mon Aug 17 12:50:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ido Schimmel X-Patchwork-Id: 1346201 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=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=idosch.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.a=rsa-sha256 header.s=fm3 header.b=EK5Auc/f; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4BVYpz1xcyz9sTH for ; Mon, 17 Aug 2020 22:52:27 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728472AbgHQMwZ (ORCPT ); Mon, 17 Aug 2020 08:52:25 -0400 Received: from wnew3-smtp.messagingengine.com ([64.147.123.17]:40545 "EHLO wnew3-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726265AbgHQMwT (ORCPT ); Mon, 17 Aug 2020 08:52:19 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailnew.west.internal (Postfix) with ESMTP id 064B591A; Mon, 17 Aug 2020 08:52:16 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Mon, 17 Aug 2020 08:52:18 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=vRj7vivqnf1v+jiCT5U1Hl4dU1EvMWMoZLKfL7WV5xE=; b=EK5Auc/f kXYN1NxTc/I0Dxz0WHsVxRSO5z7kwV6zYC5OeNMjpYuay2H/bWI1FUcep3/6g5SZ 6EMGDHLe2Dl6WISGAJoO7nNNdtQCBgHI/BmzHP1LBjrp2Nrbxs6IHPRIkwQKL2Ez LHZSKoDxLZpVBn9jEw5ZeK9ERG/TNCGMV0snxKcUMu5TX65/ntwJ3b/SQTjt2GJ7 AParUsC/VKye2WnjyALHVcq+sDPZMCjzZCOBOce3iMqBiy78ZOg2PBgen+Zv7X/2 8dxOs/0tvoqDJWSaZ1VYx7E0pfdAmV9J6DqxqVYXM3BagvpHUIg3+4rm7DhCuNMv QsShlSfId+skIA== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduiedruddtfedgheeiucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefhvffufffkofgjfhgggfestdekre dtredttdenucfhrhhomhepkfguohcuufgthhhimhhmvghluceoihguohhstghhsehiugho shgthhdrohhrgheqnecuggftrfgrthhtvghrnhepudetieevffffveelkeeljeffkefhke ehgfdtffethfelvdejgffghefgveejkefhnecukfhppeejledrudekvddrieefrdegvden ucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehiughosh gthhesihguohhstghhrdhorhhg X-ME-Proxy: Received: from localhost.localdomain (bzq-79-182-63-42.red.bezeqint.net [79.182.63.42]) by mail.messagingengine.com (Postfix) with ESMTPA id 368623060067; Mon, 17 Aug 2020 08:52:02 -0400 (EDT) From: Ido Schimmel To: netdev@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, jiri@nvidia.com, amcohen@nvidia.com, danieller@nvidia.com, mlxsw@nvidia.com, roopa@nvidia.com, dsahern@gmail.com, andrew@lunn.ch, f.fainelli@gmail.com, vivien.didelot@gmail.com, saeedm@nvidia.com, tariqt@nvidia.com, ayal@nvidia.com, eranbe@nvidia.com, mkubecek@suse.cz, Ido Schimmel Subject: [RFC PATCH net-next 1/6] devlink: Add device metric infrastructure Date: Mon, 17 Aug 2020 15:50:54 +0300 Message-Id: <20200817125059.193242-2-idosch@idosch.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200817125059.193242-1-idosch@idosch.org> References: <20200817125059.193242-1-idosch@idosch.org> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Ido Schimmel Add an infrastructure that allows device drivers to dynamically register and unregister their supported metrics with devlink. The metrics and their values are exposed to user space which can decide to group certain metrics together. This allows user space to request a filtered dump of only the metrics member in the provided group. Currently, the only supported metric type is a counter, but histograms will be added in the future for devices that implement histogram agents in hardware. Signed-off-by: Amit Cohen Signed-off-by: Danielle Ratson Signed-off-by: Ido Schimmel --- .../networking/devlink/devlink-metric.rst | 26 ++ Documentation/networking/devlink/index.rst | 1 + include/net/devlink.h | 18 + include/uapi/linux/devlink.h | 19 + net/core/devlink.c | 346 ++++++++++++++++++ 5 files changed, 410 insertions(+) create mode 100644 Documentation/networking/devlink/devlink-metric.rst diff --git a/Documentation/networking/devlink/devlink-metric.rst b/Documentation/networking/devlink/devlink-metric.rst new file mode 100644 index 000000000000..cf5c5b4e4077 --- /dev/null +++ b/Documentation/networking/devlink/devlink-metric.rst @@ -0,0 +1,26 @@ +.. SPDX-License-Identifier: GPL-2.0 + +============== +Devlink Metric +============== + +The ``devlink-metric`` mechanism allows device drivers to expose device metrics +to user space in a standard and extensible fashion. It provides an alternative +to the driver-specific debugfs interface. + +Metric Types +============ + +The ``devlink-metric`` mechanism supports the following metric types: + + * ``counter``: Monotonically increasing. Cannot be reset. + +Metrics Documentation +===================== + +All the metrics exposed by a device driver must be clearly documented in the +driver-specific ``devlink`` documentation under +``Documentation/networking/devlink/``. + +When possible, a selftest (under ``tools/testing/selftests/drivers/``) should +also be provided to ensure the metrics are updated under the right conditions. diff --git a/Documentation/networking/devlink/index.rst b/Documentation/networking/devlink/index.rst index 7684ae5c4a4a..b6f353384968 100644 --- a/Documentation/networking/devlink/index.rst +++ b/Documentation/networking/devlink/index.rst @@ -21,6 +21,7 @@ general. devlink-region devlink-resource devlink-trap + devlink-metric Driver-specific documentation ----------------------------- diff --git a/include/net/devlink.h b/include/net/devlink.h index 8f3c8a443238..f4754075dc43 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -36,6 +36,7 @@ struct devlink { struct list_head trap_list; struct list_head trap_group_list; struct list_head trap_policer_list; + struct list_head metric_list; const struct devlink_ops *ops; struct xarray snapshot_ids; struct device *dev; @@ -990,6 +991,16 @@ enum devlink_trap_group_generic_id { .min_burst = _min_burst, \ } +struct devlink_metric; + +/** + * struct devlink_metric_ops - Metric operations. + * @counter_get: Get the counter value. Cannot be NULL when counter. + */ +struct devlink_metric_ops { + int (*counter_get)(struct devlink_metric *metric, u64 *p_val); +}; + struct devlink_ops { int (*reload_down)(struct devlink *devlink, bool netns_change, struct netlink_ext_ack *extack); @@ -1405,6 +1416,13 @@ devlink_trap_policers_unregister(struct devlink *devlink, const struct devlink_trap_policer *policers, size_t policers_count); +void *devlink_metric_priv(struct devlink_metric *metric); +struct devlink_metric * +devlink_metric_counter_create(struct devlink *devlink, const char *name, + const struct devlink_metric_ops *ops, void *priv); +void devlink_metric_destroy(struct devlink *devlink, + struct devlink_metric *metric); + #if IS_ENABLED(CONFIG_NET_DEVLINK) void devlink_compat_running_version(struct net_device *dev, diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h index cfef4245ea5a..ebb555cb7cf7 100644 --- a/include/uapi/linux/devlink.h +++ b/include/uapi/linux/devlink.h @@ -122,6 +122,11 @@ enum devlink_command { DEVLINK_CMD_TRAP_POLICER_NEW, DEVLINK_CMD_TRAP_POLICER_DEL, + DEVLINK_CMD_METRIC_GET, /* can dump */ + DEVLINK_CMD_METRIC_SET, + DEVLINK_CMD_METRIC_NEW, + DEVLINK_CMD_METRIC_DEL, + /* add new commands above here */ __DEVLINK_CMD_MAX, DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1 @@ -272,6 +277,14 @@ enum { DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE, }; +/** + * enum devlink_metric_type - Metric type. + * @DEVLINK_METRIC_TYPE_COUNTER: Counter. Monotonically increasing. + */ +enum devlink_metric_type { + DEVLINK_METRIC_TYPE_COUNTER, +}; + enum devlink_attr { /* don't change the order or add anything between, this is ABI! */ DEVLINK_ATTR_UNSPEC, @@ -458,6 +471,12 @@ enum devlink_attr { DEVLINK_ATTR_PORT_LANES, /* u32 */ DEVLINK_ATTR_PORT_SPLITTABLE, /* u8 */ + DEVLINK_ATTR_METRIC_NAME, /* string */ + /* enum devlink_metric_type */ + DEVLINK_ATTR_METRIC_TYPE, /* u8 */ + DEVLINK_ATTR_METRIC_COUNTER_VALUE, /* u64 */ + DEVLINK_ATTR_METRIC_GROUP, /* u32 */ + /* add new attributes above here, update the policy in devlink.c */ __DEVLINK_ATTR_MAX, diff --git a/net/core/devlink.c b/net/core/devlink.c index e674f0f46dc2..94c0a1e09242 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c @@ -6994,6 +6994,218 @@ static int devlink_nl_cmd_trap_policer_set_doit(struct sk_buff *skb, return devlink_trap_policer_set(devlink, policer_item, info); } +/** + * struct devlink_metric - Metric attributes. + * @name: Metric name. + * @ops: Metric operations. + * @list: Member of 'metric_list' + * @type: Metric type. + * @group: Group number. '0' is the default group number. + * @priv: Metric private information. + */ +struct devlink_metric { + const char *name; + const struct devlink_metric_ops *ops; + struct list_head list; + enum devlink_metric_type type; + u32 group; + void *priv; +}; + +static struct devlink_metric * +devlink_metric_lookup(struct devlink *devlink, const char *name) +{ + struct devlink_metric *metric; + + list_for_each_entry(metric, &devlink->metric_list, list) { + if (!strcmp(metric->name, name)) + return metric; + } + + return NULL; +} + +static struct devlink_metric * +devlink_metric_get_from_info(struct devlink *devlink, struct genl_info *info) +{ + struct nlattr *attr; + + if (!info->attrs[DEVLINK_ATTR_METRIC_NAME]) + return NULL; + attr = info->attrs[DEVLINK_ATTR_METRIC_NAME]; + + return devlink_metric_lookup(devlink, nla_data(attr)); +} + +static int devlink_nl_metric_counter_fill(struct sk_buff *msg, + struct devlink_metric *metric) +{ + u64 val; + int err; + + err = metric->ops->counter_get(metric, &val); + if (err) + return err; + + if (nla_put_u64_64bit(msg, DEVLINK_ATTR_METRIC_COUNTER_VALUE, val, + DEVLINK_ATTR_PAD)) + return -EMSGSIZE; + + return 0; +} + +static int +devlink_nl_metric_fill(struct sk_buff *msg, struct devlink *devlink, + struct devlink_metric *metric, enum devlink_command cmd, + u32 portid, u32 seq, int flags) +{ + void *hdr; + + hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); + if (!hdr) + return -EMSGSIZE; + + if (devlink_nl_put_handle(msg, devlink)) + goto nla_put_failure; + + if (nla_put_string(msg, DEVLINK_ATTR_METRIC_NAME, metric->name)) + goto nla_put_failure; + + if (nla_put_u8(msg, DEVLINK_ATTR_METRIC_TYPE, metric->type)) + goto nla_put_failure; + + if (metric->type == DEVLINK_METRIC_TYPE_COUNTER && + devlink_nl_metric_counter_fill(msg, metric)) + goto nla_put_failure; + + if (nla_put_u32(msg, DEVLINK_ATTR_METRIC_GROUP, metric->group)) + goto nla_put_failure; + + genlmsg_end(msg, hdr); + + return 0; + +nla_put_failure: + genlmsg_cancel(msg, hdr); + return -EMSGSIZE; +} + +static int devlink_nl_cmd_metric_get_doit(struct sk_buff *skb, + struct genl_info *info) +{ + struct netlink_ext_ack *extack = info->extack; + struct devlink *devlink = info->user_ptr[0]; + struct devlink_metric *metric; + struct sk_buff *msg; + int err; + + if (list_empty(&devlink->metric_list)) + return -EOPNOTSUPP; + + metric = devlink_metric_get_from_info(devlink, info); + if (!metric) { + NL_SET_ERR_MSG_MOD(extack, "Device did not register this metric"); + return -ENOENT; + } + + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!msg) + return -ENOMEM; + + err = devlink_nl_metric_fill(msg, devlink, metric, + DEVLINK_CMD_METRIC_NEW, info->snd_portid, + info->snd_seq, 0); + if (err) + goto err_metric_fill; + + return genlmsg_reply(msg, info); + +err_metric_fill: + nlmsg_free(msg); + return err; +} + +static int devlink_nl_cmd_metric_get_dumpit(struct sk_buff *msg, + struct netlink_callback *cb) +{ + const struct genl_dumpit_info *info = genl_dumpit_info(cb); + enum devlink_command cmd = DEVLINK_CMD_METRIC_NEW; + u32 portid = NETLINK_CB(cb->skb).portid; + struct devlink_metric *metric; + struct devlink *devlink; + int start = cb->args[0]; + int flags = NLM_F_MULTI; + u32 group = 0; + int idx = 0; + int err; + + if (info->attrs[DEVLINK_ATTR_METRIC_GROUP]) { + group = nla_get_u32(info->attrs[DEVLINK_ATTR_METRIC_GROUP]); + flags |= NLM_F_DUMP_FILTERED; + } + + mutex_lock(&devlink_mutex); + list_for_each_entry(devlink, &devlink_list, list) { + if (!net_eq(devlink_net(devlink), sock_net(msg->sk))) + continue; + mutex_lock(&devlink->lock); + list_for_each_entry(metric, &devlink->metric_list, list) { + if (idx < start) { + idx++; + continue; + } + if (group && metric->group != group) { + idx++; + continue; + } + err = devlink_nl_metric_fill(msg, devlink, metric, cmd, + portid, cb->nlh->nlmsg_seq, + flags); + if (err) { + mutex_unlock(&devlink->lock); + goto out; + } + idx++; + } + mutex_unlock(&devlink->lock); + } +out: + mutex_unlock(&devlink_mutex); + + cb->args[0] = idx; + return msg->len; +} + +static void devlink_metric_group_set(struct devlink_metric *metric, + struct genl_info *info) +{ + if (!info->attrs[DEVLINK_ATTR_METRIC_GROUP]) + return; + + metric->group = nla_get_u32(info->attrs[DEVLINK_ATTR_METRIC_GROUP]); +} + +static int devlink_nl_cmd_metric_set_doit(struct sk_buff *skb, + struct genl_info *info) +{ + struct netlink_ext_ack *extack = info->extack; + struct devlink *devlink = info->user_ptr[0]; + struct devlink_metric *metric; + + if (list_empty(&devlink->metric_list)) + return -EOPNOTSUPP; + + metric = devlink_metric_get_from_info(devlink, info); + if (!metric) { + NL_SET_ERR_MSG_MOD(extack, "Device did not register this metric"); + return -ENOENT; + } + + devlink_metric_group_set(metric, info); + + return 0; +} + static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = { [DEVLINK_ATTR_UNSPEC] = { .strict_start_type = DEVLINK_ATTR_TRAP_POLICER_ID }, @@ -7039,6 +7251,9 @@ static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = { [DEVLINK_ATTR_TRAP_POLICER_RATE] = { .type = NLA_U64 }, [DEVLINK_ATTR_TRAP_POLICER_BURST] = { .type = NLA_U64 }, [DEVLINK_ATTR_PORT_FUNCTION] = { .type = NLA_NESTED }, + [DEVLINK_ATTR_METRIC_NAME] = { .type = NLA_NUL_STRING }, + [DEVLINK_ATTR_METRIC_TYPE] = { .type = NLA_U8 }, + [DEVLINK_ATTR_METRIC_GROUP] = { .type = NLA_U32 }, }; static const struct genl_ops devlink_nl_ops[] = { @@ -7347,6 +7562,17 @@ static const struct genl_ops devlink_nl_ops[] = { .doit = devlink_nl_cmd_trap_policer_set_doit, .flags = GENL_ADMIN_PERM, }, + { + .cmd = DEVLINK_CMD_METRIC_GET, + .doit = devlink_nl_cmd_metric_get_doit, + .dumpit = devlink_nl_cmd_metric_get_dumpit, + /* can be retrieved by unprivileged users */ + }, + { + .cmd = DEVLINK_CMD_METRIC_SET, + .doit = devlink_nl_cmd_metric_set_doit, + .flags = GENL_ADMIN_PERM, + }, }; static struct genl_family devlink_nl_family __ro_after_init = { @@ -7396,6 +7622,7 @@ struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size) INIT_LIST_HEAD(&devlink->trap_list); INIT_LIST_HEAD(&devlink->trap_group_list); INIT_LIST_HEAD(&devlink->trap_policer_list); + INIT_LIST_HEAD(&devlink->metric_list); mutex_init(&devlink->lock); mutex_init(&devlink->reporters_lock); return devlink; @@ -7480,6 +7707,7 @@ void devlink_free(struct devlink *devlink) { mutex_destroy(&devlink->reporters_lock); mutex_destroy(&devlink->lock); + WARN_ON(!list_empty(&devlink->metric_list)); WARN_ON(!list_empty(&devlink->trap_policer_list)); WARN_ON(!list_empty(&devlink->trap_group_list)); WARN_ON(!list_empty(&devlink->trap_list)); @@ -9484,6 +9712,124 @@ devlink_trap_policers_unregister(struct devlink *devlink, } EXPORT_SYMBOL_GPL(devlink_trap_policers_unregister); +/** + * devlink_metric_priv - Return metric private information. + * @metric: Metric. + * + * Return: Metric private information that was passed from device-driver + * during metric creation. + */ +void *devlink_metric_priv(struct devlink_metric *metric) +{ + return metric->priv; +} +EXPORT_SYMBOL_GPL(devlink_metric_priv); + +static void devlink_metric_notify(struct devlink *devlink, + struct devlink_metric *metric, + enum devlink_command cmd) +{ + struct sk_buff *msg; + int err; + + WARN_ON_ONCE(cmd != DEVLINK_CMD_METRIC_NEW && + cmd != DEVLINK_CMD_METRIC_DEL); + + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); + if (!msg) + return; + + err = devlink_nl_metric_fill(msg, devlink, metric, cmd, 0, 0, 0); + if (err) { + nlmsg_free(msg); + return; + } + + genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), + msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); +} + +/** + * devlink_metric_counter_create - Create metric of counter type. + * @devlink: devlink. + * @name: Metric name. + * @ops: Metric operations. + * @priv: Metric private information. + * + * All metrics must be documented in the per-device documentation under + * Documentation/networking/devlink/. + * + * Return: Error pointer on failure. + */ +struct devlink_metric * +devlink_metric_counter_create(struct devlink *devlink, const char *name, + const struct devlink_metric_ops *ops, void *priv) +{ + struct devlink_metric *metric; + int err; + + if (!ops || !ops->counter_get || !name) + return ERR_PTR(-EINVAL); + + mutex_lock(&devlink->lock); + + if (devlink_metric_lookup(devlink, name)) { + err = -EEXIST; + goto err_exists; + } + + metric = kzalloc(sizeof(*metric), GFP_KERNEL); + if (!metric) { + err = -ENOMEM; + goto err_alloc_metric; + } + + metric->name = kstrdup(name, GFP_KERNEL); + if (!metric->name) { + err = -ENOMEM; + goto err_alloc_metric_name; + } + + metric->ops = ops; + metric->type = DEVLINK_METRIC_TYPE_COUNTER; + metric->group = 0; + metric->priv = priv; + + list_add_tail(&metric->list, &devlink->metric_list); + devlink_metric_notify(devlink, metric, DEVLINK_CMD_METRIC_NEW); + + mutex_unlock(&devlink->lock); + + return metric; + +err_alloc_metric_name: + kfree(metric); +err_alloc_metric: +err_exists: + mutex_unlock(&devlink->lock); + return ERR_PTR(err); +} +EXPORT_SYMBOL_GPL(devlink_metric_counter_create); + +/** + * devlink_metric_destroy - Destroy metric. + * @devlink: devlink. + * @metric: Metric. + */ +void devlink_metric_destroy(struct devlink *devlink, + struct devlink_metric *metric) +{ + mutex_lock(&devlink->lock); + + devlink_metric_notify(devlink, metric, DEVLINK_CMD_METRIC_DEL); + list_del(&metric->list); + kfree(metric->name); + kfree(metric); + + mutex_unlock(&devlink->lock); +} +EXPORT_SYMBOL_GPL(devlink_metric_destroy); + static void __devlink_compat_running_version(struct devlink *devlink, char *buf, size_t len) { From patchwork Mon Aug 17 12:50:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ido Schimmel X-Patchwork-Id: 1346202 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=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=idosch.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.a=rsa-sha256 header.s=fm3 header.b=Hu/TDNFO; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4BVYqK1Kksz9sPB for ; Mon, 17 Aug 2020 22:52:42 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728505AbgHQMwl (ORCPT ); Mon, 17 Aug 2020 08:52:41 -0400 Received: from wnew3-smtp.messagingengine.com ([64.147.123.17]:55175 "EHLO wnew3-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728452AbgHQMwa (ORCPT ); Mon, 17 Aug 2020 08:52:30 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailnew.west.internal (Postfix) with ESMTP id C89B391A; Mon, 17 Aug 2020 08:52:28 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Mon, 17 Aug 2020 08:52:29 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=RZNNt95zD5BPj7e1BZG4LoynU6kgWATDWqYasbxe7es=; b=Hu/TDNFO s1bhBCLIol4zj8RhHk1V78AJnumcUzsrYdrbvCf1cF/MlRc36+O7d5uSUKeKzfGp tYm++DqWtbu6UM8AFQwti34OKgukfu9qUxKCVLmo6orJ7Yfwi43OnI6TlksfbixR LxU2Meao2qj0rzw1DvRdW2y4TvxyhNnyaQJ+3ervbdKC+R9UoClszyRKlpERYsTq P071ermpA3EaiixJmxzezIrf+27xNk49TtBiWklWTJVD0zeflY/WLFaTpM6HVqkt /bd1IXLf3g3H3UTusrPRvZkk9BRZwEfqTS81RFxjkoMYgyJwRUdOsmp2i6ezxm7G 0hiVt14jIRrV8Q== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduiedruddtfedgheeiucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefhvffufffkofgjfhgggfestdekre dtredttdenucfhrhhomhepkfguohcuufgthhhimhhmvghluceoihguohhstghhsehiugho shgthhdrohhrgheqnecuggftrfgrthhtvghrnhepudetieevffffveelkeeljeffkefhke ehgfdtffethfelvdejgffghefgveejkefhnecukfhppeejledrudekvddrieefrdegvden ucevlhhushhtvghrufhiiigvpedunecurfgrrhgrmhepmhgrihhlfhhrohhmpehiughosh gthhesihguohhstghhrdhorhhg X-ME-Proxy: Received: from localhost.localdomain (bzq-79-182-63-42.red.bezeqint.net [79.182.63.42]) by mail.messagingengine.com (Postfix) with ESMTPA id 64F9D306005F; Mon, 17 Aug 2020 08:52:16 -0400 (EDT) From: Ido Schimmel To: netdev@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, jiri@nvidia.com, amcohen@nvidia.com, danieller@nvidia.com, mlxsw@nvidia.com, roopa@nvidia.com, dsahern@gmail.com, andrew@lunn.ch, f.fainelli@gmail.com, vivien.didelot@gmail.com, saeedm@nvidia.com, tariqt@nvidia.com, ayal@nvidia.com, eranbe@nvidia.com, mkubecek@suse.cz, Ido Schimmel Subject: [RFC PATCH net-next 2/6] netdevsim: Add devlink metric support Date: Mon, 17 Aug 2020 15:50:55 +0300 Message-Id: <20200817125059.193242-3-idosch@idosch.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200817125059.193242-1-idosch@idosch.org> References: <20200817125059.193242-1-idosch@idosch.org> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Ido Schimmel Register a dummy counter with devlink that is incremented by one whenever queried. Allow the query to fail by writing to a file in debugfs so that error paths in the core infrastructure could be exercised. Signed-off-by: Amit Cohen Signed-off-by: Danielle Ratson Signed-off-by: Ido Schimmel --- drivers/net/netdevsim/dev.c | 92 ++++++++++++++++++++++++++++++- drivers/net/netdevsim/netdevsim.h | 1 + 2 files changed, 91 insertions(+), 2 deletions(-) diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c index 32f339fedb21..075d2d4e22a5 100644 --- a/drivers/net/netdevsim/dev.c +++ b/drivers/net/netdevsim/dev.c @@ -692,6 +692,81 @@ static void nsim_dev_traps_exit(struct devlink *devlink) kfree(nsim_dev->trap_data); } +struct nsim_metric_data { + struct devlink_metric *dummy_counter; + struct dentry *ddir; + u64 dummy_counter_value; + bool fail_counter_get; +}; + +static int nsim_dev_dummy_counter_get(struct devlink_metric *metric, u64 *p_val) +{ + struct nsim_dev *nsim_dev = devlink_metric_priv(metric); + u64 *cnt; + + if (nsim_dev->metric_data->fail_counter_get) + return -EINVAL; + + cnt = &nsim_dev->metric_data->dummy_counter_value; + *p_val = (*cnt)++; + + return 0; +} + +static const struct devlink_metric_ops nsim_dev_dummy_counter_ops = { + .counter_get = nsim_dev_dummy_counter_get, +}; + +static int nsim_dev_metric_init(struct nsim_dev *nsim_dev) +{ + struct devlink *devlink = priv_to_devlink(nsim_dev); + struct nsim_metric_data *nsim_metric_data; + struct devlink_metric *dummy_counter; + int err; + + nsim_metric_data = kzalloc(sizeof(*nsim_metric_data), GFP_KERNEL); + if (!nsim_metric_data) + return -ENOMEM; + nsim_dev->metric_data = nsim_metric_data; + + dummy_counter = devlink_metric_counter_create(devlink, "dummy_counter", + &nsim_dev_dummy_counter_ops, + nsim_dev); + if (IS_ERR(dummy_counter)) { + err = PTR_ERR(dummy_counter); + goto err_free_metric_data; + } + nsim_metric_data->dummy_counter = dummy_counter; + + nsim_metric_data->ddir = debugfs_create_dir("metric", nsim_dev->ddir); + if (IS_ERR(nsim_metric_data->ddir)) { + err = PTR_ERR(nsim_metric_data->ddir); + goto err_dummy_counter_destroy; + } + + nsim_metric_data->fail_counter_get = false; + debugfs_create_bool("fail_counter_get", 0600, nsim_metric_data->ddir, + &nsim_metric_data->fail_counter_get); + + return 0; + +err_dummy_counter_destroy: + devlink_metric_destroy(devlink, dummy_counter); +err_free_metric_data: + kfree(nsim_metric_data); + return err; +} + +static void nsim_dev_metric_exit(struct nsim_dev *nsim_dev) +{ + struct nsim_metric_data *nsim_metric_data = nsim_dev->metric_data; + struct devlink *devlink = priv_to_devlink(nsim_dev); + + debugfs_remove_recursive(nsim_metric_data->ddir); + devlink_metric_destroy(devlink, nsim_metric_data->dummy_counter); + kfree(nsim_metric_data); +} + static int nsim_dev_reload_create(struct nsim_dev *nsim_dev, struct netlink_ext_ack *extack); static void nsim_dev_reload_destroy(struct nsim_dev *nsim_dev); @@ -1008,10 +1083,14 @@ static int nsim_dev_reload_create(struct nsim_dev *nsim_dev, if (err) goto err_traps_exit; - err = nsim_dev_port_add_all(nsim_dev, nsim_bus_dev->port_count); + err = nsim_dev_metric_init(nsim_dev); if (err) goto err_health_exit; + err = nsim_dev_port_add_all(nsim_dev, nsim_bus_dev->port_count); + if (err) + goto err_metric_exit; + nsim_dev->take_snapshot = debugfs_create_file("take_snapshot", 0200, nsim_dev->ddir, @@ -1019,6 +1098,8 @@ static int nsim_dev_reload_create(struct nsim_dev *nsim_dev, &nsim_dev_take_snapshot_fops); return 0; +err_metric_exit: + nsim_dev_metric_exit(nsim_dev); err_health_exit: nsim_dev_health_exit(nsim_dev); err_traps_exit: @@ -1089,10 +1170,14 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev) if (err) goto err_debugfs_exit; - err = nsim_bpf_dev_init(nsim_dev); + err = nsim_dev_metric_init(nsim_dev); if (err) goto err_health_exit; + err = nsim_bpf_dev_init(nsim_dev); + if (err) + goto err_metric_exit; + err = nsim_dev_port_add_all(nsim_dev, nsim_bus_dev->port_count); if (err) goto err_bpf_dev_exit; @@ -1103,6 +1188,8 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev) err_bpf_dev_exit: nsim_bpf_dev_exit(nsim_dev); +err_metric_exit: + nsim_dev_metric_exit(nsim_dev); err_health_exit: nsim_dev_health_exit(nsim_dev); err_debugfs_exit: @@ -1133,6 +1220,7 @@ static void nsim_dev_reload_destroy(struct nsim_dev *nsim_dev) return; debugfs_remove(nsim_dev->take_snapshot); nsim_dev_port_del_all(nsim_dev); + nsim_dev_metric_exit(nsim_dev); nsim_dev_health_exit(nsim_dev); nsim_dev_traps_exit(devlink); nsim_dev_dummy_region_exit(nsim_dev); diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h index 284f7092241d..5f9a99bc4022 100644 --- a/drivers/net/netdevsim/netdevsim.h +++ b/drivers/net/netdevsim/netdevsim.h @@ -171,6 +171,7 @@ struct nsim_dev { struct nsim_bus_dev *nsim_bus_dev; struct nsim_fib_data *fib_data; struct nsim_trap_data *trap_data; + struct nsim_metric_data *metric_data; struct dentry *ddir; struct dentry *ports_ddir; struct dentry *take_snapshot; From patchwork Mon Aug 17 12:50:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ido Schimmel X-Patchwork-Id: 1346203 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=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=idosch.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.a=rsa-sha256 header.s=fm3 header.b=Um3/slVW; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4BVYqR09dTz9sTH for ; Mon, 17 Aug 2020 22:52:51 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728530AbgHQMwt (ORCPT ); Mon, 17 Aug 2020 08:52:49 -0400 Received: from wnew3-smtp.messagingengine.com ([64.147.123.17]:41735 "EHLO wnew3-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728460AbgHQMwn (ORCPT ); Mon, 17 Aug 2020 08:52:43 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailnew.west.internal (Postfix) with ESMTP id 848BC96C; Mon, 17 Aug 2020 08:52:41 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Mon, 17 Aug 2020 08:52:42 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=fVJ4PhELr1POP2qOa9FY1nLDgGLQSoP5u1WZrNPF3Po=; b=Um3/slVW 7Cs91YntXxX3JvMWtW2YLJ8dWLk19JP+4bgyFJiqug0QedSYCiECFYCvqF1pcRHx hUwjbQscJ9J12FMxcOLHTnJI3uWpHzItMu4Sfwf8xmUshBp25K1Dx0diZ4+eDFDn t0JHAXrFyHaLhpZRwp7e4mCRBHZ3+uTipQD4l+zJosprLYnpwlCY5/RNsx/B2kbz RUfECHAXvrSoSkat0aibcf/HtEWgwZKM0BQPiNu4CnaywtBxfNOo+LZl3O9/Vi9/ wU7vhXCe6S1dM64hcWKNZ59ow0S/PDLYaaeaLuM1eFi/RW9DefyMiX16Xn8f3ul6 M75u7h/xyNUpBA== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduiedruddtfedgheeiucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefhvffufffkofgjfhgggfestdekre dtredttdenucfhrhhomhepkfguohcuufgthhhimhhmvghluceoihguohhstghhsehiugho shgthhdrohhrgheqnecuggftrfgrthhtvghrnhepudetieevffffveelkeeljeffkefhke ehgfdtffethfelvdejgffghefgveejkefhnecukfhppeejledrudekvddrieefrdegvden ucevlhhushhtvghrufhiiigvpedvnecurfgrrhgrmhepmhgrihhlfhhrohhmpehiughosh gthhesihguohhstghhrdhorhhg X-ME-Proxy: Received: from localhost.localdomain (bzq-79-182-63-42.red.bezeqint.net [79.182.63.42]) by mail.messagingengine.com (Postfix) with ESMTPA id 4839630600A6; Mon, 17 Aug 2020 08:52:28 -0400 (EDT) From: Ido Schimmel To: netdev@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, jiri@nvidia.com, amcohen@nvidia.com, danieller@nvidia.com, mlxsw@nvidia.com, roopa@nvidia.com, dsahern@gmail.com, andrew@lunn.ch, f.fainelli@gmail.com, vivien.didelot@gmail.com, saeedm@nvidia.com, tariqt@nvidia.com, ayal@nvidia.com, eranbe@nvidia.com, mkubecek@suse.cz, Ido Schimmel Subject: [RFC PATCH net-next 3/6] selftests: netdevsim: Add devlink metric tests Date: Mon, 17 Aug 2020 15:50:56 +0300 Message-Id: <20200817125059.193242-4-idosch@idosch.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200817125059.193242-1-idosch@idosch.org> References: <20200817125059.193242-1-idosch@idosch.org> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Ido Schimmel Test the existing functionality of the devlink metric infrastructure. Tests will be added for any new functionality. Signed-off-by: Ido Schimmel --- .../networking/devlink/devlink-metric.rst | 11 +++++ .../drivers/net/netdevsim/devlink.sh | 49 ++++++++++++++++++- 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/Documentation/networking/devlink/devlink-metric.rst b/Documentation/networking/devlink/devlink-metric.rst index cf5c5b4e4077..8a4515df1bc0 100644 --- a/Documentation/networking/devlink/devlink-metric.rst +++ b/Documentation/networking/devlink/devlink-metric.rst @@ -24,3 +24,14 @@ driver-specific ``devlink`` documentation under When possible, a selftest (under ``tools/testing/selftests/drivers/``) should also be provided to ensure the metrics are updated under the right conditions. + +Testing +======= + +See ``tools/testing/selftests/drivers/net/netdevsim/devlink.sh`` for a +test covering the core infrastructure. Test cases should be added for any new +functionality. + +Device drivers should focus their tests on device-specific functionality, such +as making sure the exposed metrics are correctly incremented and read from the +device. diff --git a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh index de4b32fc4223..4ca345e227bc 100755 --- a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh +++ b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh @@ -5,7 +5,8 @@ lib_dir=$(dirname $0)/../../../net/forwarding ALL_TESTS="fw_flash_test params_test regions_test reload_test \ netns_reload_test resource_test dev_info_test \ - empty_reporter_test dummy_reporter_test" + empty_reporter_test dummy_reporter_test \ + metric_counter_test" NUM_NETIFS=0 source $lib_dir/lib.sh @@ -486,6 +487,52 @@ dummy_reporter_test() log_test "dummy reporter test" } +metric_counter_value_get() +{ + local metric=$1; shift + + cmd_jq "devlink -jps dev metric show $DL_HANDLE metric $metric" \ + '.[][][]["value"]' +} + +metric_group_get() +{ + local metric=$1; shift + + cmd_jq "devlink -jp dev metric show $DL_HANDLE metric $metric" \ + '.[][][]["group"]' +} + +metric_counter_test() +{ + RET=0 + + local val_t0=$(metric_counter_value_get dummy_counter) + local val_t1=$(metric_counter_value_get dummy_counter) + (( val_t0 < val_t1 )) + check_err $? "Expected to read a higher value in second read" + + echo "y" > $DEBUGFS_DIR/metric/fail_counter_get + metric_counter_value_get dummy_counter + check_fail $? "Unexpected success of counter get" + echo "n" > $DEBUGFS_DIR/metric/fail_counter_get + + devlink dev metric set $DL_HANDLE metric dummy_counter group 10 + + (( 10 == $(metric_group_get dummy_counter) )) + check_err $? "Expected \"dummy_counter\" to be in group 10" + + devlink dev metric show group 10 | grep -q "dummy_counter" + check_err $? "Expected \"dummy_counter\" to be dumped" + + devlink dev metric show group 20 | grep -q "dummy_counter" + check_fail $? "Did not expect to see \"dummy_counter\" in group 20" + + devlink dev metric set $DL_HANDLE metric dummy_counter group 0 + + log_test "metric counter test" +} + setup_prepare() { modprobe netdevsim From patchwork Mon Aug 17 12:50:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ido Schimmel X-Patchwork-Id: 1346204 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=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=idosch.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.a=rsa-sha256 header.s=fm3 header.b=awfjKvdn; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4BVYqX18dXz9sTH for ; Mon, 17 Aug 2020 22:52:56 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728540AbgHQMwz (ORCPT ); Mon, 17 Aug 2020 08:52:55 -0400 Received: from wnew3-smtp.messagingengine.com ([64.147.123.17]:53713 "EHLO wnew3-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728460AbgHQMwy (ORCPT ); Mon, 17 Aug 2020 08:52:54 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailnew.west.internal (Postfix) with ESMTP id BA6493CA; Mon, 17 Aug 2020 08:52:52 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Mon, 17 Aug 2020 08:52:53 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=9Yq33ndBPm2JTNKrE2BgBjBPYn1WEP/sFtVlS8Smhq0=; b=awfjKvdn sNkYpmmEApkoGjgvhXKuaDhZN06jPiCQR0mdqqvxEltVmlZ8/7tFurk2exhYBPCL UobOcGIs/117RuVLM64BsGdKVmp4v5R3c1QfjC9+vfGsaSe2VroRuiJJFqssAe+Z tV+D1f3vLf6Zsk9mZE9n08BJEzgBy3g6+svQKyGszqKnGPild73no9SHflhA42IU BqJMbPZ+lmiZLJ6KeI3VeIbMh9yJ7oXwoCdLUBaV7AVdPlV3/9OSHvqMclhOdxr4 lWkabrYjjlv/L123/3ri7l+Nvt3UvQVDR936aFVBbkv6GhHuOerq+hmuoc2h+WOt KF68sMCjmNQlWw== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduiedruddtfedgheeiucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefhvffufffkofgjfhgggfestdekre dtredttdenucfhrhhomhepkfguohcuufgthhhimhhmvghluceoihguohhstghhsehiugho shgthhdrohhrgheqnecuggftrfgrthhtvghrnhepudetieevffffveelkeeljeffkefhke ehgfdtffethfelvdejgffghefgveejkefhnecukfhppeejledrudekvddrieefrdegvden ucevlhhushhtvghrufhiiigvpeefnecurfgrrhgrmhepmhgrihhlfhhrohhmpehiughosh gthhesihguohhstghhrdhorhhg X-ME-Proxy: Received: from localhost.localdomain (bzq-79-182-63-42.red.bezeqint.net [79.182.63.42]) by mail.messagingengine.com (Postfix) with ESMTPA id CD2C03060067; Mon, 17 Aug 2020 08:52:41 -0400 (EDT) From: Ido Schimmel To: netdev@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, jiri@nvidia.com, amcohen@nvidia.com, danieller@nvidia.com, mlxsw@nvidia.com, roopa@nvidia.com, dsahern@gmail.com, andrew@lunn.ch, f.fainelli@gmail.com, vivien.didelot@gmail.com, saeedm@nvidia.com, tariqt@nvidia.com, ayal@nvidia.com, eranbe@nvidia.com, mkubecek@suse.cz, Ido Schimmel Subject: [RFC PATCH net-next 4/6] mlxsw: reg: Add Tunneling NVE Counters Register Date: Mon, 17 Aug 2020 15:50:57 +0300 Message-Id: <20200817125059.193242-5-idosch@idosch.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200817125059.193242-1-idosch@idosch.org> References: <20200817125059.193242-1-idosch@idosch.org> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Ido Schimmel The TNCR register exposes counters of NVE encapsulation and decapsulation on Spectrum-1. Signed-off-by: Amit Cohen Signed-off-by: Danielle Ratson Signed-off-by: Ido Schimmel --- drivers/net/ethernet/mellanox/mlxsw/reg.h | 51 +++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h index 079b080de7f7..9f19127caf83 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/reg.h +++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h @@ -10070,6 +10070,56 @@ static inline void mlxsw_reg_tngcr_pack(char *payload, mlxsw_reg_tngcr_nve_group_size_flood_set(payload, 1); } +/* TNCR - Tunneling NVE Counters Register + * -------------------------------------- + * The TNCR register exposes counters of NVE encapsulation and decapsulation. + * + * Note: Not supported by Spectrum-2 onwards. + */ +#define MLXSW_REG_TNCR_ID 0xA002 +#define MLXSW_REG_TNCR_LEN 0x30 + +MLXSW_REG_DEFINE(tncr, MLXSW_REG_TNCR_ID, MLXSW_REG_TNCR_LEN); + +/* reg_tncr_clear_counters + * Clear counters. + * Access: OP + */ +MLXSW_ITEM32(reg, tncr, clear_counters, 0x00, 31, 1); + +/* reg_tncr_count_encap + * Count number of packets which did encapsulation to an NVE tunnel. + * Access: RO + * + * Note: Multicast packets which are encapsulated multiple times are counted + * multiple times. + */ +MLXSW_ITEM64(reg, tncr, count_encap, 0x10, 0, 64); + +/* reg_tncr_count_decap + * Count number of packets which did decapsulation from an NVE tunnel. + * Access: RO + */ +MLXSW_ITEM64(reg, tncr, count_decap, 0x18, 0, 64); + +/* reg_tncr_count_decap_errors + * Count number of packets which had decapsulation errors from an NVE tunnel. + * Access: RO + */ +MLXSW_ITEM64(reg, tncr, count_decap_errors, 0x20, 0, 64); + +/* reg_tncr_count_decap_discards + * Count number of packets which had decapsulation discards from an NVE tunnel. + * Access: RO + */ +MLXSW_ITEM64(reg, tncr, count_decap_discards, 0x28, 0, 64); + +static inline void mlxsw_reg_tncr_pack(char *payload, bool clear_counters) +{ + MLXSW_REG_ZERO(tncr, payload); + mlxsw_reg_tncr_clear_counters_set(payload, clear_counters); +} + /* TNUMT - Tunneling NVE Underlay Multicast Table Register * ------------------------------------------------------- * The TNUMT register is for building the underlay MC table. It is used @@ -11001,6 +11051,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = { MLXSW_REG(mtptpt), MLXSW_REG(mgpir), MLXSW_REG(tngcr), + MLXSW_REG(tncr), MLXSW_REG(tnumt), MLXSW_REG(tnqcr), MLXSW_REG(tnqdr), From patchwork Mon Aug 17 12:50:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ido Schimmel X-Patchwork-Id: 1346205 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=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=idosch.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.a=rsa-sha256 header.s=fm3 header.b=C/cZorCy; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4BVYqm0B2Kz9sPB for ; Mon, 17 Aug 2020 22:53:08 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728555AbgHQMxH (ORCPT ); Mon, 17 Aug 2020 08:53:07 -0400 Received: from wnew3-smtp.messagingengine.com ([64.147.123.17]:51495 "EHLO wnew3-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728317AbgHQMxG (ORCPT ); Mon, 17 Aug 2020 08:53:06 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailnew.west.internal (Postfix) with ESMTP id 9643E3D4; Mon, 17 Aug 2020 08:53:04 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Mon, 17 Aug 2020 08:53:05 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=1y0pxL/D4napyzVCBXtQaBi7cF5gb039FBxvu0mwCDg=; b=C/cZorCy 8Yg0JYXYbuFOR+hzifEjHoDVqOghAGKu9TkB1NuOSsKIDXty39hjzDRe453ty/nL wD7WJj9iSr4WY33zaTXRJ6ZzWMyjce2wPQgqThNUlSkKu8ww9rvwtskQmSS3fuQG e3Udgfx7izK1WLAHusJpvtthU6M80DyThwAIRie2vv7nQ9fjs01lUCX+N0iK+6yv 7mOX7EaGM8Dr6+5BLSs9YfSoaBrlY4VT4uXAO1+iaGJuneTAmNe9eBJLRRNyjzI2 Md9irkCwCnkq0jLOV7/Lxr14viUWDeqvv/SnqrMOmCOMoUrHZREa+1mj1wF9ju4E aLzQkmPIYmYihA== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduiedruddtfedgheeiucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefhvffufffkofgjfhgggfestdekre dtredttdenucfhrhhomhepkfguohcuufgthhhimhhmvghluceoihguohhstghhsehiugho shgthhdrohhrgheqnecuggftrfgrthhtvghrnhepudetieevffffveelkeeljeffkefhke ehgfdtffethfelvdejgffghefgveejkefhnecukfhppeejledrudekvddrieefrdegvden ucevlhhushhtvghrufhiiigvpeegnecurfgrrhgrmhepmhgrihhlfhhrohhmpehiughosh gthhesihguohhstghhrdhorhhg X-ME-Proxy: Received: from localhost.localdomain (bzq-79-182-63-42.red.bezeqint.net [79.182.63.42]) by mail.messagingengine.com (Postfix) with ESMTPA id 3950030600A3; Mon, 17 Aug 2020 08:52:52 -0400 (EDT) From: Ido Schimmel To: netdev@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, jiri@nvidia.com, amcohen@nvidia.com, danieller@nvidia.com, mlxsw@nvidia.com, roopa@nvidia.com, dsahern@gmail.com, andrew@lunn.ch, f.fainelli@gmail.com, vivien.didelot@gmail.com, saeedm@nvidia.com, tariqt@nvidia.com, ayal@nvidia.com, eranbe@nvidia.com, mkubecek@suse.cz, Ido Schimmel Subject: [RFC PATCH net-next 5/6] mlxsw: reg: Add Tunneling NVE Counters Register Version 2 Date: Mon, 17 Aug 2020 15:50:58 +0300 Message-Id: <20200817125059.193242-6-idosch@idosch.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200817125059.193242-1-idosch@idosch.org> References: <20200817125059.193242-1-idosch@idosch.org> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Ido Schimmel The TNCR-V2 register exposes counters of NVE encapsulation and decapsulation on Spectrum-2 onwards. Signed-off-by: Amit Cohen Signed-off-by: Danielle Ratson Signed-off-by: Ido Schimmel --- drivers/net/ethernet/mellanox/mlxsw/reg.h | 53 +++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlxsw/reg.h b/drivers/net/ethernet/mellanox/mlxsw/reg.h index 9f19127caf83..c891fc590ddd 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/reg.h +++ b/drivers/net/ethernet/mellanox/mlxsw/reg.h @@ -10210,6 +10210,58 @@ static inline void mlxsw_reg_tnumt_pack(char *payload, mlxsw_reg_tnumt_record_size_set(payload, record_size); } +/* TNCR-V2 - Tunneling NVE Counters Register Version 2 + * --------------------------------------------------- + * The TNCR-V2 register exposes counters of NVE encapsulation and + * decapsulation. + * + * Note: Not supported by Spectrum-1. + */ +#define MLXSW_REG_TNCR2_ID 0xA004 +#define MLXSW_REG_TNCR2_LEN 0x38 + +MLXSW_REG_DEFINE(tncr2, MLXSW_REG_TNCR2_ID, MLXSW_REG_TNCR2_LEN); + +/* reg_tncr2_clear_counters + * Clear counters. + * Access: OP + */ +MLXSW_ITEM32(reg, tncr2, clear_counters, 0x00, 31, 1); + +enum mlxsw_reg_tncr2_tunnel_port { + MLXSW_REG_TNCR2_TUNNEL_PORT_NVE, + MLXSW_REG_TNCR2_TUNNEL_PORT_VPLS, + MLXSW_REG_TNCR2_TUNNEL_FLEX_TUNNEL0, + MLXSW_REG_TNCR2_TUNNEL_FLEX_TUNNEL1, +}; + +/* reg_tncr2_tunnel_port + * Tunnel port. + * Access: Index + */ +MLXSW_ITEM32(reg, tncr2, tunnel_port, 0x00, 0, 4); + +/* reg_tncr2_count_decap_discards + * Count number of packets which had decapsulation discards from an NVE tunnel. + * Access: RO + */ +MLXSW_ITEM64(reg, tncr2, count_decap_discards, 0x28, 0, 64); + +/* reg_tncr2_count_encap_discards + * Count number of packets which had encapsulation discards to an NVE tunnel. + * Access: RO + */ +MLXSW_ITEM64(reg, tncr2, count_encap_discards, 0x30, 0, 64); + +static inline void mlxsw_reg_tncr2_pack(char *payload, + enum mlxsw_reg_tncr2_tunnel_port tport, + bool clear_counters) +{ + MLXSW_REG_ZERO(tncr2, payload); + mlxsw_reg_tncr2_clear_counters_set(payload, clear_counters); + mlxsw_reg_tncr2_tunnel_port_set(payload, tport); +} + /* TNQCR - Tunneling NVE QoS Configuration Register * ------------------------------------------------ * The TNQCR register configures how QoS is set in encapsulation into the @@ -11053,6 +11105,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = { MLXSW_REG(tngcr), MLXSW_REG(tncr), MLXSW_REG(tnumt), + MLXSW_REG(tncr2), MLXSW_REG(tnqcr), MLXSW_REG(tnqdr), MLXSW_REG(tneem), From patchwork Mon Aug 17 12:50:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ido Schimmel X-Patchwork-Id: 1346206 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=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=idosch.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.a=rsa-sha256 header.s=fm3 header.b=AgjKSaC7; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4BVYr51zqCz9sPB for ; Mon, 17 Aug 2020 22:53:25 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728576AbgHQMxX (ORCPT ); Mon, 17 Aug 2020 08:53:23 -0400 Received: from wnew3-smtp.messagingengine.com ([64.147.123.17]:60951 "EHLO wnew3-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728563AbgHQMxW (ORCPT ); Mon, 17 Aug 2020 08:53:22 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailnew.west.internal (Postfix) with ESMTP id A6150714; Mon, 17 Aug 2020 08:53:20 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Mon, 17 Aug 2020 08:53:21 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=aVE32PImCPZl/J7SliC3bPsJtAIgs+EOzRaZs/BOa5Y=; b=AgjKSaC7 UeGqop4sA56GAB/7Ee/13ZxsoJRxaSjL2F0IBw3IVVwc291FtOjngnS9vTPjB/IL mROTSIvbqTy6VjmQcO2LLzYMqKh/62Pljvz8Xh0x1v/L5Z0/3HJvaTMuaq2dJMbi as6+8UmjQZUX+Ag67UL736M/0TmJO0RJn2oEBem/KR9dkdXu9umMaZyx4jG49Wpo jTu7MPIDBLZ/72JxeUvVX+a5fU/OrrUbLQWvHeHJKShj8KGpYeYio9NQZ2RyKige rk5O9PuNa11BWVHzz6bnY329XttEdn6J+KOuGtBviOH0+vehsex1ni0GiUJ+ahCT MFpN69jtM92rRg== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduiedruddtfedgheeiucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpefhvffufffkofgjfhgggfestdekre dtredttdenucfhrhhomhepkfguohcuufgthhhimhhmvghluceoihguohhstghhsehiugho shgthhdrohhrgheqnecuggftrfgrthhtvghrnhepudetieevffffveelkeeljeffkefhke ehgfdtffethfelvdejgffghefgveejkefhnecukfhppeejledrudekvddrieefrdegvden ucevlhhushhtvghrufhiiigvpeehnecurfgrrhgrmhepmhgrihhlfhhrohhmpehiughosh gthhesihguohhstghhrdhorhhg X-ME-Proxy: Received: from localhost.localdomain (bzq-79-182-63-42.red.bezeqint.net [79.182.63.42]) by mail.messagingengine.com (Postfix) with ESMTPA id 0DACA30600B1; Mon, 17 Aug 2020 08:53:04 -0400 (EDT) From: Ido Schimmel To: netdev@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, jiri@nvidia.com, amcohen@nvidia.com, danieller@nvidia.com, mlxsw@nvidia.com, roopa@nvidia.com, dsahern@gmail.com, andrew@lunn.ch, f.fainelli@gmail.com, vivien.didelot@gmail.com, saeedm@nvidia.com, tariqt@nvidia.com, ayal@nvidia.com, eranbe@nvidia.com, mkubecek@suse.cz, Ido Schimmel Subject: [RFC PATCH net-next 6/6] mlxsw: spectrum_nve: Expose VXLAN counters via devlink-metric Date: Mon, 17 Aug 2020 15:50:59 +0300 Message-Id: <20200817125059.193242-7-idosch@idosch.org> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200817125059.193242-1-idosch@idosch.org> References: <20200817125059.193242-1-idosch@idosch.org> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Ido Schimmel The Spectrum ASICs have a single hardware VTEP that is able to perform VXLAN encapsulation and decapsulation. The VTEP is logically mapped by mlxsw to the multiple VXLAN netdevs that are using it. Exposing the counters of this VTEP via the multiple VXLAN netdevs that are using it would be both inaccurate and confusing for users. Instead, expose the counters of the VTEP via devlink-metric. Note that Spectrum-1 supports a different set of counters compared to newer ASICs in the Spectrum family. Signed-off-by: Amit Cohen Signed-off-by: Danielle Ratson Signed-off-by: Ido Schimmel --- Documentation/networking/devlink/mlxsw.rst | 36 +++ .../ethernet/mellanox/mlxsw/spectrum_nve.h | 10 + .../mellanox/mlxsw/spectrum_nve_vxlan.c | 285 ++++++++++++++++++ 3 files changed, 331 insertions(+) diff --git a/Documentation/networking/devlink/mlxsw.rst b/Documentation/networking/devlink/mlxsw.rst index cf857cb4ba8f..5d95056a571a 100644 --- a/Documentation/networking/devlink/mlxsw.rst +++ b/Documentation/networking/devlink/mlxsw.rst @@ -79,3 +79,39 @@ Driver-specific Traps routed through a disabled router interface (RIF). This can happen during RIF dismantle, when the RIF is first disabled before being removed completely + +Metrics +======= + +.. list-table:: List of metrics registered by ``mlxsw`` + :widths: 5 5 20 70 + + * - Name + - Type + - Supported platforms + - Description + * - ``nve_vxlan_encap`` + - ``counter`` + - Spectrum-1 only + - Counts number of packets that were VXLAN encapsulated by the device. A + packet sent to multiple VTEPs is counted multiple times + * - ``nve_vxlan_decap`` + - ``counter`` + - Spectrum-1 only + - Counts number of VXLAN packets that were decapsulated (successfully or + otherwise) by the device + * - ``nve_vxlan_decap_errors`` + - ``counter`` + - Spectrum-1 only + - Counts number of VXLAN packets that encountered decapsulation errors. + This includes overlay packets with a VLAN tag, ECN mismatch between + overlay and underlay, multicast overlay source MAC, overlay source MAC + equals overlay destination MAC and packets too short to decapsulate + * - ``nve_vxlan_decap_discards`` + - ``counter`` + - All + - Counts number of VXLAN packets that were discarded during decapsulation. + In Spectrum-1 this includes packets that had to be VXLAN decapsulated + when VXLAN decapsulation is disabled and fragmented overlay packets. In + Spectrum-2 this includes ``nve_vxlan_decap_errors`` errors and a missing + mapping between VNI and filtering identifier (FID) diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_nve.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_nve.h index 12f664f42f21..249adea4d547 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_nve.h +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_nve.h @@ -6,6 +6,7 @@ #include #include +#include #include "spectrum.h" @@ -20,10 +21,19 @@ struct mlxsw_sp_nve_config { union mlxsw_sp_l3addr ul_sip; }; +struct mlxsw_sp_nve_metrics { + struct devlink_metric *counter_encap; + struct devlink_metric *counter_decap; + struct devlink_metric *counter_decap_errors; + struct devlink_metric *counter_decap_discards; + struct devlink_metric *counter_encap_discards; +}; + struct mlxsw_sp_nve { struct mlxsw_sp_nve_config config; struct rhashtable mc_list_ht; struct mlxsw_sp *mlxsw_sp; + struct mlxsw_sp_nve_metrics metrics; const struct mlxsw_sp_nve_ops **nve_ops_arr; unsigned int num_nve_tunnels; /* Protected by RTNL */ unsigned int num_max_mc_entries[MLXSW_SP_L3_PROTO_MAX]; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_nve_vxlan.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_nve_vxlan.c index 05517c7feaa5..7b71fecb3b96 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_nve_vxlan.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_nve_vxlan.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include "reg.h" @@ -220,6 +221,173 @@ static int mlxsw_sp1_nve_vxlan_rtdp_set(struct mlxsw_sp *mlxsw_sp, return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rtdp), rtdp_pl); } +static int +mlxsw_sp1_nve_vxlan_common_counter_get(struct devlink_metric *metric, + char *tncr_pl) +{ + struct mlxsw_sp *mlxsw_sp = devlink_metric_priv(metric); + + mlxsw_reg_tncr_pack(tncr_pl, false); + + return mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(tncr), tncr_pl); +} + +static int +mlxsw_sp1_nve_vxlan_encap_counter_get(struct devlink_metric *metric, + u64 *p_val) +{ + char tncr_pl[MLXSW_REG_TNCR_LEN]; + int err; + + err = mlxsw_sp1_nve_vxlan_common_counter_get(metric, tncr_pl); + if (err) + return err; + + *p_val = mlxsw_reg_tncr_count_encap_get(tncr_pl); + + return 0; +} + +static const struct devlink_metric_ops mlxsw_sp1_nve_vxlan_encap_ops = { + .counter_get = mlxsw_sp1_nve_vxlan_encap_counter_get, +}; + +static int +mlxsw_sp1_nve_vxlan_decap_counter_get(struct devlink_metric *metric, + u64 *p_val) +{ + char tncr_pl[MLXSW_REG_TNCR_LEN]; + int err; + + err = mlxsw_sp1_nve_vxlan_common_counter_get(metric, tncr_pl); + if (err) + return err; + + *p_val = mlxsw_reg_tncr_count_decap_get(tncr_pl); + + return 0; +} + +static const struct devlink_metric_ops mlxsw_sp1_nve_vxlan_decap_ops = { + .counter_get = mlxsw_sp1_nve_vxlan_decap_counter_get, +}; + +static int +mlxsw_sp1_nve_vxlan_decap_errors_counter_get(struct devlink_metric *metric, + u64 *p_val) +{ + char tncr_pl[MLXSW_REG_TNCR_LEN]; + int err; + + err = mlxsw_sp1_nve_vxlan_common_counter_get(metric, tncr_pl); + if (err) + return err; + + *p_val = mlxsw_reg_tncr_count_decap_errors_get(tncr_pl); + + return 0; +} + +static const struct devlink_metric_ops mlxsw_sp1_nve_vxlan_decap_errors_ops = { + .counter_get = mlxsw_sp1_nve_vxlan_decap_errors_counter_get, +}; + +static int +mlxsw_sp1_nve_vxlan_decap_discards_counter_get(struct devlink_metric *metric, + u64 *p_val) +{ + char tncr_pl[MLXSW_REG_TNCR_LEN]; + int err; + + err = mlxsw_sp1_nve_vxlan_common_counter_get(metric, tncr_pl); + if (err) + return err; + + *p_val = mlxsw_reg_tncr_count_decap_discards_get(tncr_pl); + + return 0; +} + +static const struct devlink_metric_ops mlxsw_sp1_nve_vxlan_decap_discards_ops = { + .counter_get = mlxsw_sp1_nve_vxlan_decap_discards_counter_get, +}; + +static int mlxsw_sp1_nve_vxlan_counters_clear(struct mlxsw_sp *mlxsw_sp) +{ + char tncr_pl[MLXSW_REG_TNCR_LEN]; + + mlxsw_reg_tncr_pack(tncr_pl, true); + + /* Clear operation is implemented on query. */ + return mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(tncr), tncr_pl); +} + +static int mlxsw_sp1_nve_vxlan_metrics_init(struct mlxsw_sp *mlxsw_sp) +{ + struct mlxsw_sp_nve_metrics *metrics = &mlxsw_sp->nve->metrics; + struct devlink *devlink = priv_to_devlink(mlxsw_sp->core); + int err; + + err = mlxsw_sp1_nve_vxlan_counters_clear(mlxsw_sp); + if (err) + return err; + + metrics->counter_encap = + devlink_metric_counter_create(devlink, "nve_vxlan_encap", + &mlxsw_sp1_nve_vxlan_encap_ops, + mlxsw_sp); + if (IS_ERR(metrics->counter_encap)) + return PTR_ERR(metrics->counter_encap); + + metrics->counter_decap = + devlink_metric_counter_create(devlink, "nve_vxlan_decap", + &mlxsw_sp1_nve_vxlan_decap_ops, + mlxsw_sp); + if (IS_ERR(metrics->counter_decap)) { + err = PTR_ERR(metrics->counter_decap); + goto err_counter_decap; + } + + metrics->counter_decap_errors = + devlink_metric_counter_create(devlink, "nve_vxlan_decap_errors", + &mlxsw_sp1_nve_vxlan_decap_errors_ops, + mlxsw_sp); + if (IS_ERR(metrics->counter_decap_errors)) { + err = PTR_ERR(metrics->counter_decap_errors); + goto err_counter_decap_errors; + } + + metrics->counter_decap_discards = + devlink_metric_counter_create(devlink, "nve_vxlan_decap_discards", + &mlxsw_sp1_nve_vxlan_decap_discards_ops, + mlxsw_sp); + if (IS_ERR(metrics->counter_decap_discards)) { + err = PTR_ERR(metrics->counter_decap_discards); + goto err_counter_decap_discards; + } + + return 0; + +err_counter_decap_discards: + devlink_metric_destroy(devlink, metrics->counter_decap_errors); +err_counter_decap_errors: + devlink_metric_destroy(devlink, metrics->counter_decap); +err_counter_decap: + devlink_metric_destroy(devlink, metrics->counter_encap); + return err; +} + +static void mlxsw_sp1_nve_vxlan_metrics_fini(struct mlxsw_sp *mlxsw_sp) +{ + struct mlxsw_sp_nve_metrics *metrics = &mlxsw_sp->nve->metrics; + struct devlink *devlink = priv_to_devlink(mlxsw_sp->core); + + devlink_metric_destroy(devlink, metrics->counter_decap_discards); + devlink_metric_destroy(devlink, metrics->counter_decap_errors); + devlink_metric_destroy(devlink, metrics->counter_decap); + devlink_metric_destroy(devlink, metrics->counter_encap); +} + static int mlxsw_sp1_nve_vxlan_init(struct mlxsw_sp_nve *nve, const struct mlxsw_sp_nve_config *config) { @@ -238,6 +406,10 @@ static int mlxsw_sp1_nve_vxlan_init(struct mlxsw_sp_nve *nve, if (err) goto err_rtdp_set; + err = mlxsw_sp1_nve_vxlan_metrics_init(mlxsw_sp); + if (err) + goto err_metrics_init; + err = mlxsw_sp_router_nve_promote_decap(mlxsw_sp, config->ul_tb_id, config->ul_proto, &config->ul_sip, @@ -248,6 +420,8 @@ static int mlxsw_sp1_nve_vxlan_init(struct mlxsw_sp_nve *nve, return 0; err_promote_decap: + mlxsw_sp1_nve_vxlan_metrics_fini(mlxsw_sp); +err_metrics_init: err_rtdp_set: mlxsw_sp1_nve_vxlan_config_clear(mlxsw_sp); err_config_set: @@ -262,6 +436,7 @@ static void mlxsw_sp1_nve_vxlan_fini(struct mlxsw_sp_nve *nve) mlxsw_sp_router_nve_demote_decap(mlxsw_sp, config->ul_tb_id, config->ul_proto, &config->ul_sip); + mlxsw_sp1_nve_vxlan_metrics_fini(mlxsw_sp); mlxsw_sp1_nve_vxlan_config_clear(mlxsw_sp); __mlxsw_sp_nve_inc_parsing_depth_put(mlxsw_sp, 0); } @@ -360,6 +535,109 @@ static int mlxsw_sp2_nve_vxlan_rtdp_set(struct mlxsw_sp *mlxsw_sp, return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rtdp), rtdp_pl); } +static int +mlxsw_sp2_nve_vxlan_common_counter_get(struct devlink_metric *metric, + char *tncr2_pl) +{ + struct mlxsw_sp *mlxsw_sp = devlink_metric_priv(metric); + + mlxsw_reg_tncr2_pack(tncr2_pl, MLXSW_REG_TNCR2_TUNNEL_PORT_NVE, false); + + return mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(tncr2), tncr2_pl); +} + +static int +mlxsw_sp2_nve_vxlan_decap_discards_counter_get(struct devlink_metric *metric, + u64 *p_val) +{ + char tncr2_pl[MLXSW_REG_TNCR2_LEN]; + int err; + + err = mlxsw_sp2_nve_vxlan_common_counter_get(metric, tncr2_pl); + if (err) + return err; + + *p_val = mlxsw_reg_tncr2_count_decap_discards_get(tncr2_pl); + + return 0; +} + +static const struct devlink_metric_ops mlxsw_sp2_nve_vxlan_decap_discards_ops = { + .counter_get = mlxsw_sp2_nve_vxlan_decap_discards_counter_get, +}; + +static int +mlxsw_sp2_nve_vxlan_encap_discards_counter_get(struct devlink_metric *metric, + u64 *p_val) +{ + char tncr2_pl[MLXSW_REG_TNCR2_LEN]; + int err; + + err = mlxsw_sp2_nve_vxlan_common_counter_get(metric, tncr2_pl); + if (err) + return err; + + *p_val = mlxsw_reg_tncr2_count_encap_discards_get(tncr2_pl); + + return 0; +} + +static const struct devlink_metric_ops mlxsw_sp2_nve_vxlan_encap_discards_ops = { + .counter_get = mlxsw_sp2_nve_vxlan_encap_discards_counter_get, +}; + +static int mlxsw_sp2_nve_vxlan_counters_clear(struct mlxsw_sp *mlxsw_sp) +{ + char tncr2_pl[MLXSW_REG_TNCR2_LEN]; + + mlxsw_reg_tncr2_pack(tncr2_pl, MLXSW_REG_TNCR2_TUNNEL_PORT_NVE, true); + + /* Clear operation is implemented on query. */ + return mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(tncr2), tncr2_pl); +} + +static int mlxsw_sp2_nve_vxlan_metrics_init(struct mlxsw_sp *mlxsw_sp) +{ + struct mlxsw_sp_nve_metrics *metrics = &mlxsw_sp->nve->metrics; + struct devlink *devlink = priv_to_devlink(mlxsw_sp->core); + int err; + + err = mlxsw_sp2_nve_vxlan_counters_clear(mlxsw_sp); + if (err) + return err; + + metrics->counter_decap_discards = + devlink_metric_counter_create(devlink, "nve_vxlan_decap_discards", + &mlxsw_sp2_nve_vxlan_decap_discards_ops, + mlxsw_sp); + if (IS_ERR(metrics->counter_decap_discards)) + return PTR_ERR(metrics->counter_decap_discards); + + metrics->counter_encap_discards = + devlink_metric_counter_create(devlink, "nve_vxlan_encap_discards", + &mlxsw_sp2_nve_vxlan_encap_discards_ops, + mlxsw_sp); + if (IS_ERR(metrics->counter_encap_discards)) { + err = PTR_ERR(metrics->counter_encap_discards); + goto err_counter_encap_discards; + } + + return 0; + +err_counter_encap_discards: + devlink_metric_destroy(devlink, metrics->counter_decap_discards); + return err; +} + +static void mlxsw_sp2_nve_vxlan_metrics_fini(struct mlxsw_sp *mlxsw_sp) +{ + struct mlxsw_sp_nve_metrics *metrics = &mlxsw_sp->nve->metrics; + struct devlink *devlink = priv_to_devlink(mlxsw_sp->core); + + devlink_metric_destroy(devlink, metrics->counter_encap_discards); + devlink_metric_destroy(devlink, metrics->counter_decap_discards); +} + static int mlxsw_sp2_nve_vxlan_init(struct mlxsw_sp_nve *nve, const struct mlxsw_sp_nve_config *config) { @@ -379,6 +657,10 @@ static int mlxsw_sp2_nve_vxlan_init(struct mlxsw_sp_nve *nve, if (err) goto err_rtdp_set; + err = mlxsw_sp2_nve_vxlan_metrics_init(mlxsw_sp); + if (err) + goto err_metrics_init; + err = mlxsw_sp_router_nve_promote_decap(mlxsw_sp, config->ul_tb_id, config->ul_proto, &config->ul_sip, @@ -389,6 +671,8 @@ static int mlxsw_sp2_nve_vxlan_init(struct mlxsw_sp_nve *nve, return 0; err_promote_decap: + mlxsw_sp2_nve_vxlan_metrics_fini(mlxsw_sp); +err_metrics_init: err_rtdp_set: mlxsw_sp2_nve_vxlan_config_clear(mlxsw_sp); err_config_set: @@ -403,6 +687,7 @@ static void mlxsw_sp2_nve_vxlan_fini(struct mlxsw_sp_nve *nve) mlxsw_sp_router_nve_demote_decap(mlxsw_sp, config->ul_tb_id, config->ul_proto, &config->ul_sip); + mlxsw_sp2_nve_vxlan_metrics_fini(mlxsw_sp); mlxsw_sp2_nve_vxlan_config_clear(mlxsw_sp); __mlxsw_sp_nve_inc_parsing_depth_put(mlxsw_sp, 0); }