Commit 7004c6c4 authored by Moshe Shemesh's avatar Moshe Shemesh Committed by Jakub Kicinski

devlink: Move devlink health dump to health file

Move devlink health report dump callbacks and related code from
leftover.c to health.c. No functional change in this patch.
Signed-off-by: default avatarMoshe Shemesh <moshe@nvidia.com>
Reviewed-by: default avatarJiri Pirko <jiri@nvidia.com>
Reviewed-by: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent a929df7f
...@@ -278,3 +278,7 @@ int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb, ...@@ -278,3 +278,7 @@ int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb,
struct genl_info *info); struct genl_info *info);
int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb, int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb,
struct genl_info *info); struct genl_info *info);
int devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff *skb,
struct netlink_callback *cb);
int devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff *skb,
struct genl_info *info);
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
*/ */
#include <net/genetlink.h> #include <net/genetlink.h>
#include <net/sock.h>
#include <trace/events/devlink.h> #include <trace/events/devlink.h>
#include "devl_internal.h" #include "devl_internal.h"
...@@ -507,6 +508,56 @@ devlink_health_reporter_recover(struct devlink_health_reporter *reporter, ...@@ -507,6 +508,56 @@ devlink_health_reporter_recover(struct devlink_health_reporter *reporter,
return 0; return 0;
} }
static void
devlink_health_dump_clear(struct devlink_health_reporter *reporter)
{
if (!reporter->dump_fmsg)
return;
devlink_fmsg_free(reporter->dump_fmsg);
reporter->dump_fmsg = NULL;
}
int devlink_health_do_dump(struct devlink_health_reporter *reporter,
void *priv_ctx,
struct netlink_ext_ack *extack)
{
int err;
if (!reporter->ops->dump)
return 0;
if (reporter->dump_fmsg)
return 0;
reporter->dump_fmsg = devlink_fmsg_alloc();
if (!reporter->dump_fmsg) {
err = -ENOMEM;
return err;
}
err = devlink_fmsg_obj_nest_start(reporter->dump_fmsg);
if (err)
goto dump_err;
err = reporter->ops->dump(reporter, reporter->dump_fmsg,
priv_ctx, extack);
if (err)
goto dump_err;
err = devlink_fmsg_obj_nest_end(reporter->dump_fmsg);
if (err)
goto dump_err;
reporter->dump_ts = jiffies;
reporter->dump_real_ts = ktime_get_real_ns();
return 0;
dump_err:
devlink_health_dump_clear(reporter);
return err;
}
int devlink_health_report(struct devlink_health_reporter *reporter, int devlink_health_report(struct devlink_health_reporter *reporter,
const char *msg, void *priv_ctx) const char *msg, void *priv_ctx)
{ {
...@@ -1174,3 +1225,74 @@ int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb, ...@@ -1174,3 +1225,74 @@ int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb,
devlink_fmsg_free(fmsg); devlink_fmsg_free(fmsg);
return err; return err;
} }
static struct devlink_health_reporter *
devlink_health_reporter_get_from_cb(struct netlink_callback *cb)
{
const struct genl_dumpit_info *info = genl_dumpit_info(cb);
struct devlink_health_reporter *reporter;
struct nlattr **attrs = info->attrs;
struct devlink *devlink;
devlink = devlink_get_from_attrs_lock(sock_net(cb->skb->sk), attrs);
if (IS_ERR(devlink))
return NULL;
devl_unlock(devlink);
reporter = devlink_health_reporter_get_from_attrs(devlink, attrs);
devlink_put(devlink);
return reporter;
}
int devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff *skb,
struct netlink_callback *cb)
{
struct devlink_nl_dump_state *state = devlink_dump_state(cb);
struct devlink_health_reporter *reporter;
int err;
reporter = devlink_health_reporter_get_from_cb(cb);
if (!reporter)
return -EINVAL;
if (!reporter->ops->dump)
return -EOPNOTSUPP;
mutex_lock(&reporter->dump_lock);
if (!state->idx) {
err = devlink_health_do_dump(reporter, NULL, cb->extack);
if (err)
goto unlock;
state->dump_ts = reporter->dump_ts;
}
if (!reporter->dump_fmsg || state->dump_ts != reporter->dump_ts) {
NL_SET_ERR_MSG(cb->extack, "Dump trampled, please retry");
err = -EAGAIN;
goto unlock;
}
err = devlink_fmsg_dumpit(reporter->dump_fmsg, skb, cb,
DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET);
unlock:
mutex_unlock(&reporter->dump_lock);
return err;
}
int devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff *skb,
struct genl_info *info)
{
struct devlink *devlink = info->user_ptr[0];
struct devlink_health_reporter *reporter;
reporter = devlink_health_reporter_get_from_info(devlink, info);
if (!reporter)
return -EINVAL;
if (!reporter->ops->dump)
return -EOPNOTSUPP;
mutex_lock(&reporter->dump_lock);
devlink_health_dump_clear(reporter);
mutex_unlock(&reporter->dump_lock);
return 0;
}
...@@ -5372,129 +5372,6 @@ static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb, ...@@ -5372,129 +5372,6 @@ static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
return err; return err;
} }
static void
devlink_health_dump_clear(struct devlink_health_reporter *reporter)
{
if (!reporter->dump_fmsg)
return;
devlink_fmsg_free(reporter->dump_fmsg);
reporter->dump_fmsg = NULL;
}
int devlink_health_do_dump(struct devlink_health_reporter *reporter,
void *priv_ctx,
struct netlink_ext_ack *extack)
{
int err;
if (!reporter->ops->dump)
return 0;
if (reporter->dump_fmsg)
return 0;
reporter->dump_fmsg = devlink_fmsg_alloc();
if (!reporter->dump_fmsg) {
err = -ENOMEM;
return err;
}
err = devlink_fmsg_obj_nest_start(reporter->dump_fmsg);
if (err)
goto dump_err;
err = reporter->ops->dump(reporter, reporter->dump_fmsg,
priv_ctx, extack);
if (err)
goto dump_err;
err = devlink_fmsg_obj_nest_end(reporter->dump_fmsg);
if (err)
goto dump_err;
reporter->dump_ts = jiffies;
reporter->dump_real_ts = ktime_get_real_ns();
return 0;
dump_err:
devlink_health_dump_clear(reporter);
return err;
}
static struct devlink_health_reporter *
devlink_health_reporter_get_from_cb(struct netlink_callback *cb)
{
const struct genl_dumpit_info *info = genl_dumpit_info(cb);
struct devlink_health_reporter *reporter;
struct nlattr **attrs = info->attrs;
struct devlink *devlink;
devlink = devlink_get_from_attrs_lock(sock_net(cb->skb->sk), attrs);
if (IS_ERR(devlink))
return NULL;
devl_unlock(devlink);
reporter = devlink_health_reporter_get_from_attrs(devlink, attrs);
devlink_put(devlink);
return reporter;
}
static int
devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff *skb,
struct netlink_callback *cb)
{
struct devlink_nl_dump_state *state = devlink_dump_state(cb);
struct devlink_health_reporter *reporter;
int err;
reporter = devlink_health_reporter_get_from_cb(cb);
if (!reporter)
return -EINVAL;
if (!reporter->ops->dump)
return -EOPNOTSUPP;
mutex_lock(&reporter->dump_lock);
if (!state->idx) {
err = devlink_health_do_dump(reporter, NULL, cb->extack);
if (err)
goto unlock;
state->dump_ts = reporter->dump_ts;
}
if (!reporter->dump_fmsg || state->dump_ts != reporter->dump_ts) {
NL_SET_ERR_MSG(cb->extack, "Dump trampled, please retry");
err = -EAGAIN;
goto unlock;
}
err = devlink_fmsg_dumpit(reporter->dump_fmsg, skb, cb,
DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET);
unlock:
mutex_unlock(&reporter->dump_lock);
return err;
}
static int
devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff *skb,
struct genl_info *info)
{
struct devlink *devlink = info->user_ptr[0];
struct devlink_health_reporter *reporter;
reporter = devlink_health_reporter_get_from_info(devlink, info);
if (!reporter)
return -EINVAL;
if (!reporter->ops->dump)
return -EOPNOTSUPP;
mutex_lock(&reporter->dump_lock);
devlink_health_dump_clear(reporter);
mutex_unlock(&reporter->dump_lock);
return 0;
}
static int devlink_nl_cmd_health_reporter_test_doit(struct sk_buff *skb, static int devlink_nl_cmd_health_reporter_test_doit(struct sk_buff *skb,
struct genl_info *info) struct genl_info *info)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment