Skip to content

Commit 276910a

Browse files
Jiri Pirkodavem330
Jiri Pirko
authored andcommitted
devlink: introduce line card info get message
Allow the driver to provide per line card info get op to fill-up info, similar to the "devlink dev info". Example: $ devlink lc info pci/0000:01:00.0 lc 8 pci/0000:01:00.0: lc 8 versions: fixed: hw.revision 0 running: ini.version 4 Signed-off-by: Jiri Pirko <[email protected]> Signed-off-by: Ido Schimmel <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 8d92e4f commit 276910a

File tree

4 files changed

+138
-5
lines changed

4 files changed

+138
-5
lines changed

Documentation/networking/devlink/devlink-linecard.rst

+4
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ system. Following operations are provided:
1414
* Get a list of supported line card types.
1515
* Provision of a slot with specific line card type.
1616
* Get and monitor of line card state and its change.
17+
* Get information about line card versions.
1718

1819
Line card according to the type may contain one or more gearboxes
1920
to mux the lanes with certain speed to multiple ports with lanes
@@ -120,3 +121,6 @@ Example usage
120121
121122
# Set slot 8 to be unprovisioned:
122123
$ devlink lc set pci/0000:01:00.0 lc 8 notype
124+
125+
# Set info for slot 8:
126+
$ devlink lc info pci/0000:01:00.0 lc 8

include/net/devlink.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ struct devlink_port_new_attrs {
150150
sfnum_valid:1;
151151
};
152152

