All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vikas Gupta <vikas.gupta@broadcom.com>
To: jiri@nvidia.com, kuba@kernel.org
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	davem@davemloft.net, dsahern@kernel.org,
	stephen@networkplumber.org, edumazet@google.com,
	michael.chan@broadcom.com, andrew.gospodarek@broadcom.com,
	Vikas Gupta <vikas.gupta@broadcom.com>
Subject: [PATCH net-next v1 1/3] devlink: introduce framework for selftests
Date: Tue, 28 Jun 2022 22:12:39 +0530	[thread overview]
Message-ID: <20220628164241.44360-2-vikas.gupta@broadcom.com> (raw)
In-Reply-To: <20220628164241.44360-1-vikas.gupta@broadcom.com>

[-- Attachment #1: Type: text/plain, Size: 10400 bytes --]

Add a framework for running selftests.
Framework exposes devlink commands and test suite(s) to the user
to execute and query the supported tests by the driver.

To execute tests, users can provide a test mask for executing
group tests or standalone tests. API devlink_selftest_result_put() helps
drivers to populate the test results along with their names.

To query supported tests by device, API devlink_selftest_name_put()
helps a driver to populate test names.

Signed-off-by: Vikas Gupta <vikas.gupta@broadcom.com>
Reviewed-by: Michael Chan <michael.chan@broadcom.com>
Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
---
 .../networking/devlink/devlink-selftests.rst  |  39 +++++
 include/net/devlink.h                         |  40 +++++
 include/uapi/linux/devlink.h                  |  24 +++
 net/core/devlink.c                            | 147 ++++++++++++++++++
 4 files changed, 250 insertions(+)
 create mode 100644 Documentation/networking/devlink/devlink-selftests.rst

diff --git a/Documentation/networking/devlink/devlink-selftests.rst b/Documentation/networking/devlink/devlink-selftests.rst
new file mode 100644
index 000000000000..df7c8fcac9bf
--- /dev/null
+++ b/Documentation/networking/devlink/devlink-selftests.rst
@@ -0,0 +1,39 @@
+.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+.. _devlink_selftests:
+
+=================
+Devlink Selftests
+=================
+
+The ``devlink-selftests`` API allows executing selftests on the device.
+
+Tests Mask
+==========
+The ``devlink-selftests`` command should be run with a mask indicating
+the tests to be executed.
+
+Tests Description
+=================
+The following is a list of tests that drivers may execute.
+
+.. list-table:: List of tests
+   :widths: 5 90
+
+   * - Name
+     - Description
+   * - ``DEVLINK_SELFTEST_FLASH``
+     - Runs a flash test on the device which helps to log the health of the flash.
+       see Documentation/networking/devlink/devlink-health.rst
+
+example usage
+-------------
+
+.. code:: shell
+
+    # Query selftests supported on the device
+    $ devlink dev selftests show DEV
+    # Executes selftests on the device
+    $ devlink dev selftests run DEV test {flash | all}
+
+
diff --git a/include/net/devlink.h b/include/net/devlink.h
index 2a2a2a0c93f7..493dab368340 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -1215,6 +1215,19 @@ enum {
 	DEVLINK_F_RELOAD = 1UL << 0,
 };
 
+/**
+ * struct devlink_selftest_exec_info - Devlink selftest execution info.
+ * @name: Test name.
+ * @result: Test result.
+ */
+struct devlink_selftest_exec_info {
+	const char *name;
+	bool result;
+};
+
+#define DEVLINK_SELFTEST_FLASH_TEST_NAME \
+	"flash test"
+
 struct devlink_ops {
 	/**
 	 * @supported_flash_update_params:
@@ -1509,6 +1522,28 @@ struct devlink_ops {
 				    struct devlink_rate *parent,
 				    void *priv_child, void *priv_parent,
 				    struct netlink_ext_ack *extack);
+	/**
+	 * selftests_show() - Shows selftests supported by device
+	 * @devlink: Devlink instance
+	 * @skb: message payload
+	 * @extack: extack for reporting error messages
+	 *
+	 * Return: 0 on success, negative value otherwise.
+	 */
+
+	int (*selftests_show)(struct devlink *devlink, struct sk_buff *skb,
+			      struct netlink_ext_ack *extack);
+	/**
+	 * selftests_run() - Runs selftests
+	 * @devlink: Devlink instance
+	 * @skb: message payload
+	 * @tests_mask: tests to be run
+	 * @extack: extack for reporting error messages
+	 *
+	 * Return: 0 on success, negative value otherwise.
+	 */
+	int (*selftests_run)(struct devlink *devlink, struct sk_buff *skb,
+			     u32 tests_mask, struct netlink_ext_ack *extack);
 };
 
 void *devlink_priv(struct devlink *devlink);
@@ -1774,6 +1809,11 @@ void
 devlink_trap_policers_unregister(struct devlink *devlink,
 				 const struct devlink_trap_policer *policers,
 				 size_t policers_count);
+int
+devlink_selftest_result_put(struct sk_buff *skb,
+			    struct devlink_selftest_exec_info *test);
+int
+devlink_selftest_name_put(struct sk_buff *skb, const char *name);
 
 #if IS_ENABLED(CONFIG_NET_DEVLINK)
 
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index b3d40a5d72ff..58e2ef4010f0 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -136,6 +136,9 @@ enum devlink_command {
 	DEVLINK_CMD_LINECARD_NEW,
 	DEVLINK_CMD_LINECARD_DEL,
 
+	DEVLINK_CMD_SELFTESTS_SHOW,
+	DEVLINK_CMD_SELFTESTS_RUN,
+
 	/* add new commands above here */
 	__DEVLINK_CMD_MAX,
 	DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1
@@ -276,6 +279,21 @@ enum {
 #define DEVLINK_SUPPORTED_FLASH_OVERWRITE_SECTIONS \
 	(_BITUL(__DEVLINK_FLASH_OVERWRITE_MAX_BIT) - 1)
 
+/* Commonly used test cases. Drivers might interpret test bit
+ * in their own way and it may map single to multiple tests.
+ */
+enum {
+	DEVLINK_SELFTEST_FLASH_BIT,
+
+	__DEVLINK_SELFTEST_MAX_BIT,
+	DEVLINK_SELFTEST_MAX_BIT = __DEVLINK_SELFTEST_MAX_BIT - 1
+};
+
+#define DEVLINK_SELFTEST_FLASH _BITUL(DEVLINK_SELFTEST_FLASH_BIT)
+
+#define DEVLINK_SUPPORTED_SELFTESTS \
+	(_BITUL(__DEVLINK_SELFTEST_MAX_BIT) - 1)
+
 /**
  * enum devlink_trap_action - Packet trap action.
  * @DEVLINK_TRAP_ACTION_DROP: Packet is dropped by the device and a copy is not
@@ -576,6 +594,12 @@ enum devlink_attr {
 	DEVLINK_ATTR_LINECARD_TYPE,		/* string */
 	DEVLINK_ATTR_LINECARD_SUPPORTED_TYPES,	/* nested */
 
+	DEVLINK_ATTR_SELFTESTS_MASK,		/* bitfield32 */
+	DEVLINK_ATTR_TEST_NAMES,		/* nested */
+	DEVLINK_ATTR_TEST_NAME,			/* string */
+	DEVLINK_ATTR_TEST_RESULTS,		/* nested */
+	DEVLINK_ATTR_TEST_RESULT,		/* nested */
+	DEVLINK_ATTR_TEST_RESULT_VAL,		/* u8 */
 	/* 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 db61f3a341cb..3c4c27a7dd40 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -4794,6 +4794,139 @@ static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
 	return ret;
 }
 
+int devlink_selftest_name_put(struct sk_buff *skb, const char *name)
+{
+	if (nla_put_string(skb, DEVLINK_ATTR_TEST_NAME, name))
+		return -EMSGSIZE;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(devlink_selftest_name_put);
+
+static int devlink_nl_cmd_selftests_show(struct sk_buff *skb,
+					 struct genl_info *info)
+{
+	struct devlink *devlink = info->user_ptr[0];
+	struct nlattr  *names_attr;
+	struct sk_buff *msg;
+	void *hdr;
+	int err;
+
+	if (!devlink->ops->selftests_show)
+		return -EOPNOTSUPP;
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!msg)
+		return -ENOMEM;
+
+	hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq,
+			  &devlink_nl_family, 0, DEVLINK_CMD_SELFTESTS_SHOW);
+	if (!hdr)
+		return -EMSGSIZE;
+
+	if (devlink_nl_put_handle(msg, devlink))
+		goto genlmsg_cancel;
+
+	names_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_TEST_NAMES);
+	if (!names_attr)
+		goto genlmsg_cancel;
+
+	err =  devlink->ops->selftests_show(devlink, msg, info->extack);
+	if (err)
+		goto names_nest_cancel;
+
+	nla_nest_end(msg, names_attr);
+	genlmsg_end(msg, hdr);
+
+	return genlmsg_reply(msg, info);
+
+names_nest_cancel:
+	nla_nest_cancel(msg, names_attr);
+genlmsg_cancel:
+	genlmsg_cancel(msg, hdr);
+	nlmsg_free(msg);
+	return err;
+}
+
+int devlink_selftest_result_put(struct sk_buff *skb,
+				struct devlink_selftest_exec_info *test)
+{
+	struct nlattr *result_attr;
+
+	result_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_TEST_RESULT);
+	if (!result_attr)
+		return -EMSGSIZE;
+
+	if (nla_put_string(skb, DEVLINK_ATTR_TEST_NAME, test->name) ||
+	    nla_put_u8(skb, DEVLINK_ATTR_TEST_RESULT_VAL, test->result))
+		goto nla_put_failure;
+
+	nla_nest_end(skb, result_attr);
+	return 0;
+
+nla_put_failure:
+	nla_nest_cancel(skb, result_attr);
+	return -EMSGSIZE;
+}
+EXPORT_SYMBOL_GPL(devlink_selftest_result_put);
+
+static int devlink_nl_cmd_selftests_run(struct sk_buff *skb,
+					struct genl_info *info)
+{
+	struct devlink *devlink = info->user_ptr[0];
+	struct nlattr  *nla_selftests_mask;
+	struct nlattr  *results_attr;
+	struct nla_bitfield32 tests;
+	struct sk_buff *msg;
+	u32 tests_mask;
+	void *hdr;
+	int err;
+
+	if (!devlink->ops->selftests_run)
+		return -EOPNOTSUPP;
+
+	if (!info->attrs[DEVLINK_ATTR_SELFTESTS_MASK])
+		return -EINVAL;
+
+	nla_selftests_mask = info->attrs[DEVLINK_ATTR_SELFTESTS_MASK];
+
+	tests = nla_get_bitfield32(nla_selftests_mask);
+	tests_mask = tests.value & tests.selector;
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!msg)
+		return -ENOMEM;
+
+	hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq,
+			  &devlink_nl_family, 0, DEVLINK_CMD_SELFTESTS_RUN);
+	if (!hdr)
+		return -EMSGSIZE;
+
+	if (devlink_nl_put_handle(msg, devlink))
+		goto genlmsg_cancel;
+
+	results_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_TEST_RESULTS);
+	if (!results_attr)
+		goto genlmsg_cancel;
+
+	err =  devlink->ops->selftests_run(devlink, msg, tests_mask,
+					   info->extack);
+	if (err)
+		goto results_nest_cancel;
+
+	nla_nest_end(msg, results_attr);
+	genlmsg_end(msg, hdr);
+
+	return genlmsg_reply(msg, info);
+
+results_nest_cancel:
+	nla_nest_cancel(msg, results_attr);
+genlmsg_cancel:
+	genlmsg_cancel(msg, hdr);
+	nlmsg_free(msg);
+	return err;
+}
+
 static const struct devlink_param devlink_param_generic[] = {
 	{
 		.id = DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET,
@@ -9000,6 +9133,8 @@ static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
 	[DEVLINK_ATTR_RATE_PARENT_NODE_NAME] = { .type = NLA_NUL_STRING },
 	[DEVLINK_ATTR_LINECARD_INDEX] = { .type = NLA_U32 },
 	[DEVLINK_ATTR_LINECARD_TYPE] = { .type = NLA_NUL_STRING },
+	[DEVLINK_ATTR_SELFTESTS_MASK] =
+		NLA_POLICY_BITFIELD32(DEVLINK_SUPPORTED_SELFTESTS),
 };
 
 static const struct genl_small_ops devlink_nl_ops[] = {
@@ -9361,6 +9496,18 @@ static const struct genl_small_ops devlink_nl_ops[] = {
 		.doit = devlink_nl_cmd_trap_policer_set_doit,
 		.flags = GENL_ADMIN_PERM,
 	},
+	{
+		.cmd = DEVLINK_CMD_SELFTESTS_SHOW,
+		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
+		.doit = devlink_nl_cmd_selftests_show,
+		.flags = GENL_ADMIN_PERM,
+	},
+	{
+		.cmd = DEVLINK_CMD_SELFTESTS_RUN,
+		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
+		.doit = devlink_nl_cmd_selftests_run,
+		.flags = GENL_ADMIN_PERM,
+	},
 };
 
 static struct genl_family devlink_nl_family __ro_after_init = {
-- 
2.31.1


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4206 bytes --]

  reply	other threads:[~2022-06-28 16:47 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-28 16:42 [PATCH net-next v1 0/3] add framework for selftests in devlink Vikas Gupta
2022-06-28 16:42 ` Vikas Gupta [this message]
2022-06-29  5:05   ` [PATCH net-next v1 1/3] devlink: introduce framework for selftests Jakub Kicinski
2022-06-28 16:42 ` [PATCH net-next v1 2/3] bnxt_en: refactor NVM APIs Vikas Gupta
2022-06-28 16:42 ` [PATCH net-next v1 3/3] bnxt_en: implement callbacks for devlink selftests Vikas Gupta
2022-07-07 18:29 ` [PATCH net-next v2 0/3] add framework for selftests in devlink Vikas Gupta
2022-07-07 18:29   ` [PATCH net-next v2 1/3] devlink: introduce framework for selftests Vikas Gupta
2022-07-08  1:20     ` Jakub Kicinski
2022-07-10  9:00       ` Ido Schimmel
2022-07-08  8:04     ` kernel test robot
2022-07-08 14:48     ` kernel test robot
2022-07-11 12:40     ` Jiri Pirko
     [not found]       ` <CAHLZf_t9ihOQPvcQa8cZsDDVUX1wisrBjC30tHG_-Dz13zg=qQ@mail.gmail.com>
2022-07-12  6:28         ` Jiri Pirko
2022-07-12 16:41           ` Vikas Gupta
2022-07-12 18:08             ` Jiri Pirko
2022-07-13  6:40               ` Vikas Gupta
2022-07-13  7:28                 ` Jiri Pirko
2022-07-13 10:16                   ` Vikas Gupta
2022-07-13 10:22                     ` Jiri Pirko
2022-07-07 18:29   ` [PATCH net-next v2 2/3] bnxt_en: refactor NVM APIs Vikas Gupta
2022-07-07 18:29   ` [PATCH net-next v2 3/3] bnxt_en: implement callbacks for devlink selftests Vikas Gupta

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220628164241.44360-2-vikas.gupta@broadcom.com \
    --to=vikas.gupta@broadcom.com \
    --cc=andrew.gospodarek@broadcom.com \
    --cc=davem@davemloft.net \
    --cc=dsahern@kernel.org \
    --cc=edumazet@google.com \
    --cc=jiri@nvidia.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=michael.chan@broadcom.com \
    --cc=netdev@vger.kernel.org \
    --cc=stephen@networkplumber.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.