Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'Devlink-notification-after-recovery-complete-by-bnxt_en-driver'

Vikas Gupta says:

====================
Devlink notification after recovery complete by bnxt_en driver

This patchset adds following feature in devlink
1) Recovery complete direct call API to be used by drivers when it
successfully completes. It is required as recovery triggered by
devlink may return with EINPROGRESS and eventually recovery
completes in different context.
2) A notification when health status is updated by reporter.

Patchset also contains required changes in bnxt_en driver to
mark recovery in progress when recovery is triggered from kernel
devlink.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+63 -17
+1
drivers/net/ethernet/broadcom/bnxt/bnxt.c
··· 10822 10822 smp_mb__before_atomic(); 10823 10823 clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state); 10824 10824 bnxt_ulp_start(bp, rc); 10825 + bnxt_dl_health_recovery_done(bp); 10825 10826 bnxt_dl_health_status_update(bp, true); 10826 10827 rtnl_unlock(); 10827 10828 break;
+12 -2
drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
··· 89 89 return -EOPNOTSUPP; 90 90 91 91 bnxt_fw_reset(bp); 92 - return 0; 92 + return -EINPROGRESS; 93 93 } 94 94 95 95 static const ··· 116 116 else if (event == BNXT_FW_EXCEPTION_SP_EVENT) 117 117 bnxt_fw_exception(bp); 118 118 119 - return 0; 119 + return -EINPROGRESS; 120 120 } 121 121 122 122 static const ··· 260 260 state); 261 261 262 262 health->fatal = false; 263 + } 264 + 265 + void bnxt_dl_health_recovery_done(struct bnxt *bp) 266 + { 267 + struct bnxt_fw_health *hlth = bp->fw_health; 268 + 269 + if (hlth->fatal) 270 + devlink_health_reporter_recovery_done(hlth->fw_fatal_reporter); 271 + else 272 + devlink_health_reporter_recovery_done(hlth->fw_reset_reporter); 263 273 } 264 274 265 275 static const struct devlink_ops bnxt_dl_ops = {
+1
drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.h
··· 58 58 59 59 void bnxt_devlink_health_report(struct bnxt *bp, unsigned long event); 60 60 void bnxt_dl_health_status_update(struct bnxt *bp, bool healthy); 61 + void bnxt_dl_health_recovery_done(struct bnxt *bp); 61 62 void bnxt_dl_fw_reporters_create(struct bnxt *bp); 62 63 void bnxt_dl_fw_reporters_destroy(struct bnxt *bp, bool all); 63 64 int bnxt_dl_register(struct bnxt *bp);
+2
include/net/devlink.h
··· 1000 1000 void 1001 1001 devlink_health_reporter_state_update(struct devlink_health_reporter *reporter, 1002 1002 enum devlink_health_reporter_state state); 1003 + void 1004 + devlink_health_reporter_recovery_done(struct devlink_health_reporter *reporter); 1003 1005 1004 1006 bool devlink_is_reload_failed(const struct devlink *devlink); 1005 1007
+47 -15
net/core/devlink.c
··· 4844 4844 EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy); 4845 4845 4846 4846 void 4847 - devlink_health_reporter_state_update(struct devlink_health_reporter *reporter, 4848 - enum devlink_health_reporter_state state) 4847 + devlink_health_reporter_recovery_done(struct devlink_health_reporter *reporter) 4849 4848 { 4850 - if (WARN_ON(state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY && 4851 - state != DEVLINK_HEALTH_REPORTER_STATE_ERROR)) 4852 - return; 4853 - 4854 - if (reporter->health_state == state) 4855 - return; 4856 - 4857 - reporter->health_state = state; 4858 - trace_devlink_health_reporter_state_update(reporter->devlink, 4859 - reporter->ops->name, state); 4849 + reporter->recovery_count++; 4850 + reporter->last_recovery_ts = jiffies; 4860 4851 } 4861 - EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update); 4852 + EXPORT_SYMBOL_GPL(devlink_health_reporter_recovery_done); 4862 4853 4863 4854 static int 4864 4855 devlink_health_reporter_recover(struct devlink_health_reporter *reporter, ··· 4867 4876 if (err) 4868 4877 return err; 4869 4878 4870 - reporter->recovery_count++; 4879 + devlink_health_reporter_recovery_done(reporter); 4871 4880 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_HEALTHY; 4872 - reporter->last_recovery_ts = jiffies; 4873 4881 4874 4882 return 0; 4875 4883 } ··· 5079 5089 genlmsg_cancel(msg, hdr); 5080 5090 return -EMSGSIZE; 5081 5091 } 5092 + 5093 + static void devlink_recover_notify(struct devlink_health_reporter *reporter, 5094 + enum devlink_command cmd) 5095 + { 5096 + struct sk_buff *msg; 5097 + int err; 5098 + 5099 + WARN_ON(cmd != DEVLINK_CMD_HEALTH_REPORTER_RECOVER); 5100 + 5101 + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 5102 + if (!msg) 5103 + return; 5104 + 5105 + err = devlink_nl_health_reporter_fill(msg, reporter->devlink, 5106 + reporter, cmd, 0, 0, 0); 5107 + if (err) { 5108 + nlmsg_free(msg); 5109 + return; 5110 + } 5111 + 5112 + genlmsg_multicast_netns(&devlink_nl_family, 5113 + devlink_net(reporter->devlink), 5114 + msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 5115 + } 5116 + 5117 + void 5118 + devlink_health_reporter_state_update(struct devlink_health_reporter *reporter, 5119 + enum devlink_health_reporter_state state) 5120 + { 5121 + if (WARN_ON(state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY && 5122 + state != DEVLINK_HEALTH_REPORTER_STATE_ERROR)) 5123 + return; 5124 + 5125 + if (reporter->health_state == state) 5126 + return; 5127 + 5128 + reporter->health_state = state; 5129 + trace_devlink_health_reporter_state_update(reporter->devlink, 5130 + reporter->ops->name, state); 5131 + devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER); 5132 + } 5133 + EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update); 5082 5134 5083 5135 static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb, 5084 5136 struct genl_info *info)