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

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: David S. Miller <davem@davemloft.net>

+60 -32
+16 -7
drivers/net/ethernet/mellanox/mlxsw/core.c
··· 770 770 771 771 static int mlxsw_devlink_port_split(struct devlink *devlink, 772 772 unsigned int port_index, 773 - unsigned int count) 773 + unsigned int count, 774 + struct netlink_ext_ack *extack) 774 775 { 775 776 struct mlxsw_core *mlxsw_core = devlink_priv(devlink); 776 777 777 - if (port_index >= mlxsw_core->max_ports) 778 + if (port_index >= mlxsw_core->max_ports) { 779 + NL_SET_ERR_MSG_MOD(extack, "Port index exceeds maximum number of ports"); 778 780 return -EINVAL; 781 + } 779 782 if (!mlxsw_core->driver->port_split) 780 783 return -EOPNOTSUPP; 781 - return mlxsw_core->driver->port_split(mlxsw_core, port_index, count); 784 + return mlxsw_core->driver->port_split(mlxsw_core, port_index, count, 785 + extack); 782 786 } 783 787 784 788 static int mlxsw_devlink_port_unsplit(struct devlink *devlink, 785 - unsigned int port_index) 789 + unsigned int port_index, 790 + struct netlink_ext_ack *extack) 786 791 { 787 792 struct mlxsw_core *mlxsw_core = devlink_priv(devlink); 788 793 789 - if (port_index >= mlxsw_core->max_ports) 794 + if (port_index >= mlxsw_core->max_ports) { 795 + NL_SET_ERR_MSG_MOD(extack, "Port index exceeds maximum number of ports"); 790 796 return -EINVAL; 797 + } 791 798 if (!mlxsw_core->driver->port_unsplit) 792 799 return -EOPNOTSUPP; 793 - return mlxsw_core->driver->port_unsplit(mlxsw_core, port_index); 800 + return mlxsw_core->driver->port_unsplit(mlxsw_core, port_index, 801 + extack); 794 802 } 795 803 796 804 static int ··· 971 963 pool_type, p_cur, p_max); 972 964 } 973 965 974 - static int mlxsw_devlink_core_bus_device_reload(struct devlink *devlink) 966 + static int mlxsw_devlink_core_bus_device_reload(struct devlink *devlink, 967 + struct netlink_ext_ack *extack) 975 968 { 976 969 struct mlxsw_core *mlxsw_core = devlink_priv(devlink); 977 970 int err;
+3 -2
drivers/net/ethernet/mellanox/mlxsw/core.h
··· 274 274 int (*port_type_set)(struct mlxsw_core *mlxsw_core, u8 local_port, 275 275 enum devlink_port_type new_type); 276 276 int (*port_split)(struct mlxsw_core *mlxsw_core, u8 local_port, 277 - unsigned int count); 278 - int (*port_unsplit)(struct mlxsw_core *mlxsw_core, u8 local_port); 277 + unsigned int count, struct netlink_ext_ack *extack); 278 + int (*port_unsplit)(struct mlxsw_core *mlxsw_core, u8 local_port, 279 + struct netlink_ext_ack *extack); 279 280 int (*sb_pool_get)(struct mlxsw_core *mlxsw_core, 280 281 unsigned int sb_index, u16 pool_index, 281 282 struct devlink_sb_pool_info *pool_info);
+12 -3
drivers/net/ethernet/mellanox/mlxsw/spectrum.c
··· 3092 3092 } 3093 3093 3094 3094 static int mlxsw_sp_port_split(struct mlxsw_core *mlxsw_core, u8 local_port, 3095 - unsigned int count) 3095 + unsigned int count, 3096 + struct netlink_ext_ack *extack) 3096 3097 { 3097 3098 struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); 3098 3099 struct mlxsw_sp_port *mlxsw_sp_port; ··· 3105 3104 if (!mlxsw_sp_port) { 3106 3105 dev_err(mlxsw_sp->bus_info->dev, "Port number \"%d\" does not exist\n", 3107 3106 local_port); 3107 + NL_SET_ERR_MSG_MOD(extack, "Port number does not exist"); 3108 3108 return -EINVAL; 3109 3109 } 3110 3110 ··· 3114 3112 3115 3113 if (count != 2 && count != 4) { 3116 3114 netdev_err(mlxsw_sp_port->dev, "Port can only be split into 2 or 4 ports\n"); 3115 + NL_SET_ERR_MSG_MOD(extack, "Port can only be split into 2 or 4 ports"); 3117 3116 return -EINVAL; 3118 3117 } 3119 3118 3120 3119 if (cur_width != MLXSW_PORT_MODULE_MAX_WIDTH) { 3121 3120 netdev_err(mlxsw_sp_port->dev, "Port cannot be split further\n"); 3121 + NL_SET_ERR_MSG_MOD(extack, "Port cannot be split further"); 3122 3122 return -EINVAL; 3123 3123 } 3124 3124 ··· 3129 3125 base_port = local_port; 3130 3126 if (mlxsw_sp->ports[base_port + 1]) { 3131 3127 netdev_err(mlxsw_sp_port->dev, "Invalid split configuration\n"); 3128 + NL_SET_ERR_MSG_MOD(extack, "Invalid split configuration"); 3132 3129 return -EINVAL; 3133 3130 } 3134 3131 } else { ··· 3137 3132 if (mlxsw_sp->ports[base_port + 1] || 3138 3133 mlxsw_sp->ports[base_port + 3]) { 3139 3134 netdev_err(mlxsw_sp_port->dev, "Invalid split configuration\n"); 3135 + NL_SET_ERR_MSG_MOD(extack, "Invalid split configuration"); 3140 3136 return -EINVAL; 3141 3137 } 3142 3138 } ··· 3159 3153 return err; 3160 3154 } 3161 3155 3162 - static int mlxsw_sp_port_unsplit(struct mlxsw_core *mlxsw_core, u8 local_port) 3156 + static int mlxsw_sp_port_unsplit(struct mlxsw_core *mlxsw_core, u8 local_port, 3157 + struct netlink_ext_ack *extack) 3163 3158 { 3164 3159 struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); 3165 3160 struct mlxsw_sp_port *mlxsw_sp_port; ··· 3172 3165 if (!mlxsw_sp_port) { 3173 3166 dev_err(mlxsw_sp->bus_info->dev, "Port number \"%d\" does not exist\n", 3174 3167 local_port); 3168 + NL_SET_ERR_MSG_MOD(extack, "Port number does not exist"); 3175 3169 return -EINVAL; 3176 3170 } 3177 3171 3178 3172 if (!mlxsw_sp_port->split) { 3179 - netdev_err(mlxsw_sp_port->dev, "Port wasn't split\n"); 3173 + netdev_err(mlxsw_sp_port->dev, "Port was not split\n"); 3174 + NL_SET_ERR_MSG_MOD(extack, "Port was not split"); 3180 3175 return -EINVAL; 3181 3176 } 3182 3177
+3 -2
drivers/net/ethernet/netronome/nfp/nfp_devlink.c
··· 92 92 93 93 static int 94 94 nfp_devlink_port_split(struct devlink *devlink, unsigned int port_index, 95 - unsigned int count) 95 + unsigned int count, struct netlink_ext_ack *extack) 96 96 { 97 97 struct nfp_pf *pf = devlink_priv(devlink); 98 98 struct nfp_eth_table_port eth_port; ··· 123 123 } 124 124 125 125 static int 126 - nfp_devlink_port_unsplit(struct devlink *devlink, unsigned int port_index) 126 + nfp_devlink_port_unsplit(struct devlink *devlink, unsigned int port_index, 127 + struct netlink_ext_ack *extack) 127 128 { 128 129 struct nfp_pf *pf = devlink_priv(devlink); 129 130 struct nfp_eth_table_port eth_port;
+4 -3
drivers/net/netdevsim/devlink.c
··· 147 147 return err; 148 148 } 149 149 150 - static int nsim_devlink_reload(struct devlink *devlink) 150 + static int nsim_devlink_reload(struct devlink *devlink, 151 + struct netlink_ext_ack *extack) 151 152 { 152 153 enum nsim_resource_id res_ids[] = { 153 154 NSIM_RESOURCE_IPV4_FIB, NSIM_RESOURCE_IPV4_FIB_RULES, ··· 163 162 164 163 err = devlink_resource_size_get(devlink, res_ids[i], &val); 165 164 if (!err) { 166 - err = nsim_fib_set_max(net, res_ids[i], val); 165 + err = nsim_fib_set_max(net, res_ids[i], val, extack); 167 166 if (err) 168 167 return err; 169 168 } ··· 181 180 int i; 182 181 183 182 for (i = 0; i < ARRAY_SIZE(res_ids); ++i) { 184 - if (nsim_fib_set_max(net, res_ids[i], (u64)-1)) { 183 + if (nsim_fib_set_max(net, res_ids[i], (u64)-1, NULL)) { 185 184 pr_err("Failed to reset limit for resource %u\n", 186 185 res_ids[i]); 187 186 }
+6 -3
drivers/net/netdevsim/fib.c
··· 64 64 return max ? entry->max : entry->num; 65 65 } 66 66 67 - int nsim_fib_set_max(struct net *net, enum nsim_resource_id res_id, u64 val) 67 + int nsim_fib_set_max(struct net *net, enum nsim_resource_id res_id, u64 val, 68 + struct netlink_ext_ack *extack) 68 69 { 69 70 struct nsim_fib_data *fib_data = net_generic(net, nsim_fib_net_id); 70 71 struct nsim_fib_entry *entry; ··· 91 90 /* not allowing a new max to be less than curren occupancy 92 91 * --> no means of evicting entries 93 92 */ 94 - if (val < entry->num) 93 + if (val < entry->num) { 94 + NL_SET_ERR_MSG_MOD(extack, "New size is less than current occupancy"); 95 95 err = -EINVAL; 96 - else 96 + } else { 97 97 entry->max = val; 98 + } 98 99 99 100 return err; 100 101 }
+2 -1
drivers/net/netdevsim/netdevsim.h
··· 126 126 int nsim_fib_init(void); 127 127 void nsim_fib_exit(void); 128 128 u64 nsim_fib_get_val(struct net *net, enum nsim_resource_id res_id, bool max); 129 - int nsim_fib_set_max(struct net *net, enum nsim_resource_id res_id, u64 val); 129 + int nsim_fib_set_max(struct net *net, enum nsim_resource_id res_id, u64 val, 130 + struct netlink_ext_ack *extack); 130 131 #else 131 132 static inline int nsim_devlink_setup(struct netdevsim *ns) 132 133 {
+4 -3
include/net/devlink.h
··· 296 296 #define DEVLINK_RESOURCE_ID_PARENT_TOP 0 297 297 298 298 struct devlink_ops { 299 - int (*reload)(struct devlink *devlink); 299 + int (*reload)(struct devlink *devlink, struct netlink_ext_ack *extack); 300 300 int (*port_type_set)(struct devlink_port *devlink_port, 301 301 enum devlink_port_type port_type); 302 302 int (*port_split)(struct devlink *devlink, unsigned int port_index, 303 - unsigned int count); 304 - int (*port_unsplit)(struct devlink *devlink, unsigned int port_index); 303 + unsigned int count, struct netlink_ext_ack *extack); 304 + int (*port_unsplit)(struct devlink *devlink, unsigned int port_index, 305 + struct netlink_ext_ack *extack); 305 306 int (*sb_pool_get)(struct devlink *devlink, unsigned int sb_index, 306 307 u16 pool_index, 307 308 struct devlink_sb_pool_info *pool_info);
+10 -8
net/core/devlink.c
··· 702 702 return 0; 703 703 } 704 704 705 - static int devlink_port_split(struct devlink *devlink, 706 - u32 port_index, u32 count) 705 + static int devlink_port_split(struct devlink *devlink, u32 port_index, 706 + u32 count, struct netlink_ext_ack *extack) 707 707 708 708 { 709 709 if (devlink->ops && devlink->ops->port_split) 710 - return devlink->ops->port_split(devlink, port_index, count); 710 + return devlink->ops->port_split(devlink, port_index, count, 711 + extack); 711 712 return -EOPNOTSUPP; 712 713 } 713 714 ··· 725 724 726 725 port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); 727 726 count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]); 728 - return devlink_port_split(devlink, port_index, count); 727 + return devlink_port_split(devlink, port_index, count, info->extack); 729 728 } 730 729 731 - static int devlink_port_unsplit(struct devlink *devlink, u32 port_index) 730 + static int devlink_port_unsplit(struct devlink *devlink, u32 port_index, 731 + struct netlink_ext_ack *extack) 732 732 733 733 { 734 734 if (devlink->ops && devlink->ops->port_unsplit) 735 - return devlink->ops->port_unsplit(devlink, port_index); 735 + return devlink->ops->port_unsplit(devlink, port_index, extack); 736 736 return -EOPNOTSUPP; 737 737 } 738 738 ··· 747 745 return -EINVAL; 748 746 749 747 port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); 750 - return devlink_port_unsplit(devlink, port_index); 748 + return devlink_port_unsplit(devlink, port_index, info->extack); 751 749 } 752 750 753 751 static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink, ··· 2601 2599 NL_SET_ERR_MSG_MOD(info->extack, "resources size validation failed"); 2602 2600 return err; 2603 2601 } 2604 - return devlink->ops->reload(devlink); 2602 + return devlink->ops->reload(devlink, info->extack); 2605 2603 } 2606 2604 2607 2605 static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {