@@ -479,6 +479,12 @@ static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
479479 return 0 ;
480480}
481481
482+ static bool
483+ devlink_reload_action_is_supported (struct devlink * devlink , enum devlink_reload_action action )
484+ {
485+ return test_bit (action , & devlink -> ops -> reload_actions );
486+ }
487+
482488static int devlink_nl_fill (struct sk_buff * msg , struct devlink * devlink ,
483489 enum devlink_command cmd , u32 portid ,
484490 u32 seq , int flags )
@@ -2984,29 +2990,68 @@ bool devlink_is_reload_failed(const struct devlink *devlink)
29842990EXPORT_SYMBOL_GPL (devlink_is_reload_failed );
29852991
29862992static int devlink_reload (struct devlink * devlink , struct net * dest_net ,
2993+ enum devlink_reload_action action , u32 * actions_performed ,
29872994 struct netlink_ext_ack * extack )
29882995{
29892996 int err ;
29902997
29912998 if (!devlink -> reload_enabled )
29922999 return - EOPNOTSUPP ;
29933000
2994- err = devlink -> ops -> reload_down (devlink , !!dest_net , extack );
3001+ err = devlink -> ops -> reload_down (devlink , !!dest_net , action , extack );
29953002 if (err )
29963003 return err ;
29973004
29983005 if (dest_net && !net_eq (dest_net , devlink_net (devlink )))
29993006 devlink_reload_netns_change (devlink , dest_net );
30003007
3001- err = devlink -> ops -> reload_up (devlink , extack );
3008+ err = devlink -> ops -> reload_up (devlink , action , actions_performed , extack );
30023009 devlink_reload_failed_set (devlink , !!err );
3003- return err ;
3010+ if (err )
3011+ return err ;
3012+
3013+ WARN_ON (!(* actions_performed & BIT (action )));
3014+ return 0 ;
3015+ }
3016+
3017+ static int
3018+ devlink_nl_reload_actions_performed_snd (struct devlink * devlink , u32 actions_performed ,
3019+ enum devlink_command cmd , struct genl_info * info )
3020+ {
3021+ struct sk_buff * msg ;
3022+ void * hdr ;
3023+
3024+ msg = nlmsg_new (NLMSG_DEFAULT_SIZE , GFP_KERNEL );
3025+ if (!msg )
3026+ return - ENOMEM ;
3027+
3028+ hdr = genlmsg_put (msg , info -> snd_portid , info -> snd_seq , & devlink_nl_family , 0 , cmd );
3029+ if (!hdr )
3030+ goto free_msg ;
3031+
3032+ if (devlink_nl_put_handle (msg , devlink ))
3033+ goto nla_put_failure ;
3034+
3035+ if (nla_put_bitfield32 (msg , DEVLINK_ATTR_RELOAD_ACTIONS_PERFORMED , actions_performed ,
3036+ actions_performed ))
3037+ goto nla_put_failure ;
3038+ genlmsg_end (msg , hdr );
3039+
3040+ return genlmsg_reply (msg , info );
3041+
3042+ nla_put_failure :
3043+ genlmsg_cancel (msg , hdr );
3044+ free_msg :
3045+ nlmsg_free (msg );
3046+ return - EMSGSIZE ;
30043047}
30053048
30063049static int devlink_nl_cmd_reload (struct sk_buff * skb , struct genl_info * info )
30073050{
30083051 struct devlink * devlink = info -> user_ptr [0 ];
3052+ enum devlink_reload_action action ;
30093053 struct net * dest_net = NULL ;
3054+ u32 actions_performed ;
30103055 int err ;
30113056
30123057 if (!devlink_reload_supported (devlink -> ops ))
@@ -3026,12 +3071,30 @@ static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info)
30263071 return PTR_ERR (dest_net );
30273072 }
30283073
3029- err = devlink_reload (devlink , dest_net , info -> extack );
3074+ if (info -> attrs [DEVLINK_ATTR_RELOAD_ACTION ])
3075+ action = nla_get_u8 (info -> attrs [DEVLINK_ATTR_RELOAD_ACTION ]);
3076+ else
3077+ action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT ;
3078+
3079+ if (!devlink_reload_action_is_supported (devlink , action )) {
3080+ NL_SET_ERR_MSG_MOD (info -> extack ,
3081+ "Requested reload action is not supported by the driver" );
3082+ return - EOPNOTSUPP ;
3083+ }
3084+
3085+ err = devlink_reload (devlink , dest_net , action , & actions_performed , info -> extack );
30303086
30313087 if (dest_net )
30323088 put_net (dest_net );
30333089
3034- return err ;
3090+ if (err )
3091+ return err ;
3092+ /* For backward compatibility generate reply only if attributes used by user */
3093+ if (!info -> attrs [DEVLINK_ATTR_RELOAD_ACTION ])
3094+ return 0 ;
3095+
3096+ return devlink_nl_reload_actions_performed_snd (devlink , actions_performed ,
3097+ DEVLINK_CMD_RELOAD , info );
30353098}
30363099
30373100static int devlink_nl_flash_update_fill (struct sk_buff * msg ,
@@ -7282,6 +7345,8 @@ static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
72827345 [DEVLINK_ATTR_TRAP_POLICER_RATE ] = { .type = NLA_U64 },
72837346 [DEVLINK_ATTR_TRAP_POLICER_BURST ] = { .type = NLA_U64 },
72847347 [DEVLINK_ATTR_PORT_FUNCTION ] = { .type = NLA_NESTED },
7348+ [DEVLINK_ATTR_RELOAD_ACTION ] = NLA_POLICY_RANGE (NLA_U8 , DEVLINK_RELOAD_ACTION_DRIVER_REINIT ,
7349+ DEVLINK_RELOAD_ACTION_MAX ),
72857350};
72867351
72877352static const struct genl_small_ops devlink_nl_ops [] = {
@@ -7615,6 +7680,21 @@ static struct genl_family devlink_nl_family __ro_after_init = {
76157680 .n_mcgrps = ARRAY_SIZE (devlink_nl_mcgrps ),
76167681};
76177682
7683+ static bool devlink_reload_actions_valid (const struct devlink_ops * ops )
7684+ {
7685+ if (!devlink_reload_supported (ops )) {
7686+ if (WARN_ON (ops -> reload_actions ))
7687+ return false;
7688+ return true;
7689+ }
7690+
7691+ if (WARN_ON (!ops -> reload_actions ||
7692+ ops -> reload_actions & BIT (DEVLINK_RELOAD_ACTION_UNSPEC ) ||
7693+ ops -> reload_actions >= BIT (__DEVLINK_RELOAD_ACTION_MAX )))
7694+ return false;
7695+ return true;
7696+ }
7697+
76187698/**
76197699 * devlink_alloc - Allocate new devlink instance resources
76207700 *
@@ -7631,6 +7711,9 @@ struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
76317711 if (WARN_ON (!ops ))
76327712 return NULL ;
76337713
7714+ if (!devlink_reload_actions_valid (ops ))
7715+ return NULL ;
7716+
76347717 devlink = kzalloc (sizeof (* devlink ) + priv_size , GFP_KERNEL );
76357718 if (!devlink )
76367719 return NULL ;
@@ -9960,6 +10043,7 @@ int devlink_compat_switch_id_get(struct net_device *dev,
996010043static void __net_exit devlink_pernet_pre_exit (struct net * net )
996110044{
996210045 struct devlink * devlink ;
10046+ u32 actions_performed ;
996310047 int err ;
996410048
996510049 /* In case network namespace is getting destroyed, reload
@@ -9970,7 +10054,9 @@ static void __net_exit devlink_pernet_pre_exit(struct net *net)
997010054 if (net_eq (devlink_net (devlink ), net )) {
997110055 if (WARN_ON (!devlink_reload_supported (devlink -> ops )))
997210056 continue ;
9973- err = devlink_reload (devlink , & init_net , NULL );
10057+ err = devlink_reload (devlink , & init_net ,
10058+ DEVLINK_RELOAD_ACTION_DRIVER_REINIT ,
10059+ & actions_performed , NULL );
997410060 if (err && err != - EOPNOTSUPP )
997510061 pr_warn ("Failed to reload devlink instance into init_net\n" );
997610062 }
0 commit comments