153+
struct devlink_info_req;
154+
153155
/**
154156
* struct devlink_linecard_ops - Linecard operations
155157
* @provision: callback to provision the linecard slot with certain
@@ -168,6 +170,7 @@ struct devlink_port_new_attrs {
168170
* provisioned.
169171
* @types_count: callback to get number of supported types
170172
* @types_get: callback to get next type in list
173+
* @info_get: callback to get linecard info
171174
*/
172175
struct devlink_linecard_ops {
173176
int (*provision)(struct devlink_linecard *linecard, void *priv,
@@ -182,6 +185,9 @@ struct devlink_linecard_ops {
182185
void (*types_get)(struct devlink_linecard *linecard,
183186
void *priv, unsigned int index, const char **type,
184187
const void **type_priv);
188+
int (*info_get)(struct devlink_linecard *linecard, void *priv,
189+
struct devlink_info_req *req,
190+
struct netlink_ext_ack *extack);
185191
};
186192

187193
struct devlink_sb_pool_info {
@@ -628,7 +634,6 @@ struct devlink_flash_update_params {
628634
#define DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK BIT(1)
629635

630636
struct devlink_region;
631-
struct devlink_info_req;
632637

633638
/**
634639
* struct devlink_region_ops - Region operations

include/uapi/linux/devlink.h

+2
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ enum devlink_command {
136136
DEVLINK_CMD_LINECARD_NEW,
137137
DEVLINK_CMD_LINECARD_DEL,
138138

139+
DEVLINK_CMD_LINECARD_INFO_GET, /* can dump */
140+
139141
/* add new commands above here */
140142
__DEVLINK_CMD_MAX,
141143
DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1

net/core/devlink.c

+126-4
Original file line numberDiff line numberDiff line change
@@ -2424,6 +2424,125 @@ static int devlink_nl_cmd_linecard_set_doit(struct sk_buff *skb,
24242424
return 0;
24252425
}
24262426

2427+
struct devlink_info_req {
2428+
struct sk_buff *msg;
2429+
};
2430+
2431+
static int
2432+
devlink_nl_linecard_info_fill(struct sk_buff *msg, struct devlink *devlink,
2433+
struct devlink_linecard *linecard,
2434+
enum devlink_command cmd, u32 portid,
2435+
u32 seq, int flags, struct netlink_ext_ack *extack)
2436+
{
2437+
struct devlink_info_req req;
2438+
void *hdr;
2439+
int err;
2440+
2441+
hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2442+
if (!hdr)
2443+
return -EMSGSIZE;
2444+
2445+
err = -EMSGSIZE;
2446+
if (devlink_nl_put_handle(msg, devlink))
2447+
goto nla_put_failure;
2448+
if (nla_put_u32(msg, DEVLINK_ATTR_LINECARD_INDEX, linecard->index))
2449+
goto nla_put_failure;
2450+
2451+
req.msg = msg;
2452+
err = linecard->ops->info_get(linecard, linecard->priv, &req, extack);
2453+
if (err)
2454+
goto nla_put_failure;
2455+
2456+
genlmsg_end(msg, hdr);
2457+
return 0;
2458+
2459+
nla_put_failure:
2460+
genlmsg_cancel(msg, hdr);
2461+
return err;
2462+
}
2463+
2464+
static int devlink_nl_cmd_linecard_info_get_doit(struct sk_buff *skb,
2465+
struct genl_info *info)
2466+
{
2467+
struct devlink_linecard *linecard = info->user_ptr[1];
2468+
struct devlink *devlink = linecard->devlink;
2469+
struct sk_buff *msg;
2470+
int err;
2471+
2472+
if (!linecard->ops->info_get)
2473+
return -EOPNOTSUPP;
2474+
2475+
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2476+
if (!msg)
2477+
return -ENOMEM;
2478+
2479+
mutex_lock(&linecard->state_lock);
2480+
err = devlink_nl_linecard_info_fill(msg, devlink, linecard,
2481+
DEVLINK_CMD_LINECARD_INFO_GET,
2482+
info->snd_portid, info->snd_seq, 0,
2483+
info->extack);
2484+
mutex_unlock(&linecard->state_lock);
2485+
if (err) {
2486+
nlmsg_free(msg);
2487+
return err;
2488+
}
2489+
2490+
return genlmsg_reply(msg, info);
2491+
}
2492+
2493+
static int devlink_nl_cmd_linecard_info_get_dumpit(struct sk_buff *msg,
2494+
struct netlink_callback *cb)
2495+
{
2496+
struct devlink_linecard *linecard;
2497+
struct devlink *devlink;
2498+
int start = cb->args[0];
2499+
unsigned long index;
2500+
int idx = 0;
2501+
int err = 0;
2502+
2503+
mutex_lock(&devlink_mutex);
2504+
xa_for_each_marked(&devlinks, index, devlink, DEVLINK_REGISTERED) {
2505+
if (!devlink_try_get(devlink))
2506+
continue;
2507+
2508+
if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
2509+
goto retry;
2510+
2511+
mutex_lock(&devlink->linecards_lock);
2512+
list_for_each_entry(linecard, &devlink->linecard_list, list) {
2513+
if (idx < start || !linecard->ops->info_get) {
2514+
idx++;
2515+
continue;
2516+
}
2517+
mutex_lock(&linecard->state_lock);
2518+
err = devlink_nl_linecard_info_fill(msg, devlink, linecard,
2519+
DEVLINK_CMD_LINECARD_INFO_GET,
2520+
NETLINK_CB(cb->skb).portid,
2521+
cb->nlh->nlmsg_seq,
2522+
NLM_F_MULTI,
2523+
cb->extack);
2524+
mutex_unlock(&linecard->state_lock);
2525+
if (err) {
2526+
mutex_unlock(&devlink->linecards_lock);
2527+
devlink_put(devlink);
2528+
goto out;
2529+
}
2530+
idx++;
2531+
}
2532+
mutex_unlock(&devlink->linecards_lock);
2533+
retry:
2534+
devlink_put(devlink);
2535+
}
2536+
out:
2537+
mutex_unlock(&devlink_mutex);
2538+
2539+
if (err != -EMSGSIZE)
2540+
return err;
2541+
2542+
cb->args[0] = idx;
2543+
return msg->len;
2544+
}
2545+
24272546
static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,
24282547
struct devlink_sb *devlink_sb,
24292548
enum devlink_command cmd, u32 portid,
@@ -6416,10 +6535,6 @@ static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
64166535
return err;
64176536
}
64186537

6419-
struct devlink_info_req {
6420-
struct sk_buff *msg;
6421-
};
6422-
64236538
int devlink_info_driver_name_put(struct devlink_info_req *req, const char *name)
64246539
{
64256540
return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME, name);
@@ -9139,6 +9254,13 @@ static const struct genl_small_ops devlink_nl_ops[] = {
91399254
.flags = GENL_ADMIN_PERM,
91409255
.internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD,
91419256
},
9257+
{
9258+
.cmd = DEVLINK_CMD_LINECARD_INFO_GET,
9259+
.doit = devlink_nl_cmd_linecard_info_get_doit,
9260+
.dumpit = devlink_nl_cmd_linecard_info_get_dumpit,
9261+
.internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD,
9262+
/* can be retrieved by unprivileged users */
9263+
},
91429264
{
91439265
.cmd = DEVLINK_CMD_SB_GET,
91449266
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,

0 commit comments

Comments
 (0)