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,
pabeni@redhat.com, ast@kernel.org, leon@kernel.org,
linux-doc@vger.kernel.org, corbet@lwn.net,
michael.chan@broadcom.com, andrew.gospodarek@broadcom.com,
Vikas Gupta <vikas.gupta@broadcom.com>
Subject: [PATCH net-next v3 1/3] devlink: introduce framework for selftests
Date: Mon, 18 Jul 2022 11:50:30 +0530 [thread overview]
Message-ID: <20220718062032.22426-2-vikas.gupta@broadcom.com> (raw)
In-Reply-To: <20220718062032.22426-1-vikas.gupta@broadcom.com>
[-- Attachment #1: Type: text/plain, Size: 11449 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.
Below are new entries in devlink_nl_ops
devlink_nl_cmd_selftests_list_doit/dumpit: To query the supported
selftests by the drivers.
devlink_nl_cmd_selftests_run: To execute selftests. Users can
provide a test mask for executing group tests or standalone tests.
Documentation/networking/devlink/ path is already part of MAINTAINERS &
the new files come under this path. Hence no update needed to the
MAINTAINERS
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 | 38 +++
include/net/devlink.h | 20 ++
include/uapi/linux/devlink.h | 29 +++
net/core/devlink.c | 216 ++++++++++++++++++
4 files changed, 303 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..0e9727895987
--- /dev/null
+++ b/Documentation/networking/devlink/devlink-selftests.rst
@@ -0,0 +1,38 @@
+.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+
+=================
+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``
+ - Devices may have the firmware on non-volatile memory on the board, e.g.
+ flash. This particular test helps to run a flash selftest on the device.
+ Implementation of the test is left to the driver/firmware.
+
+example usage
+-------------
+
+.. code:: shell
+
+ # Query selftests supported on the devlink device
+ $ devlink dev selftests show DEV
+ # Query selftests supported on all devlink devices
+ $ devlink dev selftests show
+ # Executes selftests on the device
+ $ devlink dev selftests run DEV test flash
diff --git a/include/net/devlink.h b/include/net/devlink.h
index 88c701b375a2..9d8fc09f2c39 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -1509,6 +1509,26 @@ struct devlink_ops {
struct devlink_rate *parent,
void *priv_child, void *priv_parent,
struct netlink_ext_ack *extack);
+ /**
+ * selftests_check() - queries if selftest is supported
+ * @devlink: Devlink instance
+ * @test_id: test index
+ * @extack: extack for reporting error messages
+ *
+ * Return: True if test is supported by the driver
+ */
+ bool (*selftest_check)(struct devlink *devlink, int test_id,
+ struct netlink_ext_ack *extack);
+ /**
+ * selftest_run() - Runs a selftest
+ * @devlink: Devlink instance
+ * @test_id: test index
+ * @extack: extack for reporting error messages
+ *
+ * Return: Result of the test
+ */
+ u8 (*selftest_run)(struct devlink *devlink, int test_id,
+ struct netlink_ext_ack *extack);
};
void *devlink_priv(struct devlink *devlink);
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index b3d40a5d72ff..469846f40e6d 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_LIST, /* can dump */
+ DEVLINK_CMD_SELFTESTS_RUN,
+
/* add new commands above here */
__DEVLINK_CMD_MAX,
DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1
@@ -276,6 +279,31 @@ enum {
#define DEVLINK_SUPPORTED_FLASH_OVERWRITE_SECTIONS \
(_BITUL(__DEVLINK_FLASH_OVERWRITE_MAX_BIT) - 1)
+/* Commonly used test cases */
+enum devlink_selftest_attr {
+ DEVLINK_SELFTEST_ATTR_UNSPEC,
+ DEVLINK_SELFTEST_ATTR_FLASH, /* flag */
+
+ __DEVLINK_SELFTEST_ATTR_MAX,
+ DEVLINK_SELFTEST_ATTR_MAX = __DEVLINK_SELFTEST_ATTR_MAX - 1
+};
+
+enum devlink_selftest_result {
+ DEVLINK_SELFTEST_SKIP,
+ DEVLINK_SELFTEST_PASS,
+ DEVLINK_SELFTEST_FAIL
+};
+
+enum devlink_selftest_result_attr {
+ DEVLINK_SELFTEST_ATTR_RESULT_UNSPEC,
+ DEVLINK_SELFTEST_ATTR_RESULT, /* nested */
+ DEVLINK_SELFTEST_ATTR_TEST_ID, /* u32, devlink_selftest_attr */
+ DEVLINK_SELFTEST_ATTR_TEST_STATUS, /* u8, devlink_selftest_result */
+
+ __DEVLINK_SELFTEST_ATTR_RES_MAX,
+ DEVLINK_SELFTEST_ATTR_RES_MAX = __DEVLINK_SELFTEST_ATTR_RES_MAX - 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 +604,7 @@ enum devlink_attr {
DEVLINK_ATTR_LINECARD_TYPE, /* string */
DEVLINK_ATTR_LINECARD_SUPPORTED_TYPES, /* nested */
+ DEVLINK_ATTR_SELFTESTS_INFO, /* nested */
/* 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 a9776ea923ae..57a9a183e1d1 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -198,6 +198,10 @@ static const struct nla_policy devlink_function_nl_policy[DEVLINK_PORT_FUNCTION_
DEVLINK_PORT_FN_STATE_ACTIVE),
};
+static const struct nla_policy devlink_selftest_nl_policy[DEVLINK_SELFTEST_ATTR_MAX + 1] = {
+ [DEVLINK_SELFTEST_ATTR_FLASH] = { .type = NLA_FLAG },
+};
+
static DEFINE_XARRAY_FLAGS(devlinks, XA_FLAGS_ALLOC);
#define DEVLINK_REGISTERED XA_MARK_1
@@ -4791,6 +4795,206 @@ static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
return ret;
}
+static int
+devlink_nl_selftests_fill(struct sk_buff *msg, struct devlink *devlink,
+ u32 portid, u32 seq, int flags,
+ struct netlink_ext_ack *extack)
+{
+ struct nlattr *selftests_list;
+ void *hdr;
+ int err;
+ int i;
+
+ hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags,
+ DEVLINK_CMD_SELFTESTS_LIST);
+ if (!hdr)
+ return -EMSGSIZE;
+
+ err = -EMSGSIZE;
+ if (devlink_nl_put_handle(msg, devlink))
+ goto err_cancel_msg;
+
+ selftests_list = nla_nest_start(msg, DEVLINK_ATTR_SELFTESTS_INFO);
+ if (!selftests_list)
+ goto err_cancel_msg;
+
+ for (i = 1; i < DEVLINK_SELFTEST_ATTR_MAX + 1; i++) {
+ if (devlink->ops->selftest_check(devlink, i, extack)) {
+ err = nla_put_flag(msg, i);
+ if (err)
+ goto err_cancel_msg;
+ }
+ }
+
+ nla_nest_end(msg, selftests_list);
+
+ genlmsg_end(msg, hdr);
+
+ return 0;
+
+err_cancel_msg:
+ genlmsg_cancel(msg, hdr);
+ return err;
+}
+
+static int devlink_nl_cmd_selftests_list_doit(struct sk_buff *skb,
+ struct genl_info *info)
+{
+ struct devlink *devlink = info->user_ptr[0];
+ struct sk_buff *msg;
+ int err;
+
+ if (!devlink->ops->selftest_check)
+ return -EOPNOTSUPP;
+
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ if (!msg)
+ return -ENOMEM;
+
+ err = devlink_nl_selftests_fill(msg, devlink, info->snd_portid,
+ info->snd_seq, 0, info->extack);
+ if (err) {
+ nlmsg_free(msg);
+ return err;
+ }
+
+ return genlmsg_reply(msg, info);
+}
+
+static int devlink_nl_cmd_selftests_list_dumpit(struct sk_buff *msg,
+ struct netlink_callback *cb)
+{
+ struct devlink *devlink;
+ int start = cb->args[0];
+ unsigned long index;
+ int idx = 0;
+ int err = 0;
+
+ mutex_lock(&devlink_mutex);
+ xa_for_each_marked(&devlinks, index, devlink, DEVLINK_REGISTERED) {
+ if (!devlink_try_get(devlink))
+ continue;
+
+ if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
+ goto retry;
+
+ if (idx < start || !devlink->ops->selftest_check)
+ goto inc;
+
+ mutex_lock(&devlink->lock);
+ err = devlink_nl_selftests_fill(msg, devlink,
+ NETLINK_CB(cb->skb).portid,
+ cb->nlh->nlmsg_seq, NLM_F_MULTI,
+ cb->extack);
+ mutex_unlock(&devlink->lock);
+ if (err) {
+ devlink_put(devlink);
+ break;
+ }
+inc:
+ idx++;
+retry:
+ devlink_put(devlink);
+ }
+ mutex_unlock(&devlink_mutex);
+
+ if (err != -EMSGSIZE)
+ return err;
+
+ cb->args[0] = idx;
+ return msg->len;
+}
+
+static int devlink_selftest_result_put(struct sk_buff *skb, int test_id,
+ u8 result)
+{
+ struct nlattr *result_attr;
+
+ result_attr = nla_nest_start(skb, DEVLINK_SELFTEST_ATTR_RESULT);
+ if (!result_attr)
+ return -EMSGSIZE;
+
+ if (nla_put_u32(skb, DEVLINK_SELFTEST_ATTR_TEST_ID, test_id) ||
+ nla_put_u8(skb, DEVLINK_SELFTEST_ATTR_TEST_STATUS, result))
+ goto nla_put_failure;
+
+ nla_nest_end(skb, result_attr);
+
+ return 0;
+
+nla_put_failure:
+ nla_nest_cancel(skb, result_attr);
+ return -EMSGSIZE;
+}
+
+static int devlink_nl_cmd_selftests_run(struct sk_buff *skb,
+ struct genl_info *info)
+{
+ struct nlattr *tb[DEVLINK_SELFTEST_ATTR_MAX + 1];
+ struct devlink *devlink = info->user_ptr[0];
+ struct nlattr *attrs, *tests_info;
+ struct sk_buff *msg;
+ void *hdr;
+ int err;
+ int i;
+
+ if (!devlink->ops->selftest_run)
+ return -EOPNOTSUPP;
+
+ if (!info->attrs[DEVLINK_ATTR_SELFTESTS_INFO])
+ return -EINVAL;
+
+ attrs = info->attrs[DEVLINK_ATTR_SELFTESTS_INFO];
+
+ err = nla_parse_nested(tb, DEVLINK_SELFTEST_ATTR_MAX, attrs,
+ devlink_selftest_nl_policy, info->extack);
+ if (err < 0)
+ return err;
+
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ if (!msg)
+ return -ENOMEM;
+
+ err = -EMSGSIZE;
+ hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq,
+ &devlink_nl_family, 0, DEVLINK_CMD_SELFTESTS_RUN);
+ if (!hdr)
+ goto free_msg;
+
+ if (devlink_nl_put_handle(msg, devlink))
+ goto genlmsg_cancel;
+
+ tests_info = nla_nest_start(msg, DEVLINK_ATTR_SELFTESTS_INFO);
+ if (!tests_info)
+ goto genlmsg_cancel;
+
+ for (i = 1; i < DEVLINK_SELFTEST_ATTR_MAX + 1; i++) {
+ u8 res;
+
+ if (nla_get_flag(tb[i])) {
+ res = devlink->ops->selftest_run(devlink, i,
+ info->extack);
+ err = devlink_selftest_result_put(msg, i, res);
+ if (err)
+ goto selftests_list_nest_cancel;
+ }
+ }
+
+ nla_nest_end(msg, tests_info);
+
+ genlmsg_end(msg, hdr);
+
+ return genlmsg_reply(msg, info);
+
+selftests_list_nest_cancel:
+ nla_nest_cancel(msg, tests_info);
+genlmsg_cancel:
+ genlmsg_cancel(msg, hdr);
+free_msg:
+ nlmsg_free(msg);
+ return err;
+}
+
static const struct devlink_param devlink_param_generic[] = {
{
.id = DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET,
@@ -8997,6 +9201,7 @@ 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_INFO] = { .type = NLA_NESTED },
};
static const struct genl_small_ops devlink_nl_ops[] = {
@@ -9356,6 +9561,17 @@ 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_LIST,
+ .doit = devlink_nl_cmd_selftests_list_doit,
+ .dumpit = devlink_nl_cmd_selftests_list_dumpit
+ /* can be retrieved by unprivileged users */
+ },
+ {
+ .cmd = DEVLINK_CMD_SELFTESTS_RUN,
+ .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 --]
next prev parent reply other threads:[~2022-07-18 6:22 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <0220707182950.29348-1-vikas.gupta@broadcom.com>
2022-07-18 6:20 ` [PATCH net-next v3 0/3] add framework for selftests in devlink Vikas Gupta
2022-07-18 6:20 ` Vikas Gupta [this message]
2022-07-19 3:33 ` [PATCH net-next v3 1/3] devlink: introduce framework for selftests Jakub Kicinski
2022-07-19 10:18 ` Vikas Gupta
2022-07-18 6:20 ` [PATCH net-next v3 2/3] bnxt_en: refactor NVM APIs Vikas Gupta
2022-07-18 6:20 ` [PATCH net-next v3 3/3] bnxt_en: implement callbacks for devlink selftests Vikas Gupta
2022-07-21 7:21 ` [PATCH net-next v4 0/3] add framework for selftests in devlink Vikas Gupta
2022-07-21 7:21 ` [PATCH net-next v4 1/3] devlink: introduce framework for selftests Vikas Gupta
2022-07-21 12:56 ` Jiri Pirko
2022-07-21 17:32 ` Vikas Gupta
2022-07-22 6:41 ` Jiri Pirko
2022-07-21 13:01 ` Jiri Pirko
2022-07-21 7:21 ` [PATCH net-next v4 2/3] bnxt_en: refactor NVM APIs Vikas Gupta
2022-07-21 13:02 ` Jiri Pirko
2022-07-21 14:24 ` Vikas Gupta
2022-07-21 7:21 ` [PATCH net-next v4 3/3] bnxt_en: implement callbacks for devlink selftests Vikas Gupta
2022-07-21 12:59 ` Jiri Pirko
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=20220718062032.22426-2-vikas.gupta@broadcom.com \
--to=vikas.gupta@broadcom.com \
--cc=andrew.gospodarek@broadcom.com \
--cc=ast@kernel.org \
--cc=corbet@lwn.net \
--cc=davem@davemloft.net \
--cc=dsahern@kernel.org \
--cc=edumazet@google.com \
--cc=jiri@nvidia.com \
--cc=kuba@kernel.org \
--cc=leon@kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=michael.chan@broadcom.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--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.