History

devlink: introduce line card devices support

Line card can contain one or more devices that makes sense to make visible to the user. For example, this can be a gearbox with flash memory, which could be updated. Provide the driver possibility to attach such devices to a line card and expose those to user. Example: $ devlink lc show pci/0000:01:00.0 lc 8 pci/0000:01:00.0: lc 8 state active type 16x100G supported_types: 16x100G devices: device 0 device 1 device 2 device 3

Jiri Pirko committed 4 years ago

Commit 8d92e4f1 parent cfc1d913 files · +113 −1Browse files

Unified · Split

3 files
  1. include/net/devlink.h +7 −0
  2. include/uapi/linux/devlink.h +3 −0
  3. net/core/devlink.c +103 −1
include/net/devlink.h+7−0
@@ -1578,6 +1578,13 @@ struct devlink_linecard * · 1577 unmodified lines
15781578 devlink_linecard_create(struct devlink *devlink, unsigned int linecard_index,
15791579 const struct devlink_linecard_ops *ops, void *priv);
15801580 void devlink_linecard_destroy(struct devlink_linecard *linecard);
1581+struct devlink_linecard_device;
1582+struct devlink_linecard_device *
1583+devlink_linecard_device_create(struct devlink_linecard *linecard,
1584+ unsigned int device_index);
1585+void
1586+devlink_linecard_device_destroy(struct devlink_linecard *linecard,
1587+ struct devlink_linecard_device *linecard_device);
15811588 void devlink_linecard_provision_set(struct devlink_linecard *linecard,
15821589 const char *type);
15831590 void devlink_linecard_provision_clear(struct devlink_linecard *linecard);
include/uapi/linux/devlink.h+3−0
@@ -575,6 +575,9 @@ enum devlink_attr { · 574 unmodified lines
575575 DEVLINK_ATTR_LINECARD_STATE, /* u8 */
576576 DEVLINK_ATTR_LINECARD_TYPE, /* string */
577577 DEVLINK_ATTR_LINECARD_SUPPORTED_TYPES, /* nested */
578+ DEVLINK_ATTR_LINECARD_DEVICE_LIST, /* nested */
579+ DEVLINK_ATTR_LINECARD_DEVICE, /* nested */
580+ DEVLINK_ATTR_LINECARD_DEVICE_INDEX, /* u32 */
578581
579582 /* add new attributes above here, update the policy in devlink.c */
580583
net/core/devlink.c+103−1
@@ -83,10 +83,11 @@ struct devlink_linecard { · 82 unmodified lines
8383 const struct devlink_linecard_ops *ops;
8484 void *priv;
8585 enum devlink_linecard_state state;
86− struct mutex state_lock; /* Protects state */
86+ struct mutex state_lock; /* Protects state and device_list */
8787 const char *type;
8888 struct devlink_linecard_type *types;
8989 unsigned int types_count;
90+ struct list_head device_list;
9091 };
9192
9293 /**
@@ -2058,6 +2059,55 @@ struct devlink_linecard_type { · 1965 unmodified lines
20582059 const void *priv;
20592060 };
20602061
2062+struct devlink_linecard_device {
2063+ struct list_head list;
2064+ unsigned int index;
2065+};
2066+
2067+static int
2068+devlink_nl_linecard_device_fill(struct sk_buff *msg,
2069+ struct devlink_linecard_device *linecard_device)
2070+{
2071+ struct nlattr *attr;
2072+
2073+ attr = nla_nest_start(msg, DEVLINK_ATTR_LINECARD_DEVICE);
2074+ if (!attr)
2075+ return -EMSGSIZE;
2076+ if (nla_put_u32(msg, DEVLINK_ATTR_LINECARD_DEVICE_INDEX,
2077+ linecard_device->index)) {
2078+ nla_nest_cancel(msg, attr);
2079+ return -EMSGSIZE;
2080+ }
2081+ nla_nest_end(msg, attr);
2082+
2083+ return 0;
2084+}
2085+
2086+static int devlink_nl_linecard_devices_fill(struct sk_buff *msg,
2087+ struct devlink_linecard *linecard)
2088+{
2089+ struct devlink_linecard_device *linecard_device;
2090+ struct nlattr *attr;
2091+ int err;
2092+
2093+ if (list_empty(&linecard->device_list))
2094+ return 0;
2095+
2096+ attr = nla_nest_start(msg, DEVLINK_ATTR_LINECARD_DEVICE_LIST);
2097+ if (!attr)
2098+ return -EMSGSIZE;
2099+ list_for_each_entry(linecard_device, &linecard->device_list, list) {
2100+ err = devlink_nl_linecard_device_fill(msg, linecard_device);
2101+ if (err) {
2102+ nla_nest_cancel(msg, attr);
2103+ return err;
2104+ }
2105+ }
2106+ nla_nest_end(msg, attr);
2107+
2108+ return 0;
2109+}
2110+
20612111 static int devlink_nl_linecard_fill(struct sk_buff *msg,
20622112 struct devlink *devlink,
20632113 struct devlink_linecard *linecard,
@@ -2068,6 +2118,7 @@ static int devlink_nl_linecard_fill(struct sk_buff *msg, · 4 unmodified lines
20682118 struct devlink_linecard_type *linecard_type;
20692119 struct nlattr *attr;
20702120 void *hdr;
2121+ int err;
20712122 int i;
20722123
20732124 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
@@ -2100,6 +2151,10 @@ static int devlink_nl_linecard_fill(struct sk_buff *msg, · 26 unmodified lines
21002151 nla_nest_end(msg, attr);
21012152 }
21022153
2154+ err = devlink_nl_linecard_devices_fill(msg, linecard);
2155+ if (err)
2156+ goto nla_put_failure;
2157+
21032158 genlmsg_end(msg, hdr);
21042159 return 0;
21052160
@@ -10264,6 +10319,7 @@ devlink_linecard_create(struct devlink *devlink, unsigned int linecard_index, · 8158 unmodified lines
1026410319 linecard->priv = priv;
1026510320 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
1026610321 mutex_init(&linecard->state_lock);
10322+ INIT_LIST_HEAD(&linecard->device_list);
1026710323
1026810324 err = devlink_linecard_types_init(linecard);
1026910325 if (err) {
@@ -10291,6 +10347,7 @@ void devlink_linecard_destroy(struct devlink_linecard *linecard) · 21 unmodified lines
1029110347 struct devlink *devlink = linecard->devlink;
1029210348
1029310349 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_DEL);
10350+ WARN_ON(!list_empty(&linecard->device_list));
1029410351 mutex_lock(&devlink->linecards_lock);
1029510352 list_del(&linecard->list);
1029610353 devlink_linecard_types_fini(linecard);
@@ -10299,6 +10356,50 @@ void devlink_linecard_destroy(struct devlink_linecard *linecard) · 2 unmodified lines
1029910356 }
1030010357 EXPORT_SYMBOL_GPL(devlink_linecard_destroy);
1030110358
10359+/**
10360+ * devlink_linecard_device_create - Create a device on linecard
10361+ *
10362+ * @linecard: devlink linecard
10363+ * @device_index: index of the linecard device
10364+ *
10365+ * Return: Line card device structure or an ERR_PTR() encoded error code.
10366+ */
10367+struct devlink_linecard_device *
10368+devlink_linecard_device_create(struct devlink_linecard *linecard,
10369+ unsigned int device_index)
10370+{
10371+ struct devlink_linecard_device *linecard_device;
10372+
10373+ linecard_device = kzalloc(sizeof(*linecard_device), GFP_KERNEL);
10374+ if (!linecard_device)
10375+ return ERR_PTR(-ENOMEM);
10376+ linecard_device->index = device_index;
10377+ mutex_lock(&linecard->state_lock);
10378+ list_add_tail(&linecard_device->list, &linecard->device_list);
10379+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10380+ mutex_unlock(&linecard->state_lock);
10381+ return linecard_device;
10382+}
10383+EXPORT_SYMBOL_GPL(devlink_linecard_device_create);
10384+
10385+/**
10386+ * devlink_linecard_device_destroy - Destroy device on linecard
10387+ *
10388+ * @linecard: devlink linecard
10389+ * @linecard_device: devlink linecard device
10390+ */
10391+void
10392+devlink_linecard_device_destroy(struct devlink_linecard *linecard,
10393+ struct devlink_linecard_device *linecard_device)
10394+{
10395+ mutex_lock(&linecard->state_lock);
10396+ list_del(&linecard_device->list);
10397+ devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10398+ mutex_unlock(&linecard->state_lock);
10399+ kfree(linecard_device);
10400+}
10401+EXPORT_SYMBOL_GPL(devlink_linecard_device_destroy);
10402+
1030210403 /**
1030310404 * devlink_linecard_provision_set - Set provisioning on linecard
1030410405 *
@@ -10331,6 +10432,7 @@ EXPORT_SYMBOL_GPL(devlink_linecard_provision_set); · 26 unmodified lines
1033110432 void devlink_linecard_provision_clear(struct devlink_linecard *linecard)
1033210433 {
1033310434 mutex_lock(&linecard->state_lock);
10435+ WARN_ON(!list_empty(&linecard->device_list));
1033410436 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
1033510437 linecard->type = NULL;
1033610438 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);