devlink: pass devlink_port to port_split / port_unsplit callbacks
authorJakub Kicinski <kuba@kernel.org>
Tue, 15 Mar 2022 06:00:09 +0000 (23:00 -0700)
committerJakub Kicinski <kuba@kernel.org>
Wed, 16 Mar 2022 19:56:45 +0000 (12:56 -0700)
Now that devlink ports are protected by the instance lock
it seems natural to pass devlink_port as an argument to
the port_split / port_unsplit callbacks.

This should save the drivers from doing a lookup.

In theory drivers may have supported unsplitting ports
which were not registered prior to this change.

Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Tested-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/mellanox/mlxsw/core.c
drivers/net/ethernet/netronome/nfp/nfp_devlink.c
drivers/net/ethernet/netronome/nfp/nfp_port.c
drivers/net/ethernet/netronome/nfp/nfp_port.h
include/net/devlink.h
net/core/devlink.c

index e2a6a75..b13e0f8 100644 (file)
@@ -1217,36 +1217,37 @@ static void mlxsw_core_fw_params_unregister(struct mlxsw_core *mlxsw_core)
                                  ARRAY_SIZE(mlxsw_core_fw_devlink_params));
 }
 
+static void *__dl_port(struct devlink_port *devlink_port)
+{
+       return container_of(devlink_port, struct mlxsw_core_port, devlink_port);
+}
+
 static int mlxsw_devlink_port_split(struct devlink *devlink,
-                                   unsigned int port_index,
+                                   struct devlink_port *port,
                                    unsigned int count,
                                    struct netlink_ext_ack *extack)
 {
+       struct mlxsw_core_port *mlxsw_core_port = __dl_port(port);
        struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
 
-       if (port_index >= mlxsw_core->max_ports) {
-               NL_SET_ERR_MSG_MOD(extack, "Port index exceeds maximum number of ports");
-               return -EINVAL;
-       }
        if (!mlxsw_core->driver->port_split)
                return -EOPNOTSUPP;
-       return mlxsw_core->driver->port_split(mlxsw_core, port_index, count,
-                                             extack);
+       return mlxsw_core->driver->port_split(mlxsw_core,
+                                             mlxsw_core_port->local_port,
+                                             count, extack);
 }
 
 static int mlxsw_devlink_port_unsplit(struct devlink *devlink,
-                                     unsigned int port_index,
+                                     struct devlink_port *port,
                                      struct netlink_ext_ack *extack)
 {
+       struct mlxsw_core_port *mlxsw_core_port = __dl_port(port);
        struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
 
-       if (port_index >= mlxsw_core->max_ports) {
-               NL_SET_ERR_MSG_MOD(extack, "Port index exceeds maximum number of ports");
-               return -EINVAL;
-       }
        if (!mlxsw_core->driver->port_unsplit)
                return -EOPNOTSUPP;
-       return mlxsw_core->driver->port_unsplit(mlxsw_core, port_index,
+       return mlxsw_core->driver->port_unsplit(mlxsw_core,
+                                               mlxsw_core_port->local_port,
                                                extack);
 }
 
@@ -1280,11 +1281,6 @@ mlxsw_devlink_sb_pool_set(struct devlink *devlink,
                                         extack);
 }
 
