Merge branch 'devlink-port-health' into next

Moshe Shemesh  says:

====================

Implement commands for interaction with per-port devlink health
reporters. To do this, adapt devlink-health for usage of port handles
with any existing devlink-health subcommands. Add devlink-port health
subcommand as an alias for devlink-health.

====================

Signed-off-by: David Ahern <dsahern@kernel.org>
This commit is contained in:
David Ahern 2020-07-23 00:34:07 +00:00
commit 1ca65af1c5
3 changed files with 152 additions and 45 deletions

View File

@ -2112,7 +2112,19 @@ static void __pr_out_port_handle_start(struct dl *dl, const char *bus_name,
open_json_object(buf); open_json_object(buf);
} }
} else { } else {
if (array) {
if (should_arr_last_port_handle_end(dl, bus_name, dev_name, port_index))
__pr_out_indent_dec();
if (should_arr_last_port_handle_start(dl, bus_name,
dev_name, port_index)) {
pr_out("%s:", buf); pr_out("%s:", buf);
__pr_out_newline();
__pr_out_indent_inc();
arr_last_port_handle_set(dl, bus_name, dev_name, port_index);
}
} else {
pr_out("%s:", buf);
}
} }
} }
@ -3279,6 +3291,7 @@ static void cmd_port_help(void)
pr_err(" devlink port split DEV/PORT_INDEX count COUNT\n"); pr_err(" devlink port split DEV/PORT_INDEX count COUNT\n");
pr_err(" devlink port unsplit DEV/PORT_INDEX\n"); pr_err(" devlink port unsplit DEV/PORT_INDEX\n");
pr_err(" devlink port function set DEV/PORT_INDEX [ hw_addr ADDR ]\n"); pr_err(" devlink port function set DEV/PORT_INDEX [ hw_addr ADDR ]\n");
pr_err(" devlink port health show [ DEV/PORT_INDEX reporter REPORTER_NAME ]\n");
} }
static const char *port_type_name(uint32_t type) static const char *port_type_name(uint32_t type)
@ -3528,6 +3541,9 @@ static int cmd_port_function(struct dl *dl)
return -ENOENT; return -ENOENT;
} }
static int cmd_health(struct dl *dl);
static int __cmd_health_show(struct dl *dl, bool show_device, bool show_port);
static int cmd_port(struct dl *dl) static int cmd_port(struct dl *dl)
{ {
if (dl_argv_match(dl, "help")) { if (dl_argv_match(dl, "help")) {
@ -3549,6 +3565,15 @@ static int cmd_port(struct dl *dl)
} else if (dl_argv_match(dl, "function")) { } else if (dl_argv_match(dl, "function")) {
dl_arg_inc(dl); dl_arg_inc(dl);
return cmd_port_function(dl); return cmd_port_function(dl);
} else if (dl_argv_match(dl, "health")) {
dl_arg_inc(dl);
if (dl_argv_match(dl, "list") || dl_no_arg(dl)
|| (dl_argv_match(dl, "show") && dl_argc(dl) == 1)) {
dl_arg_inc(dl);
return __cmd_health_show(dl, false, true);
} else {
return cmd_health(dl);
}
} }
pr_err("Command \"%s\" not found\n", dl_argv(dl)); pr_err("Command \"%s\" not found\n", dl_argv(dl));
return -ENOENT; return -ENOENT;
@ -4481,7 +4506,8 @@ static void pr_out_flash_update(struct dl *dl, struct nlattr **tb)
} }
static void pr_out_region(struct dl *dl, struct nlattr **tb); static void pr_out_region(struct dl *dl, struct nlattr **tb);
static void pr_out_health(struct dl *dl, struct nlattr **tb_health); static void pr_out_health(struct dl *dl, struct nlattr **tb_health,
bool show_device, bool show_port);
static void pr_out_trap(struct dl *dl, struct nlattr **tb, bool array); static void pr_out_trap(struct dl *dl, struct nlattr **tb, bool array);
static void pr_out_trap_group(struct dl *dl, struct nlattr **tb, bool array); static void pr_out_trap_group(struct dl *dl, struct nlattr **tb, bool array);
static void pr_out_trap_policer(struct dl *dl, struct nlattr **tb, bool array); static void pr_out_trap_policer(struct dl *dl, struct nlattr **tb, bool array);
@ -4560,7 +4586,7 @@ static int cmd_mon_show_cb(const struct nlmsghdr *nlh, void *data)
!tb[DEVLINK_ATTR_HEALTH_REPORTER]) !tb[DEVLINK_ATTR_HEALTH_REPORTER])
return MNL_CB_ERROR; return MNL_CB_ERROR;
pr_out_mon_header(genl->cmd); pr_out_mon_header(genl->cmd);
pr_out_health(dl, tb); pr_out_health(dl, tb, true, true);
pr_out_mon_footer(); pr_out_mon_footer();
break; break;
case DEVLINK_CMD_TRAP_GET: /* fall through */ case DEVLINK_CMD_TRAP_GET: /* fall through */
@ -6705,7 +6731,7 @@ static int cmd_health_set_params(struct dl *dl)
nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_HEALTH_REPORTER_SET, nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_HEALTH_REPORTER_SET,
NLM_F_REQUEST | NLM_F_ACK); NLM_F_REQUEST | NLM_F_ACK);
err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_HEALTH_REPORTER_NAME, err = dl_argv_parse(dl, DL_OPT_HANDLE | DL_OPT_HANDLEP | DL_OPT_HEALTH_REPORTER_NAME,
DL_OPT_HEALTH_REPORTER_GRACEFUL_PERIOD | DL_OPT_HEALTH_REPORTER_GRACEFUL_PERIOD |
DL_OPT_HEALTH_REPORTER_AUTO_RECOVER | DL_OPT_HEALTH_REPORTER_AUTO_RECOVER |
DL_OPT_HEALTH_REPORTER_AUTO_DUMP); DL_OPT_HEALTH_REPORTER_AUTO_DUMP);
@ -6725,7 +6751,8 @@ static int cmd_health_dump_clear(struct dl *dl)
NLM_F_REQUEST | NLM_F_ACK); NLM_F_REQUEST | NLM_F_ACK);
err = dl_argv_parse_put(nlh, dl, err = dl_argv_parse_put(nlh, dl,
DL_OPT_HANDLE | DL_OPT_HEALTH_REPORTER_NAME, 0); DL_OPT_HANDLE | DL_OPT_HANDLEP |
DL_OPT_HEALTH_REPORTER_NAME, 0);
if (err) if (err)
return err; return err;
@ -6972,7 +6999,8 @@ static int cmd_health_object_common(struct dl *dl, uint8_t cmd, uint16_t flags)
nlh = mnlg_msg_prepare(dl->nlg, cmd, flags | NLM_F_REQUEST | NLM_F_ACK); nlh = mnlg_msg_prepare(dl->nlg, cmd, flags | NLM_F_REQUEST | NLM_F_ACK);
err = dl_argv_parse_put(nlh, dl, err = dl_argv_parse_put(nlh, dl,
DL_OPT_HANDLE | DL_OPT_HEALTH_REPORTER_NAME, 0); DL_OPT_HANDLE | DL_OPT_HANDLEP |
DL_OPT_HEALTH_REPORTER_NAME, 0);
if (err) if (err)
return err; return err;
@ -7005,7 +7033,8 @@ static int cmd_health_recover(struct dl *dl)
NLM_F_REQUEST | NLM_F_ACK); NLM_F_REQUEST | NLM_F_ACK);
err = dl_argv_parse_put(nlh, dl, err = dl_argv_parse_put(nlh, dl,
DL_OPT_HANDLE | DL_OPT_HEALTH_REPORTER_NAME, 0); DL_OPT_HANDLE | DL_OPT_HANDLEP |
DL_OPT_HEALTH_REPORTER_NAME, 0);
if (err) if (err)
return err; return err;
@ -7079,7 +7108,8 @@ static void pr_out_dump_report_timestamp(struct dl *dl, const struct nlattr *att
print_string(PRINT_ANY, "last_dump_time", " last_dump_time %s", dump_time); print_string(PRINT_ANY, "last_dump_time", " last_dump_time %s", dump_time);
} }
static void pr_out_health(struct dl *dl, struct nlattr **tb_health) static void pr_out_health(struct dl *dl, struct nlattr **tb_health,
bool print_device, bool print_port)
{ {
struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {}; struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
enum devlink_health_reporter_state state; enum devlink_health_reporter_state state;
@ -7096,7 +7126,20 @@ static void pr_out_health(struct dl *dl, struct nlattr **tb_health)
!tb[DEVLINK_ATTR_HEALTH_REPORTER_STATE]) !tb[DEVLINK_ATTR_HEALTH_REPORTER_STATE])
return; return;
if (!print_device && !print_port)
return;
if (print_port) {
if (!print_device && !tb_health[DEVLINK_ATTR_PORT_INDEX])
return;
else if (tb_health[DEVLINK_ATTR_PORT_INDEX])
pr_out_port_handle_start_arr(dl, tb_health, false);
}
if (print_device) {
if (!print_port && tb_health[DEVLINK_ATTR_PORT_INDEX])
return;
else if (!tb_health[DEVLINK_ATTR_PORT_INDEX])
pr_out_handle_start_arr(dl, tb_health); pr_out_handle_start_arr(dl, tb_health);
}
check_indent_newline(dl); check_indent_newline(dl);
print_string(PRINT_ANY, "reporter", "reporter %s", print_string(PRINT_ANY, "reporter", "reporter %s",
@ -7130,25 +7173,33 @@ static void pr_out_health(struct dl *dl, struct nlattr **tb_health)
pr_out_handle_end(dl); pr_out_handle_end(dl);
} }
struct health_ctx {
struct dl *dl;
bool show_device;
bool show_port;
};
static int cmd_health_show_cb(const struct nlmsghdr *nlh, void *data) static int cmd_health_show_cb(const struct nlmsghdr *nlh, void *data)
{ {
struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {}; struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
struct dl *dl = data; struct health_ctx *ctx = data;
struct dl *dl = ctx->dl;
mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb); mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] || if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] ||
!tb[DEVLINK_ATTR_HEALTH_REPORTER]) !tb[DEVLINK_ATTR_HEALTH_REPORTER])
return MNL_CB_ERROR; return MNL_CB_ERROR;
pr_out_health(dl, tb); pr_out_health(dl, tb, ctx->show_device, ctx->show_port);
return MNL_CB_OK; return MNL_CB_OK;
} }
static int cmd_health_show(struct dl *dl) static int __cmd_health_show(struct dl *dl, bool show_device, bool show_port)
{ {
struct nlmsghdr *nlh; struct nlmsghdr *nlh;
struct health_ctx ctx = { dl, show_device, show_port };
uint16_t flags = NLM_F_REQUEST | NLM_F_ACK; uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
int err; int err;
@ -7158,27 +7209,28 @@ static int cmd_health_show(struct dl *dl)
flags); flags);
if (dl_argc(dl) > 0) { if (dl_argc(dl) > 0) {
ctx.show_port = true;
err = dl_argv_parse_put(nlh, dl, err = dl_argv_parse_put(nlh, dl,
DL_OPT_HANDLE | DL_OPT_HANDLE | DL_OPT_HANDLEP |
DL_OPT_HEALTH_REPORTER_NAME, 0); DL_OPT_HEALTH_REPORTER_NAME, 0);
if (err) if (err)
return err; return err;
} }
pr_out_section_start(dl, "health"); pr_out_section_start(dl, "health");
err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_health_show_cb, dl); err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_health_show_cb, &ctx);
pr_out_section_end(dl); pr_out_section_end(dl);
return err; return err;
} }
static void cmd_health_help(void) static void cmd_health_help(void)
{ {
pr_err("Usage: devlink health show [ dev DEV reporter REPORTER_NAME ]\n"); pr_err("Usage: devlink health show [ { DEV | DEV/PORT_INDEX } reporter REPORTER_NAME ]\n");
pr_err(" devlink health recover DEV reporter REPORTER_NAME\n"); pr_err(" devlink health recover { DEV | DEV/PORT_INDEX } reporter REPORTER_NAME\n");
pr_err(" devlink health diagnose DEV reporter REPORTER_NAME\n"); pr_err(" devlink health diagnose { DEV | DEV/PORT_INDEX } reporter REPORTER_NAME\n");
pr_err(" devlink health dump show DEV reporter REPORTER_NAME\n"); pr_err(" devlink health dump show { DEV | DEV/PORT_INDEX } reporter REPORTER_NAME\n");
pr_err(" devlink health dump clear DEV reporter REPORTER_NAME\n"); pr_err(" devlink health dump clear { DEV | DEV/PORT_INDEX } reporter REPORTER_NAME\n");
pr_err(" devlink health set DEV reporter REPORTER_NAME\n"); pr_err(" devlink health set { DEV | DEV/PORT_INDEX } reporter REPORTER_NAME\n");
pr_err(" [ grace_period MSEC ]\n"); pr_err(" [ grace_period MSEC ]\n");
pr_err(" [ auto_recover { true | false } ]\n"); pr_err(" [ auto_recover { true | false } ]\n");
pr_err(" [ auto_dump { true | false } ]\n"); pr_err(" [ auto_dump { true | false } ]\n");
@ -7192,7 +7244,7 @@ static int cmd_health(struct dl *dl)
} else if (dl_argv_match(dl, "show") || } else if (dl_argv_match(dl, "show") ||
dl_argv_match(dl, "list") || dl_no_arg(dl)) { dl_argv_match(dl, "list") || dl_no_arg(dl)) {
dl_arg_inc(dl); dl_arg_inc(dl);
return cmd_health_show(dl); return __cmd_health_show(dl, true, true);
} else if (dl_argv_match(dl, "recover")) { } else if (dl_argv_match(dl, "recover")) {
dl_arg_inc(dl); dl_arg_inc(dl);
return cmd_health_recover(dl); return cmd_health_recover(dl);

View File

@ -19,37 +19,37 @@ devlink-health \- devlink health reporting and recovery
.ti -8 .ti -8
.B devlink health show .B devlink health show
.RI "[ " DEV "" .RI "[ { " DEV " | " DEV/PORT_INDEX " }"
.B reporter .B reporter
.RI ""REPORTER " ] " .RI ""REPORTER " ] "
.ti -8 .ti -8
.B devlink health recover .B devlink health recover
.RI "" DEV "" .RI "{ " DEV " | " DEV/PORT_INDEX " }"
.B reporter .B reporter
.RI "" REPORTER "" .RI "" REPORTER ""
.ti -8 .ti -8
.B devlink health diagnose .B devlink health diagnose
.RI "" DEV "" .RI "{ " DEV " | " DEV/PORT_INDEX " }"
.B reporter .B reporter
.RI "" REPORTER "" .RI "" REPORTER ""
.ti -8 .ti -8
.B devlink health dump show .B devlink health dump show
.RI "" DEV "" .RI "{ " DEV " | " DEV/PORT_INDEX " }"
.B reporter .B reporter
.RI "" REPORTER "" .RI "" REPORTER ""
.ti -8 .ti -8
.B devlink health dump clear .B devlink health dump clear
.RI "" DEV "" .RI "{ " DEV " | " DEV/PORT_INDEX " }"
.B reporter .B reporter
.RI "" REPORTER "" .RI "" REPORTER ""
.ti -8 .ti -8
.B devlink health set .B devlink health set
.RI "" DEV "" .RI "{ " DEV " | " DEV/PORT_INDEX " }"
.B reporter .B reporter
.RI "" REPORTER "" .RI "" REPORTER ""
[ [
@ -64,15 +64,19 @@ devlink-health \- devlink health reporting and recovery
.B devlink health help .B devlink health help
.SH "DESCRIPTION" .SH "DESCRIPTION"
.SS devlink health show - Show status and configuration on all supported reporters on all devlink devices. .SS devlink health show - Show status and configuration on all supported reporters.
Displays info about reporters registered on devlink devices and ports.
.PP .PP
.I "DEV" .I "DEV"
- specifies the devlink device. - specifies the devlink device.
.br
.I DEV/PORT_INDEX
- specifies the devlink port.
.PP .PP
.I "REPORTER" .I "REPORTER"
- specifies the reporter's name registered on the devlink device. - specifies the reporter's name registered on specified devlink device or port.
.SS devlink health recover - Initiate a recovery operation on a reporter. .SS devlink health recover - Initiate a recovery operation on a reporter.
This action performs a recovery and increases the recoveries counter on success. This action performs a recovery and increases the recoveries counter on success.
@ -80,20 +84,26 @@ This action performs a recovery and increases the recoveries counter on success.
.PP .PP
.I "DEV" .I "DEV"
- specifies the devlink device. - specifies the devlink device.
.br
.I DEV/PORT_INDEX
- specifies the devlink port.
.PP .PP
.I "REPORTER" .I "REPORTER"
- specifies the reporter's name registered on the devlink device. - specifies the reporter's name registered on specified devlink device or port.
.SS devlink health diagnose - Retrieve diagnostics data on a reporter. .SS devlink health diagnose - Retrieve diagnostics data on a reporter.
.PP .PP
.I "DEV" .I DEV
- specifies the devlink device. - specifies the devlink device.
.br
.I DEV/PORT_INDEX
- specifies the devlink port.
.PP .PP
.I "REPORTER" .I "REPORTER"
- specifies the reporter's name registered on the devlink device. - specifies the reporter's name registered on specified devlink device or port.
.SS devlink health dump show - Display the last saved dump. .SS devlink health dump show - Display the last saved dump.
@ -111,10 +121,13 @@ reporter reports on an error or manually at the user's request.
.PP .PP
.I "DEV" .I "DEV"
- specifies the devlink device. - specifies the devlink device.
.br
.I DEV/PORT_INDEX
- specifies the devlink port.
.PP .PP
.I "REPORTER" .I "REPORTER"
- specifies the reporter's name registered on the devlink device. - specifies the reporter's name registered on specified devlink device or port.
.SS devlink health dump clear - Delete the saved dump. .SS devlink health dump clear - Delete the saved dump.
Deleting the saved dump enables a generation of a new dump on Deleting the saved dump enables a generation of a new dump on
@ -126,10 +139,13 @@ the next "devlink health dump show" command.
.PP .PP
.I "DEV" .I "DEV"
- specifies the devlink device. - specifies the devlink device.
.br
.I DEV/PORT_INDEX
- specifies the devlink port.
.PP .PP
.I "REPORTER" .I "REPORTER"
- specifies the reporter's name registered on the devlink device. - specifies the reporter's name registered on specified devlink device or port.
.SS devlink health set - Configure health reporter. .SS devlink health set - Configure health reporter.
Please note that some params are not supported on a reporter which Please note that some params are not supported on a reporter which
@ -138,10 +154,13 @@ doesn't support a recovery or dump method.
.PP .PP
.I "DEV" .I "DEV"
- specifies the devlink device. - specifies the devlink device.
.br
.I DEV/PORT_INDEX
- specifies the devlink port.
.PP .PP
.I "REPORTER" .I "REPORTER"
- specifies the reporter's name registered on the devlink device. - specifies the reporter's name registered on specified devlink device or port.
.TP .TP
.BI grace_period " MSEC " .BI grace_period " MSEC "
@ -159,38 +178,55 @@ Indicates whether the devlink should execute automatic dump on error.
.PP .PP
devlink health show devlink health show
.RS 4 .RS 4
List status and configuration of available reporters on devices. List status and configuration of available reporters on devices and ports.
.RE .RE
.PP .PP
devlink health recover pci/0000:00:09.0 reporter tx devlink health show pci/0000:00:09.0/1 reporter tx
.RS 4 .RS 4
Initiate recovery on tx reporter registered on pci/0000:00:09.0. List status and configuration of tx reporter registered on port on pci/0000:00:09.0/1
.RE .RE
.PP .PP
devlink health diagnose pci/0000:00:09.0 reporter tx devlink health recover pci/0000:00:09.0 reporter fw_fatal
.RS 4
Initiate recovery on fw_fatal reporter registered on device on pci/0000:00:09.0.
.RE
.PP
devlink health recover pci/0000:00:09.0/1 reporter tx
.RS 4
Initiate recovery on tx reporter registered on port on pci/0000:00:09.0/1.
.RE
.PP
devlink health diagnose pci/0000:00:09.0 reporter fw
.RS 4 .RS 4
List diagnostics data on the specified device and reporter. List diagnostics data on the specified device and reporter.
.RE .RE
.PP .PP
devlink health dump show pci/0000:00:09.0 reporter tx devlink health dump show pci/0000:00:09.0/1 reporter tx
.RS 4 .RS 4
Display the last saved dump on the specified device and reporter. Display the last saved dump on the specified port and reporter.
.RE .RE
.PP .PP
devlink health dump clear pci/0000:00:09.0 reporter tx devlink health dump clear pci/0000:00:09.0/1 reporter tx
.RS 4 .RS 4
Delete saved dump on the specified device and reporter. Delete saved dump on the specified port and reporter.
.RE .RE
.PP .PP
devlink health set pci/0000:00:09.0 reporter tx grace_period 3500 devlink health set pci/0000:00:09.0 reporter fw_fatal grace_period 3500
.RS 4 .RS 4
Set time interval between auto recoveries to minimum of 3500 msec on Set time interval between auto recoveries to minimum of 3500 msec on
the specified device and reporter. the specified device and reporter.
.RE .RE
.PP .PP
devlink health set pci/0000:00:09.0 reporter tx auto_recover false devlink health set pci/0000:00:09.0/1 reporter tx grace_period 3500
.RS 4
Set time interval between auto recoveries to minimum of 3500 msec on
the specified port and reporter.
.RE
.PP
devlink health set pci/0000:00:09.0 reporter fw_fatal auto_recover false
.RS 4 .RS 4
Turn off auto recovery on the specified device and reporter. Turn off auto recovery on the specified device and reporter.
.RE .RE
.SH SEE ALSO .SH SEE ALSO
.BR devlink (8), .BR devlink (8),

View File

@ -39,6 +39,10 @@ devlink-port \- devlink port configuration
.B devlink port show .B devlink port show
.RI "[ " DEV/PORT_INDEX " ]" .RI "[ " DEV/PORT_INDEX " ]"
.ti -8
.B devlink port health
.RI "{ " show " | " recover " | " diagnose " | " dump " | " set " }"
.ti -8 .ti -8
.B devlink port help .B devlink port help
@ -91,6 +95,10 @@ Could be performed on any split port of the same split group.
- specifies the devlink port to show. - specifies the devlink port to show.
If this argument is omitted all ports are listed. If this argument is omitted all ports are listed.
.SS devlink port health - devlink health reporting and recovery
Is an alias for
.BR devlink-health (8).
.SH "EXAMPLES" .SH "EXAMPLES"
.PP .PP
devlink port show devlink port show
@ -117,12 +125,23 @@ devlink port unsplit pci/0000:01:00.0/1
.RS 4 .RS 4
Unplit the specified previously split devlink port. Unplit the specified previously split devlink port.
.RE .RE
.PP
devlink port health show
.RS 4
Shows status and configuration of all supported reporters registered on all devlink ports.
.RE
.PP
devlink port health show pci/0000:01:00.0/1 reporter tx
.RS 4
Shows status and configuration of tx reporter registered on pci/0000:01:00.0/1 devlink port.
.RE
.SH SEE ALSO .SH SEE ALSO
.BR devlink (8), .BR devlink (8),
.BR devlink-dev (8), .BR devlink-dev (8),
.BR devlink-sb (8), .BR devlink-sb (8),
.BR devlink-monitor (8), .BR devlink-monitor (8),
.BR devlink-health (8),
.br .br
.SH AUTHOR .SH AUTHOR