mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-01 10:42:11 +00:00
netdev-genl: spec: Extend netdev netlink spec in YAML for NAPI
Add support in netlink spec(netdev.yaml) for napi related information. Add code generated from the spec. Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com> Reviewed-by: Sridhar Samudrala <sridhar.samudrala@intel.com> Link: https://lore.kernel.org/r/170147333119.5260.7050639053080529108.stgit@anambiarhost.jf.intel.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
6b6171db7f
commit
ff9991499f
@ -213,6 +213,19 @@ attribute-sets:
|
||||
name: recycle-released-refcnt
|
||||
type: uint
|
||||
|
||||
-
|
||||
name: napi
|
||||
attributes:
|
||||
-
|
||||
name: ifindex
|
||||
doc: ifindex of the netdevice to which NAPI instance belongs.
|
||||
type: u32
|
||||
checks:
|
||||
min: 1
|
||||
-
|
||||
name: id
|
||||
doc: ID of the NAPI instance.
|
||||
type: u32
|
||||
-
|
||||
name: queue
|
||||
attributes:
|
||||
@ -359,6 +372,23 @@ operations:
|
||||
attributes:
|
||||
- ifindex
|
||||
reply: *queue-get-op
|
||||
-
|
||||
name: napi-get
|
||||
doc: Get information about NAPI instances configured on the system.
|
||||
attribute-set: napi
|
||||
do:
|
||||
request:
|
||||
attributes:
|
||||
- id
|
||||
reply: &napi-get-op
|
||||
attributes:
|
||||
- id
|
||||
- ifindex
|
||||
dump:
|
||||
request:
|
||||
attributes:
|
||||
- ifindex
|
||||
reply: *napi-get-op
|
||||
|
||||
mcast-groups:
|
||||
list:
|
||||
|
@ -109,6 +109,14 @@ enum {
|
||||
NETDEV_A_PAGE_POOL_STATS_MAX = (__NETDEV_A_PAGE_POOL_STATS_MAX - 1)
|
||||
};
|
||||
|
||||
enum {
|
||||
NETDEV_A_NAPI_IFINDEX = 1,
|
||||
NETDEV_A_NAPI_ID,
|
||||
|
||||
__NETDEV_A_NAPI_MAX,
|
||||
NETDEV_A_NAPI_MAX = (__NETDEV_A_NAPI_MAX - 1)
|
||||
};
|
||||
|
||||
enum {
|
||||
NETDEV_A_QUEUE_ID = 1,
|
||||
NETDEV_A_QUEUE_IFINDEX,
|
||||
@ -130,6 +138,7 @@ enum {
|
||||
NETDEV_CMD_PAGE_POOL_CHANGE_NTF,
|
||||
NETDEV_CMD_PAGE_POOL_STATS_GET,
|
||||
NETDEV_CMD_QUEUE_GET,
|
||||
NETDEV_CMD_NAPI_GET,
|
||||
|
||||
__NETDEV_CMD_MAX,
|
||||
NETDEV_CMD_MAX = (__NETDEV_CMD_MAX - 1)
|
||||
|
@ -58,6 +58,16 @@ static const struct nla_policy netdev_queue_get_dump_nl_policy[NETDEV_A_QUEUE_IF
|
||||
[NETDEV_A_QUEUE_IFINDEX] = NLA_POLICY_MIN(NLA_U32, 1),
|
||||
};
|
||||
|
||||
/* NETDEV_CMD_NAPI_GET - do */
|
||||
static const struct nla_policy netdev_napi_get_do_nl_policy[NETDEV_A_NAPI_ID + 1] = {
|
||||
[NETDEV_A_NAPI_ID] = { .type = NLA_U32, },
|
||||
};
|
||||
|
||||
/* NETDEV_CMD_NAPI_GET - dump */
|
||||
static const struct nla_policy netdev_napi_get_dump_nl_policy[NETDEV_A_NAPI_IFINDEX + 1] = {
|
||||
[NETDEV_A_NAPI_IFINDEX] = NLA_POLICY_MIN(NLA_U32, 1),
|
||||
};
|
||||
|
||||
/* Ops table for netdev */
|
||||
static const struct genl_split_ops netdev_nl_ops[] = {
|
||||
{
|
||||
@ -114,6 +124,20 @@ static const struct genl_split_ops netdev_nl_ops[] = {
|
||||
.maxattr = NETDEV_A_QUEUE_IFINDEX,
|
||||
.flags = GENL_CMD_CAP_DUMP,
|
||||
},
|
||||
{
|
||||
.cmd = NETDEV_CMD_NAPI_GET,
|
||||
.doit = netdev_nl_napi_get_doit,
|
||||
.policy = netdev_napi_get_do_nl_policy,
|
||||
.maxattr = NETDEV_A_NAPI_ID,
|
||||
.flags = GENL_CMD_CAP_DO,
|
||||
},
|
||||
{
|
||||
.cmd = NETDEV_CMD_NAPI_GET,
|
||||
.dumpit = netdev_nl_napi_get_dumpit,
|
||||
.policy = netdev_napi_get_dump_nl_policy,
|
||||
.maxattr = NETDEV_A_NAPI_IFINDEX,
|
||||
.flags = GENL_CMD_CAP_DUMP,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct genl_multicast_group netdev_nl_mcgrps[] = {
|
||||
|
@ -26,6 +26,8 @@ int netdev_nl_page_pool_stats_get_dumpit(struct sk_buff *skb,
|
||||
int netdev_nl_queue_get_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int netdev_nl_queue_get_dumpit(struct sk_buff *skb,
|
||||
struct netlink_callback *cb);
|
||||
int netdev_nl_napi_get_doit(struct sk_buff *skb, struct genl_info *info);
|
||||
int netdev_nl_napi_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb);
|
||||
|
||||
enum {
|
||||
NETDEV_NLGRP_MGMT,
|
||||
|
@ -155,6 +155,16 @@ int netdev_nl_dev_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
return skb->len;
|
||||
}
|
||||
|
||||
int netdev_nl_napi_get_doit(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
int netdev_nl_napi_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static int
|
||||
netdev_nl_queue_fill_one(struct sk_buff *rsp, struct net_device *netdev,
|
||||
u32 q_idx, u32 q_type, const struct genl_info *info)
|
||||
|
@ -109,6 +109,14 @@ enum {
|
||||
NETDEV_A_PAGE_POOL_STATS_MAX = (__NETDEV_A_PAGE_POOL_STATS_MAX - 1)
|
||||
};
|
||||
|
||||
enum {
|
||||
NETDEV_A_NAPI_IFINDEX = 1,
|
||||
NETDEV_A_NAPI_ID,
|
||||
|
||||
__NETDEV_A_NAPI_MAX,
|
||||
NETDEV_A_NAPI_MAX = (__NETDEV_A_NAPI_MAX - 1)
|
||||
};
|
||||
|
||||
enum {
|
||||
NETDEV_A_QUEUE_ID = 1,
|
||||
NETDEV_A_QUEUE_IFINDEX,
|
||||
@ -130,6 +138,7 @@ enum {
|
||||
NETDEV_CMD_PAGE_POOL_CHANGE_NTF,
|
||||
NETDEV_CMD_PAGE_POOL_STATS_GET,
|
||||
NETDEV_CMD_QUEUE_GET,
|
||||
NETDEV_CMD_NAPI_GET,
|
||||
|
||||
__NETDEV_CMD_MAX,
|
||||
NETDEV_CMD_MAX = (__NETDEV_CMD_MAX - 1)
|
||||
|
@ -24,6 +24,7 @@ static const char * const netdev_op_strmap[] = {
|
||||
[NETDEV_CMD_PAGE_POOL_CHANGE_NTF] = "page-pool-change-ntf",
|
||||
[NETDEV_CMD_PAGE_POOL_STATS_GET] = "page-pool-stats-get",
|
||||
[NETDEV_CMD_QUEUE_GET] = "queue-get",
|
||||
[NETDEV_CMD_NAPI_GET] = "napi-get",
|
||||
};
|
||||
|
||||
const char *netdev_op_str(int op)
|
||||
@ -160,6 +161,16 @@ struct ynl_policy_nest netdev_queue_nest = {
|
||||
.table = netdev_queue_policy,
|
||||
};
|
||||
|
||||
struct ynl_policy_attr netdev_napi_policy[NETDEV_A_NAPI_MAX + 1] = {
|
||||
[NETDEV_A_NAPI_IFINDEX] = { .name = "ifindex", .type = YNL_PT_U32, },
|
||||
[NETDEV_A_NAPI_ID] = { .name = "id", .type = YNL_PT_U32, },
|
||||
};
|
||||
|
||||
struct ynl_policy_nest netdev_napi_nest = {
|
||||
.max_attr = NETDEV_A_NAPI_MAX,
|
||||
.table = netdev_napi_policy,
|
||||
};
|
||||
|
||||
/* Common nested types */
|
||||
void netdev_page_pool_info_free(struct netdev_page_pool_info *obj)
|
||||
{
|
||||
@ -770,6 +781,119 @@ netdev_queue_get_dump(struct ynl_sock *ys,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ============== NETDEV_CMD_NAPI_GET ============== */
|
||||
/* NETDEV_CMD_NAPI_GET - do */
|
||||
void netdev_napi_get_req_free(struct netdev_napi_get_req *req)
|
||||
{
|
||||
free(req);
|
||||
}
|
||||
|
||||
void netdev_napi_get_rsp_free(struct netdev_napi_get_rsp *rsp)
|
||||
{
|
||||
free(rsp);
|
||||
}
|
||||
|
||||
int netdev_napi_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
|
||||
{
|
||||
struct ynl_parse_arg *yarg = data;
|
||||
struct netdev_napi_get_rsp *dst;
|
||||
const struct nlattr *attr;
|
||||
|
||||
dst = yarg->data;
|
||||
|
||||
mnl_attr_for_each(attr, nlh, sizeof(struct genlmsghdr)) {
|
||||
unsigned int type = mnl_attr_get_type(attr);
|
||||
|
||||
if (type == NETDEV_A_NAPI_ID) {
|
||||
if (ynl_attr_validate(yarg, attr))
|
||||
return MNL_CB_ERROR;
|
||||
dst->_present.id = 1;
|
||||
dst->id = mnl_attr_get_u32(attr);
|
||||
} else if (type == NETDEV_A_NAPI_IFINDEX) {
|
||||
if (ynl_attr_validate(yarg, attr))
|
||||
return MNL_CB_ERROR;
|
||||
dst->_present.ifindex = 1;
|
||||
dst->ifindex = mnl_attr_get_u32(attr);
|
||||
}
|
||||
}
|
||||
|
||||
return MNL_CB_OK;
|
||||
}
|
||||
|
||||
struct netdev_napi_get_rsp *
|
||||
netdev_napi_get(struct ynl_sock *ys, struct netdev_napi_get_req *req)
|
||||
{
|
||||
struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
|
||||
struct netdev_napi_get_rsp *rsp;
|
||||
struct nlmsghdr *nlh;
|
||||
int err;
|
||||
|
||||
nlh = ynl_gemsg_start_req(ys, ys->family_id, NETDEV_CMD_NAPI_GET, 1);
|
||||
ys->req_policy = &netdev_napi_nest;
|
||||
yrs.yarg.rsp_policy = &netdev_napi_nest;
|
||||
|
||||
if (req->_present.id)
|
||||
mnl_attr_put_u32(nlh, NETDEV_A_NAPI_ID, req->id);
|
||||
|
||||
rsp = calloc(1, sizeof(*rsp));
|
||||
yrs.yarg.data = rsp;
|
||||
yrs.cb = netdev_napi_get_rsp_parse;
|
||||
yrs.rsp_cmd = NETDEV_CMD_NAPI_GET;
|
||||
|
||||
err = ynl_exec(ys, nlh, &yrs);
|
||||
if (err < 0)
|
||||
goto err_free;
|
||||
|
||||
return rsp;
|
||||
|
||||
err_free:
|
||||
netdev_napi_get_rsp_free(rsp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* NETDEV_CMD_NAPI_GET - dump */
|
||||
void netdev_napi_get_list_free(struct netdev_napi_get_list *rsp)
|
||||
{
|
||||
struct netdev_napi_get_list *next = rsp;
|
||||
|
||||
while ((void *)next != YNL_LIST_END) {
|
||||
rsp = next;
|
||||
next = rsp->next;
|
||||
|
||||
free(rsp);
|
||||
}
|
||||
}
|
||||
|
||||
struct netdev_napi_get_list *
|
||||
netdev_napi_get_dump(struct ynl_sock *ys, struct netdev_napi_get_req_dump *req)
|
||||
{
|
||||
struct ynl_dump_state yds = {};
|
||||
struct nlmsghdr *nlh;
|
||||
int err;
|
||||
|
||||
yds.ys = ys;
|
||||
yds.alloc_sz = sizeof(struct netdev_napi_get_list);
|
||||
yds.cb = netdev_napi_get_rsp_parse;
|
||||
yds.rsp_cmd = NETDEV_CMD_NAPI_GET;
|
||||
yds.rsp_policy = &netdev_napi_nest;
|
||||
|
||||
nlh = ynl_gemsg_start_dump(ys, ys->family_id, NETDEV_CMD_NAPI_GET, 1);
|
||||
ys->req_policy = &netdev_napi_nest;
|
||||
|
||||
if (req->_present.ifindex)
|
||||
mnl_attr_put_u32(nlh, NETDEV_A_NAPI_IFINDEX, req->ifindex);
|
||||
|
||||
err = ynl_exec_dump(ys, nlh, &yds);
|
||||
if (err < 0)
|
||||
goto free_list;
|
||||
|
||||
return yds.first;
|
||||
|
||||
free_list:
|
||||
netdev_napi_get_list_free(yds.first);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct ynl_ntf_info netdev_ntf_info[] = {
|
||||
[NETDEV_CMD_DEV_ADD_NTF] = {
|
||||
.alloc_sz = sizeof(struct netdev_dev_get_ntf),
|
||||
|
@ -360,4 +360,79 @@ struct netdev_queue_get_list *
|
||||
netdev_queue_get_dump(struct ynl_sock *ys,
|
||||
struct netdev_queue_get_req_dump *req);
|
||||
|
||||
/* ============== NETDEV_CMD_NAPI_GET ============== */
|
||||
/* NETDEV_CMD_NAPI_GET - do */
|
||||
struct netdev_napi_get_req {
|
||||
struct {
|
||||
__u32 id:1;
|
||||
} _present;
|
||||
|
||||
__u32 id;
|
||||
};
|
||||
|
||||
static inline struct netdev_napi_get_req *netdev_napi_get_req_alloc(void)
|
||||
{
|
||||
return calloc(1, sizeof(struct netdev_napi_get_req));
|
||||
}
|
||||
void netdev_napi_get_req_free(struct netdev_napi_get_req *req);
|
||||
|
||||
static inline void
|
||||
netdev_napi_get_req_set_id(struct netdev_napi_get_req *req, __u32 id)
|
||||
{
|
||||
req->_present.id = 1;
|
||||
req->id = id;
|
||||
}
|
||||
|
||||
struct netdev_napi_get_rsp {
|
||||
struct {
|
||||
__u32 id:1;
|
||||
__u32 ifindex:1;
|
||||
} _present;
|
||||
|
||||
__u32 id;
|
||||
__u32 ifindex;
|
||||
};
|
||||
|
||||
void netdev_napi_get_rsp_free(struct netdev_napi_get_rsp *rsp);
|
||||
|
||||
/*
|
||||
* Get information about NAPI instances configured on the system.
|
||||
*/
|
||||
struct netdev_napi_get_rsp *
|
||||
netdev_napi_get(struct ynl_sock *ys, struct netdev_napi_get_req *req);
|
||||
|
||||
/* NETDEV_CMD_NAPI_GET - dump */
|
||||
struct netdev_napi_get_req_dump {
|
||||
struct {
|
||||
__u32 ifindex:1;
|
||||
} _present;
|
||||
|
||||
__u32 ifindex;
|
||||
};
|
||||
|
||||
static inline struct netdev_napi_get_req_dump *
|
||||
netdev_napi_get_req_dump_alloc(void)
|
||||
{
|
||||
return calloc(1, sizeof(struct netdev_napi_get_req_dump));
|
||||
}
|
||||
void netdev_napi_get_req_dump_free(struct netdev_napi_get_req_dump *req);
|
||||
|
||||
static inline void
|
||||
netdev_napi_get_req_dump_set_ifindex(struct netdev_napi_get_req_dump *req,
|
||||
__u32 ifindex)
|
||||
{
|
||||
req->_present.ifindex = 1;
|
||||
req->ifindex = ifindex;
|
||||
}
|
||||
|
||||
struct netdev_napi_get_list {
|
||||
struct netdev_napi_get_list *next;
|
||||
struct netdev_napi_get_rsp obj __attribute__((aligned(8)));
|
||||
};
|
||||
|
||||
void netdev_napi_get_list_free(struct netdev_napi_get_list *rsp);
|
||||
|
||||
struct netdev_napi_get_list *
|
||||
netdev_napi_get_dump(struct ynl_sock *ys, struct netdev_napi_get_req_dump *req);
|
||||
|
||||
#endif /* _LINUX_NETDEV_GEN_H */
|
||||
|
Loading…
Reference in New Issue
Block a user