-static void *__dl_port(struct devlink_port *devlink_port)
-{
-       return container_of(devlink_port, struct mlxsw_core_port, devlink_port);
-}
-
 static int mlxsw_devlink_port_type_set(struct devlink_port *devlink_port,
                                       enum devlink_port_type port_type)
 {
index 6bd6f4a..48b9556 100644 (file)
@@ -26,12 +26,11 @@ nfp_devlink_fill_eth_port(struct nfp_port *port,
 }
 
 static int
-nfp_devlink_fill_eth_port_from_id(struct nfp_pf *pf, unsigned int port_index,
+nfp_devlink_fill_eth_port_from_id(struct nfp_pf *pf,
+                                 struct devlink_port *dl_port,
                                  struct nfp_eth_table_port *copy)
 {
-       struct nfp_port *port;
-
-       port = nfp_port_from_id(pf, NFP_PORT_PHYS_PORT, port_index);
+       struct nfp_port *port = container_of(dl_port, struct nfp_port, dl_port);
 
        return nfp_devlink_fill_eth_port(port, copy);
 }
@@ -62,7 +61,7 @@ nfp_devlink_set_lanes(struct nfp_pf *pf, unsigned int idx, unsigned int lanes)
 }
 
 static int
-nfp_devlink_port_split(struct devlink *devlink, unsigned int port_index,
+nfp_devlink_port_split(struct devlink *devlink, struct devlink_port *port,
                       unsigned int count, struct netlink_ext_ack *extack)
 {
        struct nfp_pf *pf = devlink_priv(devlink);
@@ -71,7 +70,7 @@ nfp_devlink_port_split(struct devlink *devlink, unsigned int port_index,
        int ret;
 
        rtnl_lock();
-       ret = nfp_devlink_fill_eth_port_from_id(pf, port_index, &eth_port);
+       ret = nfp_devlink_fill_eth_port_from_id(pf, port, &eth_port);
        rtnl_unlock();
        if (ret)
                return ret;
@@ -88,7 +87,7 @@ nfp_devlink_port_split(struct devlink *devlink, unsigned int port_index,
 }
 
 static int
-nfp_devlink_port_unsplit(struct devlink *devlink, unsigned int port_index,
+nfp_devlink_port_unsplit(struct devlink *devlink, struct devlink_port *port,
                         struct netlink_ext_ack *extack)
 {
        struct nfp_pf *pf = devlink_priv(devlink);
@@ -97,7 +96,7 @@ nfp_devlink_port_unsplit(struct devlink *devlink, unsigned int port_index,
        int ret;
 
        rtnl_lock();
-       ret = nfp_devlink_fill_eth_port_from_id(pf, port_index, &eth_port);
+       ret = nfp_devlink_fill_eth_port_from_id(pf, port, &eth_port);
        rtnl_unlock();
        if (ret)
                return ret;
index 236cd3c..4f23085 100644 (file)
@@ -75,24 +75,6 @@ int nfp_port_set_features(struct net_device *netdev, netdev_features_t features)
        return 0;
 }
 
-struct nfp_port *
-nfp_port_from_id(struct nfp_pf *pf, enum nfp_port_type type, unsigned int id)
-{
-       struct devlink *devlink = priv_to_devlink(pf);
-       struct nfp_port *port;
-
-       devl_assert_locked(devlink);
-
-       if (type != NFP_PORT_PHYS_PORT)
-               return NULL;
-
-       list_for_each_entry(port, &pf->ports, port_list)
-               if (port->eth_id == id)
-                       return port;
-
-       return NULL;
-}
-
 struct nfp_eth_table_port *__nfp_port_get_eth_port(struct nfp_port *port)
 {
        if (!port)
index df316b9..d1ebe6c 100644 (file)
@@ -106,8 +106,6 @@ nfp_port_set_features(struct net_device *netdev, netdev_features_t features);
 struct nfp_port *nfp_port_from_netdev(struct net_device *netdev);
 int nfp_port_get_port_parent_id(struct net_device *netdev,
                                struct netdev_phys_item_id *ppid);
-struct nfp_port *
-nfp_port_from_id(struct nfp_pf *pf, enum nfp_port_type type, unsigned int id);
 struct nfp_eth_table_port *__nfp_port_get_eth_port(struct nfp_port *port);
 struct nfp_eth_table_port *nfp_port_get_eth_port(struct nfp_port *port);
 
index 9de0d09..fd89a17 100644 (file)
@@ -1197,9 +1197,9 @@ struct devlink_ops {
                         struct netlink_ext_ack *extack);
        int (*port_type_set)(struct devlink_port *devlink_port,
                             enum devlink_port_type port_type);
-       int (*port_split)(struct devlink *devlink, unsigned int port_index,
+       int (*port_split)(struct devlink *devlink, struct devlink_port *port,
                          unsigned int count, struct netlink_ext_ack *extack);
-       int (*port_unsplit)(struct devlink *devlink, unsigned int port_index,
+       int (*port_unsplit)(struct devlink *devlink, struct devlink_port *port,
                            struct netlink_ext_ack *extack);
        int (*sb_pool_get)(struct devlink *devlink, unsigned int sb_index,
                           u16 pool_index,
index 545ae78..f2a2770 100644 (file)
@@ -1568,35 +1568,20 @@ static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
        return 0;
 }
 
-static int devlink_port_split(struct devlink *devlink, u32 port_index,
-                             u32 count, struct netlink_ext_ack *extack)
-
-{
-       if (devlink->ops->port_split)
-               return devlink->ops->port_split(devlink, port_index, count,
-                                               extack);
-       return -EOPNOTSUPP;
-}
-
 static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
                                          struct genl_info *info)
 {
+       struct devlink_port *devlink_port = info->user_ptr[1];
        struct devlink *devlink = info->user_ptr[0];
-       struct devlink_port *devlink_port;
-       u32 port_index;
        u32 count;
 
-       if (!info->attrs[DEVLINK_ATTR_PORT_INDEX] ||
-           !info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT])
+       if (!info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT])
                return -EINVAL;
+       if (!devlink->ops->port_split)
+               return -EOPNOTSUPP;
 
-       devlink_port = devlink_port_get_from_info(devlink, info);
-       port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
        count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
 
-       if (IS_ERR(devlink_port))
-               return -EINVAL;
-
        if (!devlink_port->attrs.splittable) {
                /* Split ports cannot be split. */
                if (devlink_port->attrs.split)
@@ -1611,29 +1596,19 @@ static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
                return -EINVAL;
        }
 
-       return devlink_port_split(devlink, port_index, count, info->extack);
-}
-
-static int devlink_port_unsplit(struct devlink *devlink, u32 port_index,
-                               struct netlink_ext_ack *extack)
-
-{
-       if (devlink->ops->port_unsplit)
-               return devlink->ops->port_unsplit(devlink, port_index, extack);
-       return -EOPNOTSUPP;
+       return devlink->ops->port_split(devlink, devlink_port, count,
+                                       info->extack);
 }
 
 static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
                                            struct genl_info *info)
 {
+       struct devlink_port *devlink_port = info->user_ptr[1];
        struct devlink *devlink = info->user_ptr[0];
-       u32 port_index;
 
-       if (!info->attrs[DEVLINK_ATTR_PORT_INDEX])
-               return -EINVAL;
-
-       port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
-       return devlink_port_unsplit(devlink, port_index, info->extack);
+       if (!devlink->ops->port_unsplit)
+               return -EOPNOTSUPP;
+       return devlink->ops->port_unsplit(devlink, devlink_port, info->extack);
 }
 
 static int devlink_port_new_notifiy(struct devlink *devlink,
@@ -8672,12 +8647,14 @@ static const struct genl_small_ops devlink_nl_ops[] = {
                .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
                .doit = devlink_nl_cmd_port_split_doit,
                .flags = GENL_ADMIN_PERM,
+               .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
        },
        {
                .cmd = DEVLINK_CMD_PORT_UNSPLIT,
                .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
                .doit = devlink_nl_cmd_port_unsplit_doit,
                .flags = GENL_ADMIN_PERM,
+               .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
        },
        {
                .cmd = DEVLINK_CMD_PORT_NEW,