Commit a6fa9087 authored by David S. Miller's avatar David S. Miller

Merge branch 'devlink-extack'

David Ahern says:

====================
devlink: Add extack messages for reload and port split/unsplit

Patch 1 adds extack arg to reload, port_split and port_unsplit devlink
operations.

Patch 2 adds extack messages for reload operation in netdevsim.

Patch 3 adds extack messages to port split/unsplit in mlxsw driver.

v2
- make the extack messages align with existing dev_err
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 5b5e7a0d 3fcc773b
...@@ -770,27 +770,35 @@ static void mlxsw_core_driver_put(const char *kind) ...@@ -770,27 +770,35 @@ static void mlxsw_core_driver_put(const char *kind)
static int mlxsw_devlink_port_split(struct devlink *devlink, static int mlxsw_devlink_port_split(struct devlink *devlink,
unsigned int port_index, unsigned int port_index,
unsigned int count) unsigned int count,
struct netlink_ext_ack *extack)
{ {
struct mlxsw_core *mlxsw_core = devlink_priv(devlink); struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
if (port_index >= mlxsw_core->max_ports) if (port_index >= mlxsw_core->max_ports) {
NL_SET_ERR_MSG_MOD(extack, "Port index exceeds maximum number of ports");
return -EINVAL; return -EINVAL;
}
if (!mlxsw_core->driver->port_split) if (!mlxsw_core->driver->port_split)
return -EOPNOTSUPP; return -EOPNOTSUPP;
return mlxsw_core->driver->port_split(mlxsw_core, port_index, count); return mlxsw_core->driver->port_split(mlxsw_core, port_index, count,
extack);
} }
static int mlxsw_devlink_port_unsplit(struct devlink *devlink, static int mlxsw_devlink_port_unsplit(struct devlink *devlink,
unsigned int port_index) unsigned int port_index,
struct netlink_ext_ack *extack)
{ {
struct mlxsw_core *mlxsw_core = devlink_priv(devlink); struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
if (port_index >= mlxsw_core->max_ports) if (port_index >= mlxsw_core->max_ports) {
NL_SET_ERR_MSG_MOD(extack, "Port index exceeds maximum number of ports");
return -EINVAL; return -EINVAL;
}
if (!mlxsw_core->driver->port_unsplit) if (!mlxsw_core->driver->port_unsplit)
return -EOPNOTSUPP; return -EOPNOTSUPP;
return mlxsw_core->driver->port_unsplit(mlxsw_core, port_index); return mlxsw_core->driver->port_unsplit(mlxsw_core, port_index,
extack);
} }
static int static int
...@@ -963,7 +971,8 @@ mlxsw_devlink_sb_occ_tc_port_bind_get(struct devlink_port *devlink_port, ...@@ -963,7 +971,8 @@ mlxsw_devlink_sb_occ_tc_port_bind_get(struct devlink_port *devlink_port,
pool_type, p_cur, p_max); pool_type, p_cur, p_max);
} }
static int mlxsw_devlink_core_bus_device_reload(struct devlink *devlink) static int mlxsw_devlink_core_bus_device_reload(struct devlink *devlink,
struct netlink_ext_ack *extack)
{ {
struct mlxsw_core *mlxsw_core = devlink_priv(devlink); struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
int err; int err;
......
...@@ -274,8 +274,9 @@ struct mlxsw_driver { ...@@ -274,8 +274,9 @@ struct mlxsw_driver {
int (*port_type_set)(struct mlxsw_core *mlxsw_core, u8 local_port, int (*port_type_set)(struct mlxsw_core *mlxsw_core, u8 local_port,
enum devlink_port_type new_type); enum devlink_port_type new_type);
int (*port_split)(struct mlxsw_core *mlxsw_core, u8 local_port, int (*port_split)(struct mlxsw_core *mlxsw_core, u8 local_port,
unsigned int count); unsigned int count, struct netlink_ext_ack *extack);
int (*port_unsplit)(struct mlxsw_core *mlxsw_core, u8 local_port); int (*port_unsplit)(struct mlxsw_core *mlxsw_core, u8 local_port,
struct netlink_ext_ack *extack);
int (*sb_pool_get)(struct mlxsw_core *mlxsw_core, int (*sb_pool_get)(struct mlxsw_core *mlxsw_core,
unsigned int sb_index, u16 pool_index, unsigned int sb_index, u16 pool_index,
struct devlink_sb_pool_info *pool_info); struct devlink_sb_pool_info *pool_info);
......
...@@ -3092,7 +3092,8 @@ static void mlxsw_sp_port_unsplit_create(struct mlxsw_sp *mlxsw_sp, ...@@ -3092,7 +3092,8 @@ static void mlxsw_sp_port_unsplit_create(struct mlxsw_sp *mlxsw_sp,
} }
static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port, static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port,
unsigned int count) unsigned int count,
struct netlink_ext_ack *extack)
{ {
struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
struct mlxsw_sp_port *mlxsw_sp_port; struct mlxsw_sp_port *mlxsw_sp_port;
...@@ -3104,6 +3105,7 @@ static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port, ...@@ -3104,6 +3105,7 @@ static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port,
if (!mlxsw_sp_port) { if (!mlxsw_sp_port) {
dev_err(mlxsw_sp->bus_info->dev, "Port number \"%d\" does not exist\n", dev_err(mlxsw_sp->bus_info->dev, "Port number \"%d\" does not exist\n",
local_port); local_port);
NL_SET_ERR_MSG_MOD(extack, "Port number does not exist");
return -EINVAL; return -EINVAL;
} }
...@@ -3112,11 +3114,13 @@ static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port, ...@@ -3112,11 +3114,13 @@ static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port,
if (count != 2 && count != 4) { if (count != 2 && count != 4) {
netdev_err(mlxsw_sp_port->dev, "Port can only be split into 2 or 4 ports\n"); netdev_err(mlxsw_sp_port->dev, "Port can only be split into 2 or 4 ports\n");
NL_SET_ERR_MSG_MOD(extack, "Port can only be split into 2 or 4 ports");
return -EINVAL; return -EINVAL;
} }
if (cur_width != MLXSW_PORT_MODULE_MAX_WIDTH) { if (cur_width != MLXSW_PORT_MODULE_MAX_WIDTH) {
netdev_err(mlxsw_sp_port->dev, "Port cannot be split further\n"); netdev_err(mlxsw_sp_port->dev, "Port cannot be split further\n");
NL_SET_ERR_MSG_MOD(extack, "Port cannot be split further");
return -EINVAL; return -EINVAL;
} }
...@@ -3125,6 +3129,7 @@ static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port, ...@@ -3125,6 +3129,7 @@ static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port,
base_port = local_port; base_port = local_port;
if (mlxsw_sp->ports[base_port + 1]) { if (mlxsw_sp->ports[base_port + 1]) {
netdev_err(mlxsw_sp_port->dev, "Invalid split configuration\n"); netdev_err(mlxsw_sp_port->dev, "Invalid split configuration\n");
NL_SET_ERR_MSG_MOD(extack, "Invalid split configuration");
return -EINVAL; return -EINVAL;
} }
} else { } else {
...@@ -3132,6 +3137,7 @@ static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port, ...@@ -3132,6 +3137,7 @@ static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port,
if (mlxsw_sp->ports[base_port + 1] || if (mlxsw_sp->ports[base_port + 1] ||
mlxsw_sp->ports[base_port + 3]) { mlxsw_sp->ports[base_port + 3]) {
netdev_err(mlxsw_sp_port->dev, "Invalid split configuration\n"); netdev_err(mlxsw_sp_port->dev, "Invalid split configuration\n");
NL_SET_ERR_MSG_MOD(extack, "Invalid split configuration");
return -EINVAL; return -EINVAL;
} }
} }
...@@ -3153,7 +3159,8 @@ static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port, ...@@ -3153,7 +3159,8 @@ static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port,
return err; return err;
} }
static int mlxsw_sp_port_unsplit(struct mlxsw_core *mlxsw_core, u8 local_port) static int mlxsw_sp_port_unsplit(struct mlxsw_core *mlxsw_core, u8 local_port,
struct netlink_ext_ack *extack)
{ {
struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
struct mlxsw_sp_port *mlxsw_sp_port; struct mlxsw_sp_port *mlxsw_sp_port;
...@@ -3165,11 +3172,13 @@ static int mlxsw_sp_port_unsplit(struct mlxsw_core *mlxsw_core, u8 local_port) ...@@ -3165,11 +3172,13 @@ static int mlxsw_sp_port_unsplit(struct mlxsw_core *mlxsw_core, u8 local_port)
if (!mlxsw_sp_port) { if (!mlxsw_sp_port) {
dev_err(mlxsw_sp->bus_info->dev, "Port number \"%d\" does not exist\n", dev_err(mlxsw_sp->bus_info->dev, "Port number \"%d\" does not exist\n",
local_port); local_port);
NL_SET_ERR_MSG_MOD(extack, "Port number does not exist");
return -EINVAL; return -EINVAL;
} }
if (!mlxsw_sp_port->split) { if (!mlxsw_sp_port->split) {
netdev_err(mlxsw_sp_port->dev, "Port wasn't split\n"); netdev_err(mlxsw_sp_port->dev, "Port was not split\n");
NL_SET_ERR_MSG_MOD(extack, "Port was not split");
return -EINVAL; return -EINVAL;
} }
......
...@@ -92,7 +92,7 @@ nfp_devlink_set_lanes(struct nfp_pf *pf, unsigned int idx, unsigned int lanes) ...@@ -92,7 +92,7 @@ nfp_devlink_set_lanes(struct nfp_pf *pf, unsigned int idx, unsigned int lanes)
static int static int
nfp_devlink_port_split(struct devlink *devlink, unsigned int port_index, nfp_devlink_port_split(struct devlink *devlink, unsigned int port_index,
unsigned int count) unsigned int count, struct netlink_ext_ack *extack)
{ {
struct nfp_pf *pf = devlink_priv(devlink); struct nfp_pf *pf = devlink_priv(devlink);
struct nfp_eth_table_port eth_port; struct nfp_eth_table_port eth_port;
...@@ -123,7 +123,8 @@ nfp_devlink_port_split(struct devlink *devlink, unsigned int port_index, ...@@ -123,7 +123,8 @@ nfp_devlink_port_split(struct devlink *devlink, unsigned int port_index,
} }
static int static int
nfp_devlink_port_unsplit(struct devlink *devlink, unsigned int port_index) nfp_devlink_port_unsplit(struct devlink *devlink, unsigned int port_index,
struct netlink_ext_ack *extack)
{ {
struct nfp_pf *pf = devlink_priv(devlink); struct nfp_pf *pf = devlink_priv(devlink);
struct nfp_eth_table_port eth_port; struct nfp_eth_table_port eth_port;
......
...@@ -147,7 +147,8 @@ static int devlink_resources_register(struct devlink *devlink) ...@@ -147,7 +147,8 @@ static int devlink_resources_register(struct devlink *devlink)
return err; return err;
} }
static int nsim_devlink_reload(struct devlink *devlink) static int nsim_devlink_reload(struct devlink *devlink,
struct netlink_ext_ack *extack)
{ {
enum nsim_resource_id res_ids[] = { enum nsim_resource_id res_ids[] = {
NSIM_RESOURCE_IPV4_FIB, NSIM_RESOURCE_IPV4_FIB_RULES, NSIM_RESOURCE_IPV4_FIB, NSIM_RESOURCE_IPV4_FIB_RULES,
...@@ -162,7 +163,7 @@ static int nsim_devlink_reload(struct devlink *devlink) ...@@ -162,7 +163,7 @@ static int nsim_devlink_reload(struct devlink *devlink)
err = devlink_resource_size_get(devlink, res_ids[i], &val); err = devlink_resource_size_get(devlink, res_ids[i], &val);
if (!err) { if (!err) {
err = nsim_fib_set_max(net, res_ids[i], val); err = nsim_fib_set_max(net, res_ids[i], val, extack);
if (err) if (err)
return err; return err;
} }
...@@ -180,7 +181,7 @@ static void nsim_devlink_net_reset(struct net *net) ...@@ -180,7 +181,7 @@ static void nsim_devlink_net_reset(struct net *net)
int i; int i;
for (i = 0; i < ARRAY_SIZE(res_ids); ++i) { for (i = 0; i < ARRAY_SIZE(res_ids); ++i) {
if (nsim_fib_set_max(net, res_ids[i], (u64)-1)) { if (nsim_fib_set_max(net, res_ids[i], (u64)-1, NULL)) {
pr_err("Failed to reset limit for resource %u\n", pr_err("Failed to reset limit for resource %u\n",
res_ids[i]); res_ids[i]);
} }
......
...@@ -64,7 +64,8 @@ u64 nsim_fib_get_val(struct net *net, enum nsim_resource_id res_id, bool max) ...@@ -64,7 +64,8 @@ u64 nsim_fib_get_val(struct net *net, enum nsim_resource_id res_id, bool max)
return max ? entry->max : entry->num; return max ? entry->max : entry->num;
} }
int nsim_fib_set_max(struct net *net, enum nsim_resource_id res_id, u64 val) int nsim_fib_set_max(struct net *net, enum nsim_resource_id res_id, u64 val,
struct netlink_ext_ack *extack)
{ {
struct nsim_fib_data *fib_data = net_generic(net, nsim_fib_net_id); struct nsim_fib_data *fib_data = net_generic(net, nsim_fib_net_id);
struct nsim_fib_entry *entry; struct nsim_fib_entry *entry;
...@@ -90,10 +91,12 @@ int nsim_fib_set_max(struct net *net, enum nsim_resource_id res_id, u64 val) ...@@ -90,10 +91,12 @@ int nsim_fib_set_max(struct net *net, enum nsim_resource_id res_id, u64 val)
/* not allowing a new max to be less than curren occupancy /* not allowing a new max to be less than curren occupancy
* --> no means of evicting entries * --> no means of evicting entries
*/ */
if (val < entry->num) if (val < entry->num) {
NL_SET_ERR_MSG_MOD(extack, "New size is less than current occupancy");
err = -EINVAL; err = -EINVAL;
else } else {
entry->max = val; entry->max = val;
}
return err; return err;
} }
......
...@@ -126,7 +126,8 @@ void nsim_devlink_exit(void); ...@@ -126,7 +126,8 @@ void nsim_devlink_exit(void);
int nsim_fib_init(void); int nsim_fib_init(void);
void nsim_fib_exit(void); void nsim_fib_exit(void);
u64 nsim_fib_get_val(struct net *net, enum nsim_resource_id res_id, bool max); u64 nsim_fib_get_val(struct net *net, enum nsim_resource_id res_id, bool max);
int nsim_fib_set_max(struct net *net, enum nsim_resource_id res_id, u64 val); int nsim_fib_set_max(struct net *net, enum nsim_resource_id res_id, u64 val,
struct netlink_ext_ack *extack);
#else #else
static inline int nsim_devlink_setup(struct netdevsim *ns) static inline int nsim_devlink_setup(struct netdevsim *ns)
{ {
......
...@@ -296,12 +296,13 @@ struct devlink_resource { ...@@ -296,12 +296,13 @@ struct devlink_resource {
#define DEVLINK_RESOURCE_ID_PARENT_TOP 0 #define DEVLINK_RESOURCE_ID_PARENT_TOP 0
struct devlink_ops { struct devlink_ops {
int (*reload)(struct devlink *devlink); int (*reload)(struct devlink *devlink, struct netlink_ext_ack *extack);
int (*port_type_set)(struct devlink_port *devlink_port, int (*port_type_set)(struct devlink_port *devlink_port,
enum devlink_port_type port_type); enum devlink_port_type port_type);
int (*port_split)(struct devlink *devlink, unsigned int port_index, int (*port_split)(struct devlink *devlink, unsigned int port_index,
unsigned int count); unsigned int count, struct netlink_ext_ack *extack);
int (*port_unsplit)(struct devlink *devlink, unsigned int port_index); int (*port_unsplit)(struct devlink *devlink, unsigned int port_index,
struct netlink_ext_ack *extack);
int (*sb_pool_get)(struct devlink *devlink, unsigned int sb_index, int (*sb_pool_get)(struct devlink *devlink, unsigned int sb_index,
u16 pool_index, u16 pool_index,
struct devlink_sb_pool_info *pool_info); struct devlink_sb_pool_info *pool_info);
......
...@@ -702,12 +702,13 @@ static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb, ...@@ -702,12 +702,13 @@ static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
return 0; return 0;
} }
static int devlink_port_split(struct devlink *devlink, static int devlink_port_split(struct devlink *devlink, u32 port_index,
u32 port_index, u32 count) u32 count, struct netlink_ext_ack *extack)
{ {
if (devlink->ops && devlink->ops->port_split) if (devlink->ops && devlink->ops->port_split)
return devlink->ops->port_split(devlink, port_index, count); return devlink->ops->port_split(devlink, port_index, count,
extack);
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -724,14 +725,15 @@ static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb, ...@@ -724,14 +725,15 @@ static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]); count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
return devlink_port_split(devlink, port_index, count); return devlink_port_split(devlink, port_index, count, info->extack);
} }
static int devlink_port_unsplit(struct devlink *devlink, u32 port_index) static int devlink_port_unsplit(struct devlink *devlink, u32 port_index,
struct netlink_ext_ack *extack)
{ {
if (devlink->ops && devlink->ops->port_unsplit) if (devlink->ops && devlink->ops->port_unsplit)
return devlink->ops->port_unsplit(devlink, port_index); return devlink->ops->port_unsplit(devlink, port_index, extack);
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -745,7 +747,7 @@ static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb, ...@@ -745,7 +747,7 @@ static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
return -EINVAL; return -EINVAL;
port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
return devlink_port_unsplit(devlink, port_index); return devlink_port_unsplit(devlink, port_index, info->extack);
} }
static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink, static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,
...@@ -2599,7 +2601,7 @@ static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info) ...@@ -2599,7 +2601,7 @@ static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info)
NL_SET_ERR_MSG_MOD(info->extack, "resources size validation failed"); NL_SET_ERR_MSG_MOD(info->extack, "resources size validation failed");
return err; return err;
} }
return devlink->ops->reload(devlink); return devlink->ops->reload(devlink, info->extack);
} }
static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = { static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
......
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