net: devlink: introduce nested devlink entity for line card
authorJiri Pirko <jiri@nvidia.com>
Mon, 25 Jul 2022 08:29:16 +0000 (10:29 +0200)
committerJakub Kicinski <kuba@kernel.org>
Tue, 26 Jul 2022 20:50:51 +0000 (13:50 -0700)
For the purpose of exposing device info and allow flash update which is
going to be implemented in follow-up patches, introduce a possibility
for a line card to expose relation to nested devlink entity. The nested
devlink entity represents the line card.

Example:

$ devlink lc show pci/0000:01:00.0 lc 1
pci/0000:01:00.0:
  lc 1 state active type 16x100G nested_devlink auxiliary/mlxsw_core.lc.0
    supported_types:
       16x100G
$ devlink dev show auxiliary/mlxsw_core.lc.0
auxiliary/mlxsw_core.lc.0

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
Acked-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
include/net/devlink.h
include/uapi/linux/devlink.h
net/core/devlink.c

index 780744b..5bd3fac 100644 (file)
@@ -1580,6 +1580,8 @@ void devlink_linecard_provision_clear(struct devlink_linecard *linecard);
 void devlink_linecard_provision_fail(struct devlink_linecard *linecard);
 void devlink_linecard_activate(struct devlink_linecard *linecard);
 void devlink_linecard_deactivate(struct devlink_linecard *linecard);
+void devlink_linecard_nested_dl_set(struct devlink_linecard *linecard,
+                                   struct devlink *nested_devlink);
 int devl_sb_register(struct devlink *devlink, unsigned int sb_index,
                     u32 size, u16 ingress_pools_count,
                     u16 egress_pools_count, u16 ingress_tc_count,
index b3d40a5..5413216 100644 (file)
@@ -576,6 +576,8 @@ enum devlink_attr {
        DEVLINK_ATTR_LINECARD_TYPE,             /* string */
        DEVLINK_ATTR_LINECARD_SUPPORTED_TYPES,  /* nested */
 
+       DEVLINK_ATTR_NESTED_DEVLINK,            /* nested */
+
        /* add new attributes above here, update the policy in devlink.c */
 
        __DEVLINK_ATTR_MAX,
index 865232a..698b2d6 100644 (file)
@@ -89,6 +89,7 @@ struct devlink_linecard {
        const char *type;
        struct devlink_linecard_type *types;
        unsigned int types_count;
+       struct devlink *nested_devlink;
 };
 
 /**
@@ -856,6 +857,24 @@ static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
        return 0;
 }
 
+static int devlink_nl_put_nested_handle(struct sk_buff *msg, struct devlink *devlink)
+{
+       struct nlattr *nested_attr;
+
+       nested_attr = nla_nest_start(msg, DEVLINK_ATTR_NESTED_DEVLINK);
+       if (!nested_attr)
+               return -EMSGSIZE;
+       if (devlink_nl_put_handle(msg, devlink))
+               goto nla_put_failure;
+
+       nla_nest_end(msg, nested_attr);
+       return 0;
+
+nla_put_failure:
+       nla_nest_cancel(msg, nested_attr);
+       return -EMSGSIZE;
+}
+
 struct devlink_reload_combination {
        enum devlink_reload_action action;
        enum devlink_reload_limit limit;
@@ -2135,6 +2154,10 @@ static int devlink_nl_linecard_fill(struct sk_buff *msg,
                nla_nest_end(msg, attr);
        }
 
+       if (linecard->nested_devlink &&
+           devlink_nl_put_nested_handle(msg, linecard->nested_devlink))
+               goto nla_put_failure;
+
        genlmsg_end(msg, hdr);
        return 0;
 
@@ -10255,6 +10278,7 @@ EXPORT_SYMBOL_GPL(devlink_linecard_provision_set);
 void devlink_linecard_provision_clear(struct devlink_linecard *linecard)
 {
        mutex_lock(&linecard->state_lock);
+       WARN_ON(linecard->nested_devlink);
        linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
        linecard->type = NULL;
        devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
@@ -10273,6 +10297,7 @@ EXPORT_SYMBOL_GPL(devlink_linecard_provision_clear);
 void devlink_linecard_provision_fail(struct devlink_linecard *linecard)
 {
        mutex_lock(&linecard->state_lock);
+       WARN_ON(linecard->nested_devlink);
        linecard->state = DEVLINK_LINECARD_STATE_PROVISIONING_FAILED;
        devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
        mutex_unlock(&linecard->state_lock);
@@ -10320,6 +10345,23 @@ void devlink_linecard_deactivate(struct devlink_linecard *linecard)
 }
 EXPORT_SYMBOL_GPL(devlink_linecard_deactivate);
 
+/**
+ *     devlink_linecard_nested_dl_set - Attach/detach nested devlink
+ *                                      instance to linecard.
+ *
+ *     @linecard: devlink linecard
+ *     @nested_devlink: devlink instance to attach or NULL to detach
+ */
+void devlink_linecard_nested_dl_set(struct devlink_linecard *linecard,
+                                   struct devlink *nested_devlink)
+{
+       mutex_lock(&linecard->state_lock);
+       linecard->nested_devlink = nested_devlink;
+       devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
+       mutex_unlock(&linecard->state_lock);
+}
+EXPORT_SYMBOL_GPL(devlink_linecard_nested_dl_set);
+
 int devl_sb_register(struct devlink *devlink, unsigned int sb_index,
                     u32 size, u16 ingress_pools_count,
                     u16 egress_pools_count, u16 ingress_tc_count,