Skip to content

Commit bc87795

Browse files
anambiarinkuba-moo
authored andcommitted
netdev-genl: spec: Extend netdev netlink spec in YAML for queue
Add support in netlink spec(netdev.yaml) for queue information. Add code generated from the spec. Note: The "queue-type" attribute takes values 0 and 1 for rx and tx queue type respectively. Signed-off-by: Amritha Nambiar <[email protected]> Reviewed-by: Sridhar Samudrala <[email protected]> Link: https://lore.kernel.org/r/170147330963.5260.2576294626647300472.stgit@anambiarhost.jf.intel.com Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 3706f14 commit bc87795

File tree

8 files changed

+375
-0
lines changed

8 files changed

+375
-0
lines changed

Documentation/netlink/specs/netdev.yaml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ definitions:
6666
name: tx-checksum
6767
doc:
6868
L3 checksum HW offload is supported by the driver.
69+
-
70+
name: queue-type
71+
type: enum
72+
entries: [ rx, tx ]
6973

7074
attribute-sets:
7175
-
@@ -209,6 +213,31 @@ attribute-sets:
209213
name: recycle-released-refcnt
210214
type: uint
211215

216+
-
217+
name: queue
218+
attributes:
219+
-
220+
name: id
221+
doc: Queue index; most queue types are indexed like a C array, with
222+
indexes starting at 0 and ending at queue count - 1. Queue indexes
223+
are scoped to an interface and queue type.
224+
type: u32
225+
-
226+
name: ifindex
227+
doc: ifindex of the netdevice to which the queue belongs.
228+
type: u32
229+
checks:
230+
min: 1
231+
-
232+
name: type
233+
doc: Queue type as rx, tx. Each queue type defines a separate ID space.
234+
type: u32
235+
enum: queue-type
236+
-
237+
name: napi-id
238+
doc: ID of the NAPI instance which services this queue.
239+
type: u32
240+
212241
operations:
213242
list:
214243
-
@@ -307,6 +336,29 @@ operations:
307336
dump:
308337
reply: *pp-stats-reply
309338
config-cond: page-pool-stats
339+
-
340+
name: queue-get
341+
doc: Get queue information from the kernel.
342+
Only configured queues will be reported (as opposed to all available
343+
hardware queues).
344+
attribute-set: queue
345+
do:
346+
request:
347+
attributes:
348+
- ifindex
349+
- type
350+
- id
351+
reply: &queue-get-op
352+
attributes:
353+
- id
354+
- type
355+
- napi-id
356+
- ifindex
357+
dump:
358+
request:
359+
attributes:
360+
- ifindex
361+
reply: *queue-get-op
310362

311363
mcast-groups:
312364
list:

include/uapi/linux/netdev.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ enum netdev_xsk_flags {
6262
NETDEV_XSK_FLAGS_TX_CHECKSUM = 2,
6363
};
6464

65+
enum netdev_queue_type {
66+
NETDEV_QUEUE_TYPE_RX,
67+
NETDEV_QUEUE_TYPE_TX,
68+
};
69+
6570
enum {
6671
NETDEV_A_DEV_IFINDEX = 1,
6772
NETDEV_A_DEV_PAD,
@@ -104,6 +109,16 @@ enum {
104109
NETDEV_A_PAGE_POOL_STATS_MAX = (__NETDEV_A_PAGE_POOL_STATS_MAX - 1)
105110
};
106111

112+
enum {
113+
NETDEV_A_QUEUE_ID = 1,
114+
NETDEV_A_QUEUE_IFINDEX,
115+
NETDEV_A_QUEUE_TYPE,
116+
NETDEV_A_QUEUE_NAPI_ID,
117+
118+
__NETDEV_A_QUEUE_MAX,
119+
NETDEV_A_QUEUE_MAX = (__NETDEV_A_QUEUE_MAX - 1)
120+
};
121+
107122
enum {
108123
NETDEV_CMD_DEV_GET = 1,
109124
NETDEV_CMD_DEV_ADD_NTF,
@@ -114,6 +129,7 @@ enum {
114129
NETDEV_CMD_PAGE_POOL_DEL_NTF,
115130
NETDEV_CMD_PAGE_POOL_CHANGE_NTF,
116131
NETDEV_CMD_PAGE_POOL_STATS_GET,
132+
NETDEV_CMD_QUEUE_GET,
117133

118134
__NETDEV_CMD_MAX,
119135
NETDEV_CMD_MAX = (__NETDEV_CMD_MAX - 1)

net/core/netdev-genl-gen.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,18 @@ static const struct nla_policy netdev_page_pool_stats_get_nl_policy[NETDEV_A_PAG
4646
};
4747
#endif /* CONFIG_PAGE_POOL_STATS */
4848

49+
/* NETDEV_CMD_QUEUE_GET - do */
50+
static const struct nla_policy netdev_queue_get_do_nl_policy[NETDEV_A_QUEUE_TYPE + 1] = {
51+
[NETDEV_A_QUEUE_IFINDEX] = NLA_POLICY_MIN(NLA_U32, 1),
52+
[NETDEV_A_QUEUE_TYPE] = NLA_POLICY_MAX(NLA_U32, 1),
53+
[NETDEV_A_QUEUE_ID] = { .type = NLA_U32, },
54+
};
55+
56+
/* NETDEV_CMD_QUEUE_GET - dump */
57+
static const struct nla_policy netdev_queue_get_dump_nl_policy[NETDEV_A_QUEUE_IFINDEX + 1] = {
58+
[NETDEV_A_QUEUE_IFINDEX] = NLA_POLICY_MIN(NLA_U32, 1),
59+
};
60+
4961
/* Ops table for netdev */
5062
static const struct genl_split_ops netdev_nl_ops[] = {
5163
{
@@ -88,6 +100,20 @@ static const struct genl_split_ops netdev_nl_ops[] = {
88100
.flags = GENL_CMD_CAP_DUMP,
89101
},
90102
#endif /* CONFIG_PAGE_POOL_STATS */
103+
{
104+
.cmd = NETDEV_CMD_QUEUE_GET,
105+
.doit = netdev_nl_queue_get_doit,
106+
.policy = netdev_queue_get_do_nl_policy,
107+
.maxattr = NETDEV_A_QUEUE_TYPE,
108+
.flags = GENL_CMD_CAP_DO,
109+
},
110+
{
111+
.cmd = NETDEV_CMD_QUEUE_GET,
112+
.dumpit = netdev_nl_queue_get_dumpit,
113+
.policy = netdev_queue_get_dump_nl_policy,
114+
.maxattr = NETDEV_A_QUEUE_IFINDEX,
115+
.flags = GENL_CMD_CAP_DUMP,
116+
},
91117
};
92118

93119
static const struct genl_multicast_group netdev_nl_mcgrps[] = {

net/core/netdev-genl-gen.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ int netdev_nl_page_pool_stats_get_doit(struct sk_buff *skb,
2323
struct genl_info *info);
2424
int netdev_nl_page_pool_stats_get_dumpit(struct sk_buff *skb,
2525
struct netlink_callback *cb);
26+
int netdev_nl_queue_get_doit(struct sk_buff *skb, struct genl_info *info);
27+
int netdev_nl_queue_get_dumpit(struct sk_buff *skb,
28+
struct netlink_callback *cb);
2629

2730
enum {
2831
NETDEV_NLGRP_MGMT,

net/core/netdev-genl.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,16 @@ int netdev_nl_dev_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
140140
return skb->len;
141141
}
142142

143+
int netdev_nl_queue_get_doit(struct sk_buff *skb, struct genl_info *info)
144+
{
145+
return -EOPNOTSUPP;
146+
}
147+
148+
int netdev_nl_queue_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
149+
{
150+
return -EOPNOTSUPP;
151+
}
152+
143153
static int netdev_genl_netdevice_event(struct notifier_block *nb,
144154
unsigned long event, void *ptr)
145155
{

tools/include/uapi/linux/netdev.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ enum netdev_xsk_flags {
6262
NETDEV_XSK_FLAGS_TX_CHECKSUM = 2,
6363
};
6464

65+
enum netdev_queue_type {
66+
NETDEV_QUEUE_TYPE_RX,
67+
NETDEV_QUEUE_TYPE_TX,
68+
};
69+
6570
enum {
6671
NETDEV_A_DEV_IFINDEX = 1,
6772
NETDEV_A_DEV_PAD,
@@ -104,6 +109,16 @@ enum {
104109
NETDEV_A_PAGE_POOL_STATS_MAX = (__NETDEV_A_PAGE_POOL_STATS_MAX - 1)
105110
};
106111

112+
enum {
113+
NETDEV_A_QUEUE_ID = 1,
114+
NETDEV_A_QUEUE_IFINDEX,
115+
NETDEV_A_QUEUE_TYPE,
116+
NETDEV_A_QUEUE_NAPI_ID,
117+
118+
__NETDEV_A_QUEUE_MAX,
119+
NETDEV_A_QUEUE_MAX = (__NETDEV_A_QUEUE_MAX - 1)
120+
};
121+
107122
enum {
108123
NETDEV_CMD_DEV_GET = 1,
109124
NETDEV_CMD_DEV_ADD_NTF,
@@ -114,6 +129,7 @@ enum {
114129
NETDEV_CMD_PAGE_POOL_DEL_NTF,
115130
NETDEV_CMD_PAGE_POOL_CHANGE_NTF,
116131
NETDEV_CMD_PAGE_POOL_STATS_GET,
132+
NETDEV_CMD_QUEUE_GET,
117133

118134
__NETDEV_CMD_MAX,
119135
NETDEV_CMD_MAX = (__NETDEV_CMD_MAX - 1)

tools/net/ynl/generated/netdev-user.c

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ static const char * const netdev_op_strmap[] = {
2323
[NETDEV_CMD_PAGE_POOL_DEL_NTF] = "page-pool-del-ntf",
2424
[NETDEV_CMD_PAGE_POOL_CHANGE_NTF] = "page-pool-change-ntf",
2525
[NETDEV_CMD_PAGE_POOL_STATS_GET] = "page-pool-stats-get",
26+
[NETDEV_CMD_QUEUE_GET] = "queue-get",
2627
};
2728

2829
const char *netdev_op_str(int op)
@@ -76,6 +77,18 @@ const char *netdev_xsk_flags_str(enum netdev_xsk_flags value)
7677
return netdev_xsk_flags_strmap[value];
7778
}
7879

80+
static const char * const netdev_queue_type_strmap[] = {
81+
[0] = "rx",
82+
[1] = "tx",
83+
};
84+
85+
const char *netdev_queue_type_str(enum netdev_queue_type value)
86+
{
87+
if (value < 0 || value >= (int)MNL_ARRAY_SIZE(netdev_queue_type_strmap))
88+
return NULL;
89+
return netdev_queue_type_strmap[value];
90+
}
91+
7992
/* Policies */
8093
struct ynl_policy_attr netdev_page_pool_info_policy[NETDEV_A_PAGE_POOL_MAX + 1] = {
8194
[NETDEV_A_PAGE_POOL_ID] = { .name = "id", .type = YNL_PT_UINT, },
@@ -135,6 +148,18 @@ struct ynl_policy_nest netdev_page_pool_stats_nest = {
135148
.table = netdev_page_pool_stats_policy,
136149
};
137150

151+
struct ynl_policy_attr netdev_queue_policy[NETDEV_A_QUEUE_MAX + 1] = {
152+
[NETDEV_A_QUEUE_ID] = { .name = "id", .type = YNL_PT_U32, },
153+
[NETDEV_A_QUEUE_IFINDEX] = { .name = "ifindex", .type = YNL_PT_U32, },
154+
[NETDEV_A_QUEUE_TYPE] = { .name = "type", .type = YNL_PT_U32, },
155+
[NETDEV_A_QUEUE_NAPI_ID] = { .name = "napi-id", .type = YNL_PT_U32, },
156+
};
157+
158+
struct ynl_policy_nest netdev_queue_nest = {
159+
.max_attr = NETDEV_A_QUEUE_MAX,
160+
.table = netdev_queue_policy,
161+
};
162+
138163
/* Common nested types */
139164
void netdev_page_pool_info_free(struct netdev_page_pool_info *obj)
140165
{
@@ -617,6 +642,134 @@ netdev_page_pool_stats_get_dump(struct ynl_sock *ys)
617642
return NULL;
618643
}
619644

645+
/* ============== NETDEV_CMD_QUEUE_GET ============== */
646+
/* NETDEV_CMD_QUEUE_GET - do */
647+
void netdev_queue_get_req_free(struct netdev_queue_get_req *req)
648+
{
649+
free(req);
650+
}
651+
652+
void netdev_queue_get_rsp_free(struct netdev_queue_get_rsp *rsp)
653+
{
654+
free(rsp);
655+
}
656+
657+
int netdev_queue_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
658+
{
659+
struct ynl_parse_arg *yarg = data;
660+
struct netdev_queue_get_rsp *dst;
661+
const struct nlattr *attr;
662+
663+
dst = yarg->data;
664+
665+
mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
666+
unsigned int type = mnl_attr_get_type(attr);
667+
668+
if (type == NETDEV_A_QUEUE_ID) {
669+
if (ynl_attr_validate(yarg, attr))
670+
return MNL_CB_ERROR;
671+
dst->_present.id = 1;
672+
dst->id = mnl_attr_get_u32(attr);
673+
} else if (type == NETDEV_A_QUEUE_TYPE) {
674+
if (ynl_attr_validate(yarg, attr))
675+
return MNL_CB_ERROR;
676+
dst->_present.type = 1;
677+
dst->type = mnl_attr_get_u32(attr);
678+
} else if (type == NETDEV_A_QUEUE_NAPI_ID) {
679+
if (ynl_attr_validate(yarg, attr))
680+
return MNL_CB_ERROR;
681+
dst->_present.napi_id = 1;
682+
dst->napi_id = mnl_attr_get_u32(attr);
683+
} else if (type == NETDEV_A_QUEUE_IFINDEX) {
684+
if (ynl_attr_validate(yarg, attr))
685+
return MNL_CB_ERROR;
686+
dst->_present.ifindex = 1;
687+
dst->ifindex = mnl_attr_get_u32(attr);
688+
}
689+
}
690+
691+
return MNL_CB_OK;
692+
}
693+
694+
struct netdev_queue_get_rsp *
695+
netdev_queue_get(struct ynl_sock *ys, struct netdev_queue_get_req *req)
696+
{
697+
struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
698+
struct netdev_queue_get_rsp *rsp;
699+
struct nlmsghdr *nlh;
700+
int err;
701+
702+
nlh = ynl_gemsg_start_req(ys, ys->family_id, NETDEV_CMD_QUEUE_GET, 1);
703+
ys->req_policy = &netdev_queue_nest;
704+
yrs.yarg.rsp_policy = &netdev_queue_nest;
705+
706+
if (req->_present.ifindex)
707+
mnl_attr_put_u32(nlh, NETDEV_A_QUEUE_IFINDEX, req->ifindex);
708+
if (req->_present.type)
709+
mnl_attr_put_u32(nlh, NETDEV_A_QUEUE_TYPE, req->type);
710+
if (req->_present.id)
711+
mnl_attr_put_u32(nlh, NETDEV_A_QUEUE_ID, req->id);
712+
713+
rsp = calloc(1, sizeof(*rsp));
714+
yrs.yarg.data = rsp;
715+
yrs.cb = netdev_queue_get_rsp_parse;
716+
yrs.rsp_cmd = NETDEV_CMD_QUEUE_GET;
717+
718+
err = ynl_exec(ys, nlh, &yrs);
719+
if (err < 0)
720+
goto err_free;
721+
722+
return rsp;
723+
724+
err_free:
725+
netdev_queue_get_rsp_free(rsp);
726+
return NULL;
727+
}
728+
729+
/* NETDEV_CMD_QUEUE_GET - dump */
730+
void netdev_queue_get_list_free(struct netdev_queue_get_list *rsp)
731+
{
732+
struct netdev_queue_get_list *next = rsp;
733+
734+
while ((void *)next != YNL_LIST_END) {
735+
rsp = next;
736+
next = rsp->next;
737+
738+
free(rsp);
739+
}
740+
}
741+
742+
struct netdev_queue_get_list *
743+
netdev_queue_get_dump(struct ynl_sock *ys,
744+
struct netdev_queue_get_req_dump *req)
745+
{
746+
struct ynl_dump_state yds = {};
747+
struct nlmsghdr *nlh;
748+
int err;
749+
750+
yds.ys = ys;
751+
yds.alloc_sz = sizeof(struct netdev_queue_get_list);
752+
yds.cb = netdev_queue_get_rsp_parse;
753+
yds.rsp_cmd = NETDEV_CMD_QUEUE_GET;
754+
yds.rsp_policy = &netdev_queue_nest;
755+
756+
nlh = ynl_gemsg_start_dump(ys, ys->family_id, NETDEV_CMD_QUEUE_GET, 1);
757+
ys->req_policy = &netdev_queue_nest;
758+
759+
if (req->_present.ifindex)
760+
mnl_attr_put_u32(nlh, NETDEV_A_QUEUE_IFINDEX, req->ifindex);
761+
762+
err = ynl_exec_dump(ys, nlh, &yds);
763+
if (err < 0)
764+
goto free_list;
765+
766+
return yds.first;
767+
768+
free_list:
769+
netdev_queue_get_list_free(yds.first);
770+
return NULL;
771+
}
772+
620773
static const struct ynl_ntf_info netdev_ntf_info[] = {
621774
[NETDEV_CMD_DEV_ADD_NTF] = {
622775
.alloc_sz = sizeof(struct netdev_dev_get_ntf),

0 commit comments

Comments
 (0)