* [net-next PATCH v3 01/10] netdev-genl: spec: Extend netdev netlink spec in YAML for queue
2023-09-19 22:27 [net-next PATCH v3 00/10] Introduce queue and NAPI support in netdev-genl (Was: Introduce NAPI queues support) Amritha Nambiar
@ 2023-09-19 22:27 ` Amritha Nambiar
2023-09-28 10:33 ` Paolo Abeni
2023-09-19 22:27 ` [net-next PATCH v3 02/10] net: Add queue and napi association Amritha Nambiar
` (8 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Amritha Nambiar @ 2023-09-19 22:27 UTC (permalink / raw)
To: netdev, kuba; +Cc: sridhar.samudrala, amritha.nambiar
Add support in netlink spec(netdev.yaml) for queue information.
Add code generated from the spec.
Note: The "q-type" attribute currently takes values 0 and 1 for rx
and tx queue type respectively. I haven't figured out the ynl
library changes to support string user input ("rx" and "tx") to
enum value conversion in the generated file.
Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
Reviewed-by: Sridhar Samudrala <sridhar.samudrala@intel.com>
---
Documentation/netlink/specs/netdev.yaml | 52 ++++++++++
include/uapi/linux/netdev.h | 17 +++
net/core/netdev-genl-gen.c | 26 +++++
net/core/netdev-genl-gen.h | 3 +
net/core/netdev-genl.c | 10 ++
tools/include/uapi/linux/netdev.h | 17 +++
tools/net/ynl/generated/netdev-user.c | 159 +++++++++++++++++++++++++++++++
tools/net/ynl/generated/netdev-user.h | 101 ++++++++++++++++++++
8 files changed, 385 insertions(+)
diff --git a/Documentation/netlink/specs/netdev.yaml b/Documentation/netlink/specs/netdev.yaml
index c46fcc78fc04..7b5d4cdff48b 100644
--- a/Documentation/netlink/specs/netdev.yaml
+++ b/Documentation/netlink/specs/netdev.yaml
@@ -55,6 +55,10 @@ definitions:
name: hash
doc:
Device is capable of exposing receive packet hash via bpf_xdp_metadata_rx_hash().
+ -
+ name: queue-type
+ type: enum
+ entries: [ rx, tx ]
attribute-sets:
-
@@ -89,6 +93,32 @@ attribute-sets:
enum: xdp-rx-metadata
enum-as-flags: true
+ -
+ name: queue
+ attributes:
+ -
+ name: q-id
+ doc: queue index
+ type: u32
+ -
+ name: ifindex
+ doc: netdev ifindex
+ type: u32
+ checks:
+ min: 1
+ -
+ name: q-type
+ doc: queue type as rx, tx
+ type: u32
+ enum: queue-type
+ -
+ name: napi-id
+ doc: napi id
+ type: u32
+ -
+ name: tx-maxrate
+ type: u32
+
operations:
list:
-
@@ -122,6 +152,28 @@ operations:
doc: Notification about device configuration being changed.
notify: dev-get
mcgrp: mgmt
+ -
+ name: queue-get
+ doc: queue information
+ attribute-set: queue
+ do:
+ request:
+ attributes:
+ - ifindex
+ - q-type
+ - q-id
+ reply: &queue-get-op
+ attributes:
+ - q-id
+ - q-type
+ - napi-id
+ - ifindex
+ - tx-maxrate
+ dump:
+ request:
+ attributes:
+ - ifindex
+ reply: *queue-get-op
mcast-groups:
list:
diff --git a/include/uapi/linux/netdev.h b/include/uapi/linux/netdev.h
index 2943a151d4f1..bb3713231b0b 100644
--- a/include/uapi/linux/netdev.h
+++ b/include/uapi/linux/netdev.h
@@ -53,6 +53,11 @@ enum netdev_xdp_rx_metadata {
NETDEV_XDP_RX_METADATA_MASK = 3,
};
+enum netdev_queue_type {
+ NETDEV_QUEUE_TYPE_RX,
+ NETDEV_QUEUE_TYPE_TX,
+};
+
enum {
NETDEV_A_DEV_IFINDEX = 1,
NETDEV_A_DEV_PAD,
@@ -64,11 +69,23 @@ enum {
NETDEV_A_DEV_MAX = (__NETDEV_A_DEV_MAX - 1)
};
+enum {
+ NETDEV_A_QUEUE_Q_ID = 1,
+ NETDEV_A_QUEUE_IFINDEX,
+ NETDEV_A_QUEUE_Q_TYPE,
+ NETDEV_A_QUEUE_NAPI_ID,
+ NETDEV_A_QUEUE_TX_MAXRATE,
+
+ __NETDEV_A_QUEUE_MAX,
+ NETDEV_A_QUEUE_MAX = (__NETDEV_A_QUEUE_MAX - 1)
+};
+
enum {
NETDEV_CMD_DEV_GET = 1,
NETDEV_CMD_DEV_ADD_NTF,
NETDEV_CMD_DEV_DEL_NTF,
NETDEV_CMD_DEV_CHANGE_NTF,
+ NETDEV_CMD_QUEUE_GET,
__NETDEV_CMD_MAX,
NETDEV_CMD_MAX = (__NETDEV_CMD_MAX - 1)
diff --git a/net/core/netdev-genl-gen.c b/net/core/netdev-genl-gen.c
index ea9231378aa6..e3632ed597b4 100644
--- a/net/core/netdev-genl-gen.c
+++ b/net/core/netdev-genl-gen.c
@@ -15,6 +15,18 @@ static const struct nla_policy netdev_dev_get_nl_policy[NETDEV_A_DEV_IFINDEX + 1
[NETDEV_A_DEV_IFINDEX] = NLA_POLICY_MIN(NLA_U32, 1),
};
+/* NETDEV_CMD_QUEUE_GET - do */
+static const struct nla_policy netdev_queue_get_do_nl_policy[NETDEV_A_QUEUE_Q_TYPE + 1] = {
+ [NETDEV_A_QUEUE_IFINDEX] = NLA_POLICY_MIN(NLA_U32, 1),
+ [NETDEV_A_QUEUE_Q_TYPE] = NLA_POLICY_MAX(NLA_U32, 1),
+ [NETDEV_A_QUEUE_Q_ID] = { .type = NLA_U32, },
+};
+
+/* NETDEV_CMD_QUEUE_GET - dump */
+static const struct nla_policy netdev_queue_get_dump_nl_policy[NETDEV_A_QUEUE_IFINDEX + 1] = {
+ [NETDEV_A_QUEUE_IFINDEX] = NLA_POLICY_MIN(NLA_U32, 1),
+};
+
/* Ops table for netdev */
static const struct genl_split_ops netdev_nl_ops[] = {
{
@@ -29,6 +41,20 @@ static const struct genl_split_ops netdev_nl_ops[] = {
.dumpit = netdev_nl_dev_get_dumpit,
.flags = GENL_CMD_CAP_DUMP,
},
+ {
+ .cmd = NETDEV_CMD_QUEUE_GET,
+ .doit = netdev_nl_queue_get_doit,
+ .policy = netdev_queue_get_do_nl_policy,
+ .maxattr = NETDEV_A_QUEUE_Q_TYPE,
+ .flags = GENL_CMD_CAP_DO,
+ },
+ {
+ .cmd = NETDEV_CMD_QUEUE_GET,
+ .dumpit = netdev_nl_queue_get_dumpit,
+ .policy = netdev_queue_get_dump_nl_policy,
+ .maxattr = NETDEV_A_QUEUE_IFINDEX,
+ .flags = GENL_CMD_CAP_DUMP,
+ },
};
static const struct genl_multicast_group netdev_nl_mcgrps[] = {
diff --git a/net/core/netdev-genl-gen.h b/net/core/netdev-genl-gen.h
index 7b370c073e7d..263c94f77bad 100644
--- a/net/core/netdev-genl-gen.h
+++ b/net/core/netdev-genl-gen.h
@@ -13,6 +13,9 @@
int netdev_nl_dev_get_doit(struct sk_buff *skb, struct genl_info *info);
int netdev_nl_dev_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb);
+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);
enum {
NETDEV_NLGRP_MGMT,
diff --git a/net/core/netdev-genl.c b/net/core/netdev-genl.c
index fe61f85bcf33..336c608e6a6b 100644
--- a/net/core/netdev-genl.c
+++ b/net/core/netdev-genl.c
@@ -129,6 +129,16 @@ int netdev_nl_dev_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
return skb->len;
}
+int netdev_nl_queue_get_doit(struct sk_buff *skb, struct genl_info *info)
+{
+ return -EOPNOTSUPP;
+}
+
+int netdev_nl_queue_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
+{
+ return -EOPNOTSUPP;
+}
+
static int netdev_genl_netdevice_event(struct notifier_block *nb,
unsigned long event, void *ptr)
{
diff --git a/tools/include/uapi/linux/netdev.h b/tools/include/uapi/linux/netdev.h
index 2943a151d4f1..bb3713231b0b 100644
--- a/tools/include/uapi/linux/netdev.h
+++ b/tools/include/uapi/linux/netdev.h
@@ -53,6 +53,11 @@ enum netdev_xdp_rx_metadata {
NETDEV_XDP_RX_METADATA_MASK = 3,
};
+enum netdev_queue_type {
+ NETDEV_QUEUE_TYPE_RX,
+ NETDEV_QUEUE_TYPE_TX,
+};
+
enum {
NETDEV_A_DEV_IFINDEX = 1,
NETDEV_A_DEV_PAD,
@@ -64,11 +69,23 @@ enum {
NETDEV_A_DEV_MAX = (__NETDEV_A_DEV_MAX - 1)
};
+enum {
+ NETDEV_A_QUEUE_Q_ID = 1,
+ NETDEV_A_QUEUE_IFINDEX,
+ NETDEV_A_QUEUE_Q_TYPE,
+ NETDEV_A_QUEUE_NAPI_ID,
+ NETDEV_A_QUEUE_TX_MAXRATE,
+
+ __NETDEV_A_QUEUE_MAX,
+ NETDEV_A_QUEUE_MAX = (__NETDEV_A_QUEUE_MAX - 1)
+};
+
enum {
NETDEV_CMD_DEV_GET = 1,
NETDEV_CMD_DEV_ADD_NTF,
NETDEV_CMD_DEV_DEL_NTF,
NETDEV_CMD_DEV_CHANGE_NTF,
+ NETDEV_CMD_QUEUE_GET,
__NETDEV_CMD_MAX,
NETDEV_CMD_MAX = (__NETDEV_CMD_MAX - 1)
diff --git a/tools/net/ynl/generated/netdev-user.c b/tools/net/ynl/generated/netdev-user.c
index b5ffe8cd1144..749b4bea3c6c 100644
--- a/tools/net/ynl/generated/netdev-user.c
+++ b/tools/net/ynl/generated/netdev-user.c
@@ -18,6 +18,7 @@ static const char * const netdev_op_strmap[] = {
[NETDEV_CMD_DEV_ADD_NTF] = "dev-add-ntf",
[NETDEV_CMD_DEV_DEL_NTF] = "dev-del-ntf",
[NETDEV_CMD_DEV_CHANGE_NTF] = "dev-change-ntf",
+ [NETDEV_CMD_QUEUE_GET] = "queue-get",
};
const char *netdev_op_str(int op)
@@ -58,6 +59,18 @@ const char *netdev_xdp_rx_metadata_str(enum netdev_xdp_rx_metadata value)
return netdev_xdp_rx_metadata_strmap[value];
}
+static const char * const netdev_queue_type_strmap[] = {
+ [0] = "rx",
+ [1] = "tx",
+};
+
+const char *netdev_queue_type_str(enum netdev_queue_type value)
+{
+ if (value < 0 || value >= (int)MNL_ARRAY_SIZE(netdev_queue_type_strmap))
+ return NULL;
+ return netdev_queue_type_strmap[value];
+}
+
/* Policies */
struct ynl_policy_attr netdev_dev_policy[NETDEV_A_DEV_MAX + 1] = {
[NETDEV_A_DEV_IFINDEX] = { .name = "ifindex", .type = YNL_PT_U32, },
@@ -72,6 +85,19 @@ struct ynl_policy_nest netdev_dev_nest = {
.table = netdev_dev_policy,
};
+struct ynl_policy_attr netdev_queue_policy[NETDEV_A_QUEUE_MAX + 1] = {
+ [NETDEV_A_QUEUE_Q_ID] = { .name = "q-id", .type = YNL_PT_U32, },
+ [NETDEV_A_QUEUE_IFINDEX] = { .name = "ifindex", .type = YNL_PT_U32, },
+ [NETDEV_A_QUEUE_Q_TYPE] = { .name = "q-type", .type = YNL_PT_U32, },
+ [NETDEV_A_QUEUE_NAPI_ID] = { .name = "napi-id", .type = YNL_PT_U32, },
+ [NETDEV_A_QUEUE_TX_MAXRATE] = { .name = "tx-maxrate", .type = YNL_PT_U32, },
+};
+
+struct ynl_policy_nest netdev_queue_nest = {
+ .max_attr = NETDEV_A_QUEUE_MAX,
+ .table = netdev_queue_policy,
+};
+
/* Common nested types */
/* ============== NETDEV_CMD_DEV_GET ============== */
/* NETDEV_CMD_DEV_GET - do */
@@ -197,6 +223,139 @@ void netdev_dev_get_ntf_free(struct netdev_dev_get_ntf *rsp)
free(rsp);
}
+/* ============== NETDEV_CMD_QUEUE_GET ============== */
+/* NETDEV_CMD_QUEUE_GET - do */
+void netdev_queue_get_req_free(struct netdev_queue_get_req *req)
+{
+ free(req);
+}
+
+void netdev_queue_get_rsp_free(struct netdev_queue_get_rsp *rsp)
+{
+ free(rsp);
+}
+
+int netdev_queue_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
+{
+ struct ynl_parse_arg *yarg = data;
+ struct netdev_queue_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_QUEUE_Q_ID) {
+ if (ynl_attr_validate(yarg, attr))
+ return MNL_CB_ERROR;
+ dst->_present.q_id = 1;
+ dst->q_id = mnl_attr_get_u32(attr);
+ } else if (type == NETDEV_A_QUEUE_Q_TYPE) {
+ if (ynl_attr_validate(yarg, attr))
+ return MNL_CB_ERROR;
+ dst->_present.q_type = 1;
+ dst->q_type = mnl_attr_get_u32(attr);
+ } else if (type == NETDEV_A_QUEUE_NAPI_ID) {
+ if (ynl_attr_validate(yarg, attr))
+ return MNL_CB_ERROR;
+ dst->_present.napi_id = 1;
+ dst->napi_id = mnl_attr_get_u32(attr);
+ } else if (type == NETDEV_A_QUEUE_IFINDEX) {
+ if (ynl_attr_validate(yarg, attr))
+ return MNL_CB_ERROR;
+ dst->_present.ifindex = 1;
+ dst->ifindex = mnl_attr_get_u32(attr);
+ } else if (type == NETDEV_A_QUEUE_TX_MAXRATE) {
+ if (ynl_attr_validate(yarg, attr))
+ return MNL_CB_ERROR;
+ dst->_present.tx_maxrate = 1;
+ dst->tx_maxrate = mnl_attr_get_u32(attr);
+ }
+ }
+
+ return MNL_CB_OK;
+}
+
+struct netdev_queue_get_rsp *
+netdev_queue_get(struct ynl_sock *ys, struct netdev_queue_get_req *req)
+{
+ struct ynl_req_state yrs = { .yarg = { .ys = ys, }, };
+ struct netdev_queue_get_rsp *rsp;
+ struct nlmsghdr *nlh;
+ int err;
+
+ nlh = ynl_gemsg_start_req(ys, ys->family_id, NETDEV_CMD_QUEUE_GET, 1);
+ ys->req_policy = &netdev_queue_nest;
+ yrs.yarg.rsp_policy = &netdev_queue_nest;
+
+ if (req->_present.ifindex)
+ mnl_attr_put_u32(nlh, NETDEV_A_QUEUE_IFINDEX, req->ifindex);
+ if (req->_present.q_type)
+ mnl_attr_put_u32(nlh, NETDEV_A_QUEUE_Q_TYPE, req->q_type);
+ if (req->_present.q_id)
+ mnl_attr_put_u32(nlh, NETDEV_A_QUEUE_Q_ID, req->q_id);
+
+ rsp = calloc(1, sizeof(*rsp));
+ yrs.yarg.data = rsp;
+ yrs.cb = netdev_queue_get_rsp_parse;
+ yrs.rsp_cmd = NETDEV_CMD_QUEUE_GET;
+
+ err = ynl_exec(ys, nlh, &yrs);
+ if (err < 0)
+ goto err_free;
+
+ return rsp;
+
+err_free:
+ netdev_queue_get_rsp_free(rsp);
+ return NULL;
+}
+
+/* NETDEV_CMD_QUEUE_GET - dump */
+void netdev_queue_get_list_free(struct netdev_queue_get_list *rsp)
+{
+ struct netdev_queue_get_list *next = rsp;
+
+ while ((void *)next != YNL_LIST_END) {
+ rsp = next;
+ next = rsp->next;
+
+ free(rsp);
+ }
+}
+
+struct netdev_queue_get_list *
+netdev_queue_get_dump(struct ynl_sock *ys,
+ struct netdev_queue_get_req_dump *req)
+{
+ struct ynl_dump_state yds = {};
+ struct nlmsghdr *nlh;
+ int err;
+
+ yds.ys = ys;
+ yds.alloc_sz = sizeof(struct netdev_queue_get_list);
+ yds.cb = netdev_queue_get_rsp_parse;
+ yds.rsp_cmd = NETDEV_CMD_QUEUE_GET;
+ yds.rsp_policy = &netdev_queue_nest;
+
+ nlh = ynl_gemsg_start_dump(ys, ys->family_id, NETDEV_CMD_QUEUE_GET, 1);
+ ys->req_policy = &netdev_queue_nest;
+
+ if (req->_present.ifindex)
+ mnl_attr_put_u32(nlh, NETDEV_A_QUEUE_IFINDEX, req->ifindex);
+
+ err = ynl_exec_dump(ys, nlh, &yds);
+ if (err < 0)
+ goto free_list;
+
+ return yds.first;
+
+free_list:
+ netdev_queue_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),
diff --git a/tools/net/ynl/generated/netdev-user.h b/tools/net/ynl/generated/netdev-user.h
index b4351ff34595..cc938c6ba492 100644
--- a/tools/net/ynl/generated/netdev-user.h
+++ b/tools/net/ynl/generated/netdev-user.h
@@ -19,6 +19,7 @@ extern const struct ynl_family ynl_netdev_family;
const char *netdev_op_str(int op);
const char *netdev_xdp_act_str(enum netdev_xdp_act value);
const char *netdev_xdp_rx_metadata_str(enum netdev_xdp_rx_metadata value);
+const char *netdev_queue_type_str(enum netdev_queue_type value);
/* Common nested types */
/* ============== NETDEV_CMD_DEV_GET ============== */
@@ -87,4 +88,104 @@ struct netdev_dev_get_ntf {
void netdev_dev_get_ntf_free(struct netdev_dev_get_ntf *rsp);
+/* ============== NETDEV_CMD_QUEUE_GET ============== */
+/* NETDEV_CMD_QUEUE_GET - do */
+struct netdev_queue_get_req {
+ struct {
+ __u32 ifindex:1;
+ __u32 q_type:1;
+ __u32 q_id:1;
+ } _present;
+
+ __u32 ifindex;
+ enum netdev_queue_type q_type;
+ __u32 q_id;
+};
+
+static inline struct netdev_queue_get_req *netdev_queue_get_req_alloc(void)
+{
+ return calloc(1, sizeof(struct netdev_queue_get_req));
+}
+void netdev_queue_get_req_free(struct netdev_queue_get_req *req);
+
+static inline void
+netdev_queue_get_req_set_ifindex(struct netdev_queue_get_req *req,
+ __u32 ifindex)
+{
+ req->_present.ifindex = 1;
+ req->ifindex = ifindex;
+}
+static inline void
+netdev_queue_get_req_set_q_type(struct netdev_queue_get_req *req,
+ enum netdev_queue_type q_type)
+{
+ req->_present.q_type = 1;
+ req->q_type = q_type;
+}
+static inline void
+netdev_queue_get_req_set_q_id(struct netdev_queue_get_req *req, __u32 q_id)
+{
+ req->_present.q_id = 1;
+ req->q_id = q_id;
+}
+
+struct netdev_queue_get_rsp {
+ struct {
+ __u32 q_id:1;
+ __u32 q_type:1;
+ __u32 napi_id:1;
+ __u32 ifindex:1;
+ __u32 tx_maxrate:1;
+ } _present;
+
+ __u32 q_id;
+ enum netdev_queue_type q_type;
+ __u32 napi_id;
+ __u32 ifindex;
+ __u32 tx_maxrate;
+};
+
+void netdev_queue_get_rsp_free(struct netdev_queue_get_rsp *rsp);
+
+/*
+ * queue information
+ */
+struct netdev_queue_get_rsp *
+netdev_queue_get(struct ynl_sock *ys, struct netdev_queue_get_req *req);
+
+/* NETDEV_CMD_QUEUE_GET - dump */
+struct netdev_queue_get_req_dump {
+ struct {
+ __u32 ifindex:1;
+ } _present;
+
+ __u32 ifindex;
+};
+
+static inline struct netdev_queue_get_req_dump *
+netdev_queue_get_req_dump_alloc(void)
+{
+ return calloc(1, sizeof(struct netdev_queue_get_req_dump));
+}
+void netdev_queue_get_req_dump_free(struct netdev_queue_get_req_dump *req);
+
+static inline void
+netdev_queue_get_req_dump_set_ifindex(struct netdev_queue_get_req_dump *req,
+ __u32 ifindex)
+{
+ req->_present.ifindex = 1;
+ req->ifindex = ifindex;
+}
+
+struct netdev_queue_get_list {
+ struct netdev_queue_get_list *next;
+ struct netdev_queue_get_rsp obj __attribute__ ((aligned (8)));
+};
+
+void netdev_queue_get_list_free(struct netdev_queue_get_list *rsp);
+
+struct netdev_queue_get_list *
+netdev_queue_get_dump(struct ynl_sock *ys,
+ struct netdev_queue_get_req_dump *req);
+
#endif /* _LINUX_NETDEV_GEN_H */
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [net-next PATCH v3 01/10] netdev-genl: spec: Extend netdev netlink spec in YAML for queue
2023-09-19 22:27 ` [net-next PATCH v3 01/10] netdev-genl: spec: Extend netdev netlink spec in YAML for queue Amritha Nambiar
@ 2023-09-28 10:33 ` Paolo Abeni
2023-09-28 23:06 ` Nambiar, Amritha
0 siblings, 1 reply; 19+ messages in thread
From: Paolo Abeni @ 2023-09-28 10:33 UTC (permalink / raw)
To: Amritha Nambiar, netdev, kuba; +Cc: sridhar.samudrala
On Tue, 2023-09-19 at 15:27 -0700, Amritha Nambiar wrote:
> Add support in netlink spec(netdev.yaml) for queue information.
> Add code generated from the spec.
>
> Note: The "q-type" attribute currently takes values 0 and 1 for rx
> and tx queue type respectively. I haven't figured out the ynl
> library changes to support string user input ("rx" and "tx") to
> enum value conversion in the generated file.
>
> Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
> Reviewed-by: Sridhar Samudrala <sridhar.samudrala@intel.com>
> ---
> Documentation/netlink/specs/netdev.yaml | 52 ++++++++++
> include/uapi/linux/netdev.h | 17 +++
> net/core/netdev-genl-gen.c | 26 +++++
> net/core/netdev-genl-gen.h | 3 +
> net/core/netdev-genl.c | 10 ++
> tools/include/uapi/linux/netdev.h | 17 +++
> tools/net/ynl/generated/netdev-user.c | 159 +++++++++++++++++++++++++++++++
> tools/net/ynl/generated/netdev-user.h | 101 ++++++++++++++++++++
> 8 files changed, 385 insertions(+)
>
> diff --git a/Documentation/netlink/specs/netdev.yaml b/Documentation/netlink/specs/netdev.yaml
> index c46fcc78fc04..7b5d4cdff48b 100644
> --- a/Documentation/netlink/specs/netdev.yaml
> +++ b/Documentation/netlink/specs/netdev.yaml
> @@ -55,6 +55,10 @@ definitions:
> name: hash
> doc:
> Device is capable of exposing receive packet hash via bpf_xdp_metadata_rx_hash().
> + -
> + name: queue-type
> + type: enum
> + entries: [ rx, tx ]
>
> attribute-sets:
> -
> @@ -89,6 +93,32 @@ attribute-sets:
> enum: xdp-rx-metadata
> enum-as-flags: true
>
> + -
> + name: queue
> + attributes:
> + -
> + name: q-id
Why not 'queue-id' or 'id'?
> + doc: queue index
> + type: u32
> + -
> + name: ifindex
> + doc: netdev ifindex
> + type: u32
> + checks:
> + min: 1
> + -
> + name: q-type
Same here?
Cheers,
Paolo
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [net-next PATCH v3 01/10] netdev-genl: spec: Extend netdev netlink spec in YAML for queue
2023-09-28 10:33 ` Paolo Abeni
@ 2023-09-28 23:06 ` Nambiar, Amritha
0 siblings, 0 replies; 19+ messages in thread
From: Nambiar, Amritha @ 2023-09-28 23:06 UTC (permalink / raw)
To: Paolo Abeni, netdev, kuba; +Cc: sridhar.samudrala
On 9/28/2023 3:33 AM, Paolo Abeni wrote:
> On Tue, 2023-09-19 at 15:27 -0700, Amritha Nambiar wrote:
>> Add support in netlink spec(netdev.yaml) for queue information.
>> Add code generated from the spec.
>>
>> Note: The "q-type" attribute currently takes values 0 and 1 for rx
>> and tx queue type respectively. I haven't figured out the ynl
>> library changes to support string user input ("rx" and "tx") to
>> enum value conversion in the generated file.
>>
>> Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
>> Reviewed-by: Sridhar Samudrala <sridhar.samudrala@intel.com>
>> ---
>> Documentation/netlink/specs/netdev.yaml | 52 ++++++++++
>> include/uapi/linux/netdev.h | 17 +++
>> net/core/netdev-genl-gen.c | 26 +++++
>> net/core/netdev-genl-gen.h | 3 +
>> net/core/netdev-genl.c | 10 ++
>> tools/include/uapi/linux/netdev.h | 17 +++
>> tools/net/ynl/generated/netdev-user.c | 159 +++++++++++++++++++++++++++++++
>> tools/net/ynl/generated/netdev-user.h | 101 ++++++++++++++++++++
>> 8 files changed, 385 insertions(+)
>>
>> diff --git a/Documentation/netlink/specs/netdev.yaml b/Documentation/netlink/specs/netdev.yaml
>> index c46fcc78fc04..7b5d4cdff48b 100644
>> --- a/Documentation/netlink/specs/netdev.yaml
>> +++ b/Documentation/netlink/specs/netdev.yaml
>> @@ -55,6 +55,10 @@ definitions:
>> name: hash
>> doc:
>> Device is capable of exposing receive packet hash via bpf_xdp_metadata_rx_hash().
>> + -
>> + name: queue-type
>> + type: enum
>> + entries: [ rx, tx ]
>>
>> attribute-sets:
>> -
>> @@ -89,6 +93,32 @@ attribute-sets:
>> enum: xdp-rx-metadata
>> enum-as-flags: true
>>
>> + -
>> + name: queue
>> + attributes:
>> + -
>> + name: q-id
>
> Why not 'queue-id' or 'id'?
>
Okay, I will change this to 'queue-id'.
>> + doc: queue index
>> + type: u32
>> + -
>> + name: ifindex
>> + doc: netdev ifindex
>> + type: u32
>> + checks:
>> + min: 1
>> + -
>> + name: q-type
>
> Same here?
>
Will change to 'queue-type'.
>
>
> Cheers,
>
> Paolo
>
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [net-next PATCH v3 02/10] net: Add queue and napi association
2023-09-19 22:27 [net-next PATCH v3 00/10] Introduce queue and NAPI support in netdev-genl (Was: Introduce NAPI queues support) Amritha Nambiar
2023-09-19 22:27 ` [net-next PATCH v3 01/10] netdev-genl: spec: Extend netdev netlink spec in YAML for queue Amritha Nambiar
@ 2023-09-19 22:27 ` Amritha Nambiar
2023-09-28 10:47 ` Paolo Abeni
2023-09-19 22:27 ` [net-next PATCH v3 03/10] ice: Add support in the driver for associating queue with napi Amritha Nambiar
` (7 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Amritha Nambiar @ 2023-09-19 22:27 UTC (permalink / raw)
To: netdev, kuba; +Cc: sridhar.samudrala, amritha.nambiar
Add the napi pointer in netdev queue for tracking the napi
instance for each queue. This achieves the queue<->napi mapping.
Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
Reviewed-by: Sridhar Samudrala <sridhar.samudrala@intel.com>
---
include/linux/netdevice.h | 5 +++++
include/net/netdev_rx_queue.h | 2 ++
net/core/dev.c | 34 ++++++++++++++++++++++++++++++++++
3 files changed, 41 insertions(+)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index db3d8429d50d..69e363918e4b 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -657,6 +657,8 @@ struct netdev_queue {
unsigned long state;
+ /* NAPI instance for the queue */
+ struct napi_struct *napi;
#ifdef CONFIG_BQL
struct dql dql;
#endif
@@ -2618,6 +2620,9 @@ static inline void *netdev_priv(const struct net_device *dev)
*/
#define SET_NETDEV_DEVTYPE(net, devtype) ((net)->dev.type = (devtype))
+int netif_napi_add_queue(struct napi_struct *napi, unsigned int queue_index,
+ enum netdev_queue_type type);
+
/* Default NAPI poll() weight
* Device drivers are strongly advised to not use bigger value
*/
diff --git a/include/net/netdev_rx_queue.h b/include/net/netdev_rx_queue.h
index cdcafb30d437..2e65b03d214d 100644
--- a/include/net/netdev_rx_queue.h
+++ b/include/net/netdev_rx_queue.h
@@ -21,6 +21,8 @@ struct netdev_rx_queue {
#ifdef CONFIG_XDP_SOCKETS
struct xsk_buff_pool *pool;
#endif
+ /* NAPI instance for the queue */
+ struct napi_struct *napi;
} ____cacheline_aligned_in_smp;
/*
diff --git a/net/core/dev.c b/net/core/dev.c
index cc03a5758d2d..508b1d799681 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6394,6 +6394,40 @@ int dev_set_threaded(struct net_device *dev, bool threaded)
}
EXPORT_SYMBOL(dev_set_threaded);
+/**
+ * netif_napi_add_queue - Associate queue with the napi
+ * @napi: NAPI context
+ * @queue_index: Index of queue
+ * @type: queue type as RX or TX
+ *
+ * Add queue with its corresponding napi context
+ */
+int netif_napi_add_queue(struct napi_struct *napi, unsigned int queue_index,
+ enum netdev_queue_type type)
+{
+ struct net_device *dev = napi->dev;
+ struct netdev_rx_queue *rxq;
+ struct netdev_queue *txq;
+
+ if (!dev)
+ return -EINVAL;
+
+ switch (type) {
+ case NETDEV_QUEUE_TYPE_RX:
+ rxq = __netif_get_rx_queue(dev, queue_index);
+ rxq->napi = napi;
+ break;
+ case NETDEV_QUEUE_TYPE_TX:
+ txq = netdev_get_tx_queue(dev, queue_index);
+ txq->napi = napi;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(netif_napi_add_queue);
+
void netif_napi_add_weight(struct net_device *dev, struct napi_struct *napi,
int (*poll)(struct napi_struct *, int), int weight)
{
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [net-next PATCH v3 02/10] net: Add queue and napi association
2023-09-19 22:27 ` [net-next PATCH v3 02/10] net: Add queue and napi association Amritha Nambiar
@ 2023-09-28 10:47 ` Paolo Abeni
2023-09-28 23:12 ` Nambiar, Amritha
0 siblings, 1 reply; 19+ messages in thread
From: Paolo Abeni @ 2023-09-28 10:47 UTC (permalink / raw)
To: Amritha Nambiar, netdev, kuba; +Cc: sridhar.samudrala
On Tue, 2023-09-19 at 15:27 -0700, Amritha Nambiar wrote:
> Add the napi pointer in netdev queue for tracking the napi
> instance for each queue. This achieves the queue<->napi mapping.
>
> Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
> Reviewed-by: Sridhar Samudrala <sridhar.samudrala@intel.com>
> ---
> include/linux/netdevice.h | 5 +++++
> include/net/netdev_rx_queue.h | 2 ++
> net/core/dev.c | 34 ++++++++++++++++++++++++++++++++++
> 3 files changed, 41 insertions(+)
>
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index db3d8429d50d..69e363918e4b 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -657,6 +657,8 @@ struct netdev_queue {
>
> unsigned long state;
>
> + /* NAPI instance for the queue */
> + struct napi_struct *napi;
This should be probably moved into the 'read-mostly' section, before
the '_xmit_lock' field,
> +/**
> + * netif_napi_add_queue - Associate queue with the napi
> + * @napi: NAPI context
> + * @queue_index: Index of queue
> + * @type: queue type as RX or TX
> + *
> + * Add queue with its corresponding napi context
> + */
> +int netif_napi_add_queue(struct napi_struct *napi, unsigned int queue_index,
> + enum netdev_queue_type type)
Very minor nit and others may have different opinion, but I feel like
this function name is misleading, since at this point both the rx and
tx queue should already exist. Perhaps 'netif_napi_link_queue' ?
Cheers,
Paolo
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [net-next PATCH v3 02/10] net: Add queue and napi association
2023-09-28 10:47 ` Paolo Abeni
@ 2023-09-28 23:12 ` Nambiar, Amritha
0 siblings, 0 replies; 19+ messages in thread
From: Nambiar, Amritha @ 2023-09-28 23:12 UTC (permalink / raw)
To: Paolo Abeni, netdev, kuba; +Cc: sridhar.samudrala
On 9/28/2023 3:47 AM, Paolo Abeni wrote:
> On Tue, 2023-09-19 at 15:27 -0700, Amritha Nambiar wrote:
>> Add the napi pointer in netdev queue for tracking the napi
>> instance for each queue. This achieves the queue<->napi mapping.
>>
>> Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
>> Reviewed-by: Sridhar Samudrala <sridhar.samudrala@intel.com>
>> ---
>> include/linux/netdevice.h | 5 +++++
>> include/net/netdev_rx_queue.h | 2 ++
>> net/core/dev.c | 34 ++++++++++++++++++++++++++++++++++
>> 3 files changed, 41 insertions(+)
>>
>> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
>> index db3d8429d50d..69e363918e4b 100644
>> --- a/include/linux/netdevice.h
>> +++ b/include/linux/netdevice.h
>> @@ -657,6 +657,8 @@ struct netdev_queue {
>>
>> unsigned long state;
>>
>> + /* NAPI instance for the queue */
>> + struct napi_struct *napi;
>
> This should be probably moved into the 'read-mostly' section, before
> the '_xmit_lock' field,
>
Agree. Will fix.
>> +/**
>> + * netif_napi_add_queue - Associate queue with the napi
>> + * @napi: NAPI context
>> + * @queue_index: Index of queue
>> + * @type: queue type as RX or TX
>> + *
>> + * Add queue with its corresponding napi context
>> + */
>> +int netif_napi_add_queue(struct napi_struct *napi, unsigned int queue_index,
>> + enum netdev_queue_type type)
>
> Very minor nit and others may have different opinion, but I feel like
> this function name is misleading, since at this point both the rx and
> tx queue should already exist. Perhaps 'netif_napi_link_queue' ?
>
Sounds right. Since, we are basically just setting the napi for the
queue, and this function may probably be used by both 'queue-get' and
'queue-set' commands in future, does 'netif_queue_set_napi' suit better ?
> Cheers,
>
> Paolo
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [net-next PATCH v3 03/10] ice: Add support in the driver for associating queue with napi
2023-09-19 22:27 [net-next PATCH v3 00/10] Introduce queue and NAPI support in netdev-genl (Was: Introduce NAPI queues support) Amritha Nambiar
2023-09-19 22:27 ` [net-next PATCH v3 01/10] netdev-genl: spec: Extend netdev netlink spec in YAML for queue Amritha Nambiar
2023-09-19 22:27 ` [net-next PATCH v3 02/10] net: Add queue and napi association Amritha Nambiar
@ 2023-09-19 22:27 ` Amritha Nambiar
2023-09-19 22:27 ` [net-next PATCH v3 04/10] netdev-genl: Add netlink framework functions for queue Amritha Nambiar
` (6 subsequent siblings)
9 siblings, 0 replies; 19+ messages in thread
From: Amritha Nambiar @ 2023-09-19 22:27 UTC (permalink / raw)
To: netdev, kuba; +Cc: sridhar.samudrala, amritha.nambiar
After the napi context is initialized, map the napi instance
with the queue/queue-set on the corresponding irq line.
Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
Reviewed-by: Sridhar Samudrala <sridhar.samudrala@intel.com>
---
drivers/net/ethernet/intel/ice/ice_lib.c | 57 +++++++++++++++++++++++++++++
drivers/net/ethernet/intel/ice/ice_lib.h | 4 ++
drivers/net/ethernet/intel/ice/ice_main.c | 4 ++
3 files changed, 64 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
index 01aa3d36b5a7..df1906566185 100644
--- a/drivers/net/ethernet/intel/ice/ice_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
@@ -2461,6 +2461,12 @@ ice_vsi_cfg_def(struct ice_vsi *vsi, struct ice_vsi_cfg_params *params)
goto unroll_vector_base;
ice_vsi_map_rings_to_vectors(vsi);
+
+ /* Associate q_vector rings to napi */
+ ret = ice_vsi_add_napi_queues(vsi);
+ if (ret)
+ goto unroll_vector_base;
+
vsi->stat_offsets_loaded = false;
if (ice_is_xdp_ena_vsi(vsi)) {
@@ -2940,6 +2946,57 @@ void ice_vsi_dis_irq(struct ice_vsi *vsi)
synchronize_irq(vsi->q_vectors[i]->irq.virq);
}
+/**
+ * ice_q_vector_add_napi_queues - Add queue[s] associated with the napi
+ * @q_vector: q_vector pointer
+ *
+ * Associate the q_vector napi with all the queue[s] on the vector
+ * Returns 0 on success or < 0 on error
+ */
+int ice_q_vector_add_napi_queues(struct ice_q_vector *q_vector)
+{
+ struct ice_rx_ring *rx_ring;
+ struct ice_tx_ring *tx_ring;
+ int ret = 0;
+
+ ice_for_each_rx_ring(rx_ring, q_vector->rx) {
+ ret = netif_napi_add_queue(&q_vector->napi, rx_ring->q_index,
+ NETDEV_QUEUE_TYPE_RX);
+ if (ret)
+ return ret;
+ }
+ ice_for_each_tx_ring(tx_ring, q_vector->tx) {
+ ret = netif_napi_add_queue(&q_vector->napi, tx_ring->q_index,
+ NETDEV_QUEUE_TYPE_TX);
+ if (ret)
+ return ret;
+ }
+
+ return ret;
+}
+
+/**
+ * ice_vsi_add_napi_queues
+ * @vsi: VSI pointer
+ *
+ * Associate queue[s] with napi for all vectors
+ * Returns 0 on success or < 0 on error
+ */
+int ice_vsi_add_napi_queues(struct ice_vsi *vsi)
+{
+ int i, ret = 0;
+
+ if (!vsi->netdev)
+ return ret;
+
+ ice_for_each_q_vector(vsi, i) {
+ ret = ice_q_vector_add_napi_queues(vsi->q_vectors[i]);
+ if (ret)
+ return ret;
+ }
+ return ret;
+}
+
/**
* ice_vsi_release - Delete a VSI and free its resources
* @vsi: the VSI being removed
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.h b/drivers/net/ethernet/intel/ice/ice_lib.h
index f24f5d1e6f9c..21d164ac1eed 100644
--- a/drivers/net/ethernet/intel/ice/ice_lib.h
+++ b/drivers/net/ethernet/intel/ice/ice_lib.h
@@ -91,6 +91,10 @@ void ice_vsi_cfg_netdev_tc(struct ice_vsi *vsi, u8 ena_tc);
struct ice_vsi *
ice_vsi_setup(struct ice_pf *pf, struct ice_vsi_cfg_params *params);
+int ice_q_vector_add_napi_queues(struct ice_q_vector *q_vector);
+
+int ice_vsi_add_napi_queues(struct ice_vsi *vsi);
+
int ice_vsi_release(struct ice_vsi *vsi);
void ice_vsi_close(struct ice_vsi *vsi);
diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
index b73d3b1e48d1..140e0e22021d 100644
--- a/drivers/net/ethernet/intel/ice/ice_main.c
+++ b/drivers/net/ethernet/intel/ice/ice_main.c
@@ -3374,9 +3374,11 @@ static void ice_napi_add(struct ice_vsi *vsi)
if (!vsi->netdev)
return;
- ice_for_each_q_vector(vsi, v_idx)
+ ice_for_each_q_vector(vsi, v_idx) {
netif_napi_add(vsi->netdev, &vsi->q_vectors[v_idx]->napi,
ice_napi_poll);
+ ice_q_vector_add_napi_queues(vsi->q_vectors[v_idx]);
+ }
}
/**
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [net-next PATCH v3 04/10] netdev-genl: Add netlink framework functions for queue
2023-09-19 22:27 [net-next PATCH v3 00/10] Introduce queue and NAPI support in netdev-genl (Was: Introduce NAPI queues support) Amritha Nambiar
` (2 preceding siblings ...)
2023-09-19 22:27 ` [net-next PATCH v3 03/10] ice: Add support in the driver for associating queue with napi Amritha Nambiar
@ 2023-09-19 22:27 ` Amritha Nambiar
2023-10-10 9:08 ` Paolo Abeni
2023-09-19 22:27 ` [net-next PATCH v3 05/10] netdev-genl: spec: Extend netdev netlink spec in YAML for NAPI Amritha Nambiar
` (5 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Amritha Nambiar @ 2023-09-19 22:27 UTC (permalink / raw)
To: netdev, kuba; +Cc: sridhar.samudrala, amritha.nambiar
Implement the netdev netlink framework functions for
exposing queue information.
Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
Reviewed-by: Sridhar Samudrala <sridhar.samudrala@intel.com>
---
net/core/netdev-genl.c | 207 +++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 204 insertions(+), 3 deletions(-)
diff --git a/net/core/netdev-genl.c b/net/core/netdev-genl.c
index 336c608e6a6b..ceb7d1722f7c 100644
--- a/net/core/netdev-genl.c
+++ b/net/core/netdev-genl.c
@@ -6,9 +6,24 @@
#include <net/net_namespace.h>
#include <net/sock.h>
#include <net/xdp.h>
+#include <net/netdev_rx_queue.h>
#include "netdev-genl-gen.h"
+struct netdev_nl_dump_ctx {
+ unsigned long ifindex;
+ unsigned int rxq_idx;
+ unsigned int txq_idx;
+};
+
+static inline struct netdev_nl_dump_ctx *
+netdev_dump_ctx(struct netlink_callback *cb)
+{
+ NL_ASSERT_DUMP_CTX_FITS(struct netdev_nl_dump_ctx);
+
+ return (struct netdev_nl_dump_ctx *)cb->ctx;
+}
+
static int
netdev_nl_dev_fill(struct net_device *netdev, struct sk_buff *rsp,
const struct genl_info *info)
@@ -111,12 +126,13 @@ int netdev_nl_dev_get_doit(struct sk_buff *skb, struct genl_info *info)
int netdev_nl_dev_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
{
+ struct netdev_nl_dump_ctx *ctx = netdev_dump_ctx(cb);
struct net *net = sock_net(skb->sk);
struct net_device *netdev;
int err = 0;
rtnl_lock();
- for_each_netdev_dump(net, netdev, cb->args[0]) {
+ for_each_netdev_dump(net, netdev, ctx->ifindex) {
err = netdev_nl_dev_fill(netdev, skb, genl_info_dump(cb));
if (err < 0)
break;
@@ -129,14 +145,199 @@ int netdev_nl_dev_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
return skb->len;
}
+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)
+{
+ struct netdev_rx_queue *rxq;
+ struct netdev_queue *txq;
+ void *hdr;
+
+ hdr = genlmsg_iput(rsp, info);
+ if (!hdr)
+ return -EMSGSIZE;
+
+ if (nla_put_u32(rsp, NETDEV_A_QUEUE_Q_ID, q_idx))
+ goto nla_put_failure;
+
+ if (nla_put_u32(rsp, NETDEV_A_QUEUE_Q_TYPE, q_type))
+ goto nla_put_failure;
+
+ if (nla_put_u32(rsp, NETDEV_A_QUEUE_IFINDEX, netdev->ifindex))
+ goto nla_put_failure;
+
+ switch (q_type) {
+ case NETDEV_QUEUE_TYPE_RX:
+ rxq = __netif_get_rx_queue(netdev, q_idx);
+ if (rxq->napi && nla_put_u32(rsp, NETDEV_A_QUEUE_NAPI_ID,
+ rxq->napi->napi_id))
+ goto nla_put_failure;
+ break;
+ case NETDEV_QUEUE_TYPE_TX:
+ txq = netdev_get_tx_queue(netdev, q_idx);
+ if (txq->napi && nla_put_u32(rsp, NETDEV_A_QUEUE_NAPI_ID,
+ txq->napi->napi_id))
+ goto nla_put_failure;
+
+ if (nla_put_u32(rsp, NETDEV_A_QUEUE_TX_MAXRATE,
+ txq->tx_maxrate))
+ goto nla_put_failure;
+ break;
+ }
+
+ genlmsg_end(rsp, hdr);
+
+ return 0;
+
+nla_put_failure:
+ genlmsg_cancel(rsp, hdr);
+ return -EMSGSIZE;
+}
+
+static int netdev_nl_queue_validate(struct net_device *netdev, u32 q_id, u32 q_type)
+{
+ switch (q_type) {
+ case NETDEV_QUEUE_TYPE_RX:
+ if (q_id >= netdev->real_num_rx_queues)
+ return -EINVAL;
+ return 0;
+ case NETDEV_QUEUE_TYPE_TX:
+ if (q_id >= netdev->real_num_tx_queues)
+ return -EINVAL;
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int
+netdev_nl_queue_fill(struct sk_buff *rsp, struct net_device *netdev, u32 q_idx,
+ u32 q_type, const struct genl_info *info)
+{
+ int err;
+
+ err = netdev_nl_queue_validate(netdev, q_idx, q_type);
+ if (err)
+ return err;
+
+ return netdev_nl_queue_fill_one(rsp, netdev, q_idx, q_type, info);
+}
+
int netdev_nl_queue_get_doit(struct sk_buff *skb, struct genl_info *info)
{
- return -EOPNOTSUPP;
+ u32 q_id, q_type, ifindex;
+ struct net_device *netdev;
+ struct sk_buff *rsp;
+ int err;
+
+ if (GENL_REQ_ATTR_CHECK(info, NETDEV_A_QUEUE_Q_ID))
+ return -EINVAL;
+
+ if (GENL_REQ_ATTR_CHECK(info, NETDEV_A_QUEUE_Q_TYPE))
+ return -EINVAL;
+
+ if (GENL_REQ_ATTR_CHECK(info, NETDEV_A_QUEUE_IFINDEX))
+ return -EINVAL;
+
+ q_id = nla_get_u32(info->attrs[NETDEV_A_QUEUE_Q_ID]);
+
+ q_type = nla_get_u32(info->attrs[NETDEV_A_QUEUE_Q_TYPE]);
+
+ ifindex = nla_get_u32(info->attrs[NETDEV_A_QUEUE_IFINDEX]);
+
+ rsp = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ if (!rsp)
+ return -ENOMEM;
+
+ rtnl_lock();
+
+ netdev = __dev_get_by_index(genl_info_net(info), ifindex);
+ if (netdev)
+ err = netdev_nl_queue_fill(rsp, netdev, q_id, q_type, info);
+ else
+ err = -ENODEV;
+
+ rtnl_unlock();
+
+ if (err)
+ goto err_free_msg;
+
+ return genlmsg_reply(rsp, info);
+
+err_free_msg:
+ nlmsg_free(rsp);
+ return err;
+}
+
+static int
+netdev_nl_queue_dump_one(struct net_device *netdev, struct sk_buff *rsp,
+ const struct genl_info *info, unsigned int *start_rx,
+ unsigned int *start_tx)
+{
+ int err = 0;
+ int i;
+
+ for (i = *start_rx; i < netdev->real_num_rx_queues;) {
+ err = netdev_nl_queue_fill_one(rsp, netdev, i,
+ NETDEV_QUEUE_TYPE_RX, info);
+ if (err)
+ goto out_err;
+ *start_rx = i++;
+ }
+ for (i = *start_tx; i < netdev->real_num_tx_queues;) {
+ err = netdev_nl_queue_fill_one(rsp, netdev, i,
+ NETDEV_QUEUE_TYPE_TX, info);
+ if (err)
+ goto out_err;
+ *start_tx = i++;
+ }
+out_err:
+ return err;
}
int netdev_nl_queue_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
{
- return -EOPNOTSUPP;
+ struct netdev_nl_dump_ctx *ctx = netdev_dump_ctx(cb);
+ const struct genl_info *info = genl_info_dump(cb);
+ struct net *net = sock_net(skb->sk);
+ unsigned int rxq_idx = ctx->rxq_idx;
+ unsigned int txq_idx = ctx->txq_idx;
+ struct net_device *netdev;
+ u32 ifindex = 0;
+ int err = 0;
+
+ if (info->attrs[NETDEV_A_QUEUE_IFINDEX])
+ ifindex = nla_get_u32(info->attrs[NETDEV_A_QUEUE_IFINDEX]);
+
+ rtnl_lock();
+ if (ifindex) {
+ netdev = __dev_get_by_index(net, ifindex);
+ if (netdev)
+ err = netdev_nl_queue_dump_one(netdev, skb, info,
+ &rxq_idx, &txq_idx);
+ else
+ err = -ENODEV;
+ } else {
+ for_each_netdev_dump(net, netdev, ctx->ifindex) {
+ err = netdev_nl_queue_dump_one(netdev, skb, info,
+ &rxq_idx, &txq_idx);
+
+ if (err < 0)
+ break;
+ if (!err) {
+ rxq_idx = 0;
+ txq_idx = 0;
+ }
+ }
+ }
+ rtnl_unlock();
+
+ if (err != -EMSGSIZE)
+ return err;
+
+ ctx->rxq_idx = rxq_idx;
+ ctx->txq_idx = txq_idx;
+ return skb->len;
}
static int netdev_genl_netdevice_event(struct notifier_block *nb,
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [net-next PATCH v3 04/10] netdev-genl: Add netlink framework functions for queue
2023-09-19 22:27 ` [net-next PATCH v3 04/10] netdev-genl: Add netlink framework functions for queue Amritha Nambiar
@ 2023-10-10 9:08 ` Paolo Abeni
2023-10-10 19:57 ` Nambiar, Amritha
0 siblings, 1 reply; 19+ messages in thread
From: Paolo Abeni @ 2023-10-10 9:08 UTC (permalink / raw)
To: Amritha Nambiar, netdev, kuba; +Cc: sridhar.samudrala
On Tue, 2023-09-19 at 15:27 -0700, Amritha Nambiar wrote:
> Implement the netdev netlink framework functions for
> exposing queue information.
>
> Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
> Reviewed-by: Sridhar Samudrala <sridhar.samudrala@intel.com>
> ---
> net/core/netdev-genl.c | 207 +++++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 204 insertions(+), 3 deletions(-)
>
> diff --git a/net/core/netdev-genl.c b/net/core/netdev-genl.c
> index 336c608e6a6b..ceb7d1722f7c 100644
> --- a/net/core/netdev-genl.c
> +++ b/net/core/netdev-genl.c
[...]
> int netdev_nl_queue_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
> {
> - return -EOPNOTSUPP;
> + struct netdev_nl_dump_ctx *ctx = netdev_dump_ctx(cb);
> + const struct genl_info *info = genl_info_dump(cb);
> + struct net *net = sock_net(skb->sk);
> + unsigned int rxq_idx = ctx->rxq_idx;
> + unsigned int txq_idx = ctx->txq_idx;
> + struct net_device *netdev;
> + u32 ifindex = 0;
> + int err = 0;
> +
> + if (info->attrs[NETDEV_A_QUEUE_IFINDEX])
> + ifindex = nla_get_u32(info->attrs[NETDEV_A_QUEUE_IFINDEX]);
> +
> + rtnl_lock();
> + if (ifindex) {
> + netdev = __dev_get_by_index(net, ifindex);
> + if (netdev)
> + err = netdev_nl_queue_dump_one(netdev, skb, info,
> + &rxq_idx, &txq_idx);
> + else
> + err = -ENODEV;
> + } else {
> + for_each_netdev_dump(net, netdev, ctx->ifindex) {
> + err = netdev_nl_queue_dump_one(netdev, skb, info,
> + &rxq_idx, &txq_idx);
> +
> + if (err < 0)
> + break;
> + if (!err) {
> + rxq_idx = 0;
> + txq_idx = 0;
AFAICS, above 'err' can be either < 0 or == 0. The second test: '!err'
should be unneeded and is a bit confusing.
Cheers,
Paolo
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [net-next PATCH v3 04/10] netdev-genl: Add netlink framework functions for queue
2023-10-10 9:08 ` Paolo Abeni
@ 2023-10-10 19:57 ` Nambiar, Amritha
0 siblings, 0 replies; 19+ messages in thread
From: Nambiar, Amritha @ 2023-10-10 19:57 UTC (permalink / raw)
To: Paolo Abeni, netdev, kuba; +Cc: sridhar.samudrala
On 10/10/2023 2:08 AM, Paolo Abeni wrote:
> On Tue, 2023-09-19 at 15:27 -0700, Amritha Nambiar wrote:
>> Implement the netdev netlink framework functions for
>> exposing queue information.
>>
>> Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
>> Reviewed-by: Sridhar Samudrala <sridhar.samudrala@intel.com>
>> ---
>> net/core/netdev-genl.c | 207 +++++++++++++++++++++++++++++++++++++++++++++++-
>> 1 file changed, 204 insertions(+), 3 deletions(-)
>>
>> diff --git a/net/core/netdev-genl.c b/net/core/netdev-genl.c
>> index 336c608e6a6b..ceb7d1722f7c 100644
>> --- a/net/core/netdev-genl.c
>> +++ b/net/core/netdev-genl.c
> [...]
>> int netdev_nl_queue_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
>> {
>> - return -EOPNOTSUPP;
>> + struct netdev_nl_dump_ctx *ctx = netdev_dump_ctx(cb);
>> + const struct genl_info *info = genl_info_dump(cb);
>> + struct net *net = sock_net(skb->sk);
>> + unsigned int rxq_idx = ctx->rxq_idx;
>> + unsigned int txq_idx = ctx->txq_idx;
>> + struct net_device *netdev;
>> + u32 ifindex = 0;
>> + int err = 0;
>> +
>> + if (info->attrs[NETDEV_A_QUEUE_IFINDEX])
>> + ifindex = nla_get_u32(info->attrs[NETDEV_A_QUEUE_IFINDEX]);
>> +
>> + rtnl_lock();
>> + if (ifindex) {
>> + netdev = __dev_get_by_index(net, ifindex);
>> + if (netdev)
>> + err = netdev_nl_queue_dump_one(netdev, skb, info,
>> + &rxq_idx, &txq_idx);
>> + else
>> + err = -ENODEV;
>> + } else {
>> + for_each_netdev_dump(net, netdev, ctx->ifindex) {
>> + err = netdev_nl_queue_dump_one(netdev, skb, info,
>> + &rxq_idx, &txq_idx);
>> +
>> + if (err < 0)
>> + break;
>> + if (!err) {
>> + rxq_idx = 0;
>> + txq_idx = 0;
>
> AFAICS, above 'err' can be either < 0 or == 0. The second test: '!err'
> should be unneeded and is a bit confusing.
Sure, will fix and submit v5. Just checking, this comment is on v3
series, I had submitted a v4 addressing your previous comments.
>
> Cheers,
>
> Paolo
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [net-next PATCH v3 05/10] netdev-genl: spec: Extend netdev netlink spec in YAML for NAPI
2023-09-19 22:27 [net-next PATCH v3 00/10] Introduce queue and NAPI support in netdev-genl (Was: Introduce NAPI queues support) Amritha Nambiar
` (3 preceding siblings ...)
2023-09-19 22:27 ` [net-next PATCH v3 04/10] netdev-genl: Add netlink framework functions for queue Amritha Nambiar
@ 2023-09-19 22:27 ` Amritha Nambiar
2023-09-19 22:27 ` [net-next PATCH v3 06/10] netdev-genl: Add netlink framework functions for napi Amritha Nambiar
` (4 subsequent siblings)
9 siblings, 0 replies; 19+ messages in thread
From: Amritha Nambiar @ 2023-09-19 22:27 UTC (permalink / raw)
To: netdev, kuba; +Cc: sridhar.samudrala, amritha.nambiar
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>
---
Documentation/netlink/specs/netdev.yaml | 30 ++++++++
include/uapi/linux/netdev.h | 9 ++
net/core/netdev-genl-gen.c | 24 ++++++
net/core/netdev-genl-gen.h | 2 +
net/core/netdev-genl.c | 10 +++
tools/include/uapi/linux/netdev.h | 9 ++
tools/net/ynl/generated/netdev-user.c | 124 +++++++++++++++++++++++++++++++
tools/net/ynl/generated/netdev-user.h | 75 +++++++++++++++++++
8 files changed, 283 insertions(+)
diff --git a/Documentation/netlink/specs/netdev.yaml b/Documentation/netlink/specs/netdev.yaml
index 7b5d4cdff48b..446457f0c330 100644
--- a/Documentation/netlink/specs/netdev.yaml
+++ b/Documentation/netlink/specs/netdev.yaml
@@ -93,6 +93,19 @@ attribute-sets:
enum: xdp-rx-metadata
enum-as-flags: true
+ -
+ name: napi
+ attributes:
+ -
+ name: ifindex
+ doc: netdev ifindex
+ type: u32
+ checks:
+ min: 1
+ -
+ name: napi-id
+ doc: napi id
+ type: u32
-
name: queue
attributes:
@@ -174,6 +187,23 @@ operations:
attributes:
- ifindex
reply: *queue-get-op
+ -
+ name: napi-get
+ doc: napi information such as napi-id
+ attribute-set: napi
+ do:
+ request:
+ attributes:
+ - napi-id
+ reply: &napi-get-op
+ attributes:
+ - napi-id
+ - ifindex
+ dump:
+ request:
+ attributes:
+ - ifindex
+ reply: *napi-get-op
mcast-groups:
list:
diff --git a/include/uapi/linux/netdev.h b/include/uapi/linux/netdev.h
index bb3713231b0b..96535b980065 100644
--- a/include/uapi/linux/netdev.h
+++ b/include/uapi/linux/netdev.h
@@ -69,6 +69,14 @@ enum {
NETDEV_A_DEV_MAX = (__NETDEV_A_DEV_MAX - 1)
};
+enum {
+ NETDEV_A_NAPI_IFINDEX = 1,
+ NETDEV_A_NAPI_NAPI_ID,
+
+ __NETDEV_A_NAPI_MAX,
+ NETDEV_A_NAPI_MAX = (__NETDEV_A_NAPI_MAX - 1)
+};
+
enum {
NETDEV_A_QUEUE_Q_ID = 1,
NETDEV_A_QUEUE_IFINDEX,
@@ -86,6 +94,7 @@ enum {
NETDEV_CMD_DEV_DEL_NTF,
NETDEV_CMD_DEV_CHANGE_NTF,
NETDEV_CMD_QUEUE_GET,
+ NETDEV_CMD_NAPI_GET,
__NETDEV_CMD_MAX,
NETDEV_CMD_MAX = (__NETDEV_CMD_MAX - 1)
diff --git a/net/core/netdev-genl-gen.c b/net/core/netdev-genl-gen.c
index e3632ed597b4..1ed436888e8e 100644
--- a/net/core/netdev-genl-gen.c
+++ b/net/core/netdev-genl-gen.c
@@ -27,6 +27,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_NAPI_ID + 1] = {
+ [NETDEV_A_NAPI_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[] = {
{
@@ -55,6 +65,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_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[] = {
diff --git a/net/core/netdev-genl-gen.h b/net/core/netdev-genl-gen.h
index 263c94f77bad..ffc94956d1f5 100644
--- a/net/core/netdev-genl-gen.h
+++ b/net/core/netdev-genl-gen.h
@@ -16,6 +16,8 @@ int netdev_nl_dev_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb);
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,
diff --git a/net/core/netdev-genl.c b/net/core/netdev-genl.c
index ceb7d1722f7c..8609884fefe4 100644
--- a/net/core/netdev-genl.c
+++ b/net/core/netdev-genl.c
@@ -145,6 +145,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)
diff --git a/tools/include/uapi/linux/netdev.h b/tools/include/uapi/linux/netdev.h
index bb3713231b0b..96535b980065 100644
--- a/tools/include/uapi/linux/netdev.h
+++ b/tools/include/uapi/linux/netdev.h
@@ -69,6 +69,14 @@ enum {
NETDEV_A_DEV_MAX = (__NETDEV_A_DEV_MAX - 1)
};
+enum {
+ NETDEV_A_NAPI_IFINDEX = 1,
+ NETDEV_A_NAPI_NAPI_ID,
+
+ __NETDEV_A_NAPI_MAX,
+ NETDEV_A_NAPI_MAX = (__NETDEV_A_NAPI_MAX - 1)
+};
+
enum {
NETDEV_A_QUEUE_Q_ID = 1,
NETDEV_A_QUEUE_IFINDEX,
@@ -86,6 +94,7 @@ enum {
NETDEV_CMD_DEV_DEL_NTF,
NETDEV_CMD_DEV_CHANGE_NTF,
NETDEV_CMD_QUEUE_GET,
+ NETDEV_CMD_NAPI_GET,
__NETDEV_CMD_MAX,
NETDEV_CMD_MAX = (__NETDEV_CMD_MAX - 1)
diff --git a/tools/net/ynl/generated/netdev-user.c b/tools/net/ynl/generated/netdev-user.c
index 749b4bea3c6c..190e17c37063 100644
--- a/tools/net/ynl/generated/netdev-user.c
+++ b/tools/net/ynl/generated/netdev-user.c
@@ -19,6 +19,7 @@ static const char * const netdev_op_strmap[] = {
[NETDEV_CMD_DEV_DEL_NTF] = "dev-del-ntf",
[NETDEV_CMD_DEV_CHANGE_NTF] = "dev-change-ntf",
[NETDEV_CMD_QUEUE_GET] = "queue-get",
+ [NETDEV_CMD_NAPI_GET] = "napi-get",
};
const char *netdev_op_str(int op)
@@ -98,6 +99,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_NAPI_ID] = { .name = "napi-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 */
/* ============== NETDEV_CMD_DEV_GET ============== */
/* NETDEV_CMD_DEV_GET - do */
@@ -356,6 +367,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_NAPI_ID) {
+ if (ynl_attr_validate(yarg, attr))
+ return MNL_CB_ERROR;
+ dst->_present.napi_id = 1;
+ dst->napi_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.napi_id)
+ mnl_attr_put_u32(nlh, NETDEV_A_NAPI_NAPI_ID, req->napi_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),
diff --git a/tools/net/ynl/generated/netdev-user.h b/tools/net/ynl/generated/netdev-user.h
index cc938c6ba492..78b1eae9219a 100644
--- a/tools/net/ynl/generated/netdev-user.h
+++ b/tools/net/ynl/generated/netdev-user.h
@@ -188,4 +188,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 napi_id:1;
+ } _present;
+
+ __u32 napi_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_napi_id(struct netdev_napi_get_req *req, __u32 napi_id)
+{
+ req->_present.napi_id = 1;
+ req->napi_id = napi_id;
+}
+
+struct netdev_napi_get_rsp {
+ struct {
+ __u32 napi_id:1;
+ __u32 ifindex:1;
+ } _present;
+
+ __u32 napi_id;
+ __u32 ifindex;
+};
+
+void netdev_napi_get_rsp_free(struct netdev_napi_get_rsp *rsp);
+
+/*
+ * napi information such as napi-id
+ */
+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 */
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [net-next PATCH v3 06/10] netdev-genl: Add netlink framework functions for napi
2023-09-19 22:27 [net-next PATCH v3 00/10] Introduce queue and NAPI support in netdev-genl (Was: Introduce NAPI queues support) Amritha Nambiar
` (4 preceding siblings ...)
2023-09-19 22:27 ` [net-next PATCH v3 05/10] netdev-genl: spec: Extend netdev netlink spec in YAML for NAPI Amritha Nambiar
@ 2023-09-19 22:27 ` Amritha Nambiar
2023-09-28 11:19 ` Paolo Abeni
2023-09-19 22:27 ` [net-next PATCH v3 07/10] netdev-genl: spec: Add irq in netdev netlink YAML spec Amritha Nambiar
` (3 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Amritha Nambiar @ 2023-09-19 22:27 UTC (permalink / raw)
To: netdev, kuba; +Cc: sridhar.samudrala, amritha.nambiar
Implement the netdev netlink framework functions for
napi support. The netdev structure tracks all the napi
instances and napi fields. The napi instances and associated
parameters can be retrieved this way.
Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
Reviewed-by: Sridhar Samudrala <sridhar.samudrala@intel.com>
---
include/linux/netdevice.h | 2 +
net/core/dev.c | 4 +-
net/core/netdev-genl.c | 117 ++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 119 insertions(+), 4 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 69e363918e4b..e7321178dc1a 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -536,6 +536,8 @@ static inline bool napi_complete(struct napi_struct *n)
return napi_complete_done(n, 0);
}
+struct napi_struct *napi_by_id(unsigned int napi_id);
+
int dev_set_threaded(struct net_device *dev, bool threaded);
/**
diff --git a/net/core/dev.c b/net/core/dev.c
index 508b1d799681..ea6b3115ee8b 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -165,7 +165,6 @@ static int netif_rx_internal(struct sk_buff *skb);
static int call_netdevice_notifiers_extack(unsigned long val,
struct net_device *dev,
struct netlink_ext_ack *extack);
-static struct napi_struct *napi_by_id(unsigned int napi_id);
/*
* The @dev_base_head list is protected by @dev_base_lock and the rtnl
@@ -6133,7 +6132,7 @@ bool napi_complete_done(struct napi_struct *n, int work_done)
EXPORT_SYMBOL(napi_complete_done);
/* must be called under rcu_read_lock(), as we dont take a reference */
-static struct napi_struct *napi_by_id(unsigned int napi_id)
+struct napi_struct *napi_by_id(unsigned int napi_id)
{
unsigned int hash = napi_id % HASH_SIZE(napi_hash);
struct napi_struct *napi;
@@ -6144,6 +6143,7 @@ static struct napi_struct *napi_by_id(unsigned int napi_id)
return NULL;
}
+EXPORT_SYMBOL(napi_by_id);
#if defined(CONFIG_NET_RX_BUSY_POLL)
diff --git a/net/core/netdev-genl.c b/net/core/netdev-genl.c
index 8609884fefe4..6f4ed21ebd15 100644
--- a/net/core/netdev-genl.c
+++ b/net/core/netdev-genl.c
@@ -7,6 +7,7 @@
#include <net/sock.h>
#include <net/xdp.h>
#include <net/netdev_rx_queue.h>
+#include <net/busy_poll.h>
#include "netdev-genl-gen.h"
@@ -14,6 +15,7 @@ struct netdev_nl_dump_ctx {
unsigned long ifindex;
unsigned int rxq_idx;
unsigned int txq_idx;
+ unsigned int napi_id;
};
static inline struct netdev_nl_dump_ctx *
@@ -145,14 +147,125 @@ int netdev_nl_dev_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
return skb->len;
}
+static int
+netdev_nl_napi_fill_one(struct sk_buff *rsp, struct napi_struct *napi,
+ const struct genl_info *info)
+{
+ void *hdr;
+
+ if (WARN_ON_ONCE(!napi->dev))
+ return -EINVAL;
+
+ hdr = genlmsg_iput(rsp, info);
+ if (!hdr)
+ return -EMSGSIZE;
+
+ if (napi->napi_id >= MIN_NAPI_ID &&
+ nla_put_u32(rsp, NETDEV_A_NAPI_NAPI_ID, napi->napi_id))
+ goto nla_put_failure;
+
+ if (nla_put_u32(rsp, NETDEV_A_NAPI_IFINDEX, napi->dev->ifindex))
+ goto nla_put_failure;
+
+ genlmsg_end(rsp, hdr);
+ return 0;
+
+nla_put_failure:
+ genlmsg_cancel(rsp, hdr);
+ return -EMSGSIZE;
+}
+
int netdev_nl_napi_get_doit(struct sk_buff *skb, struct genl_info *info)
{
- return -EOPNOTSUPP;
+ struct napi_struct *napi;
+ struct sk_buff *rsp;
+ u32 napi_id;
+ int err;
+
+ if (GENL_REQ_ATTR_CHECK(info, NETDEV_A_NAPI_NAPI_ID))
+ return -EINVAL;
+
+ napi_id = nla_get_u32(info->attrs[NETDEV_A_NAPI_NAPI_ID]);
+
+ rsp = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ if (!rsp)
+ return -ENOMEM;
+
+ rtnl_lock();
+
+ napi = napi_by_id(napi_id);
+ if (napi)
+ err = netdev_nl_napi_fill_one(rsp, napi, info);
+ else
+ err = -EINVAL;
+
+ rtnl_unlock();
+
+ if (err)
+ goto err_free_msg;
+
+ return genlmsg_reply(rsp, info);
+
+err_free_msg:
+ nlmsg_free(rsp);
+ return err;
+}
+
+static int
+netdev_nl_napi_dump_one(struct net_device *netdev, struct sk_buff *rsp,
+ const struct genl_info *info, unsigned int *start)
+{
+ struct napi_struct *napi;
+ int err = 0;
+
+ list_for_each_entry_rcu(napi, &netdev->napi_list, dev_list) {
+ if (*start && napi->napi_id >= *start)
+ continue;
+
+ err = netdev_nl_napi_fill_one(rsp, napi, info);
+ if (err)
+ break;
+ *start = napi->napi_id;
+ }
+ return err;
}
int netdev_nl_napi_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
{
- return -EOPNOTSUPP;
+ struct netdev_nl_dump_ctx *ctx = netdev_dump_ctx(cb);
+ const struct genl_info *info = genl_info_dump(cb);
+ struct net *net = sock_net(skb->sk);
+ unsigned int n_id = ctx->napi_id;
+ struct net_device *netdev;
+ u32 ifindex = 0;
+ int err = 0;
+
+ if (info->attrs[NETDEV_A_NAPI_IFINDEX])
+ ifindex = nla_get_u32(info->attrs[NETDEV_A_NAPI_IFINDEX]);
+
+ rtnl_lock();
+ if (ifindex) {
+ netdev = __dev_get_by_index(net, ifindex);
+ if (netdev)
+ err = netdev_nl_napi_dump_one(netdev, skb, info, &n_id);
+ else
+ err = -ENODEV;
+ } else {
+ for_each_netdev_dump(net, netdev, ctx->ifindex) {
+ err = netdev_nl_napi_dump_one(netdev, skb, info, &n_id);
+ if (err < 0)
+ break;
+ if (!err)
+ n_id = 0;
+ }
+ }
+ rtnl_unlock();
+
+ if (err != -EMSGSIZE)
+ return err;
+
+ ctx->napi_id = n_id;
+ return skb->len;
}
static int
^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [net-next PATCH v3 06/10] netdev-genl: Add netlink framework functions for napi
2023-09-19 22:27 ` [net-next PATCH v3 06/10] netdev-genl: Add netlink framework functions for napi Amritha Nambiar
@ 2023-09-28 11:19 ` Paolo Abeni
2023-09-28 23:34 ` Nambiar, Amritha
0 siblings, 1 reply; 19+ messages in thread
From: Paolo Abeni @ 2023-09-28 11:19 UTC (permalink / raw)
To: Amritha Nambiar, netdev, kuba; +Cc: sridhar.samudrala
On Tue, 2023-09-19 at 15:27 -0700, Amritha Nambiar wrote:
> Implement the netdev netlink framework functions for
> napi support. The netdev structure tracks all the napi
> instances and napi fields. The napi instances and associated
> parameters can be retrieved this way.
>
> Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
> Reviewed-by: Sridhar Samudrala <sridhar.samudrala@intel.com>
> ---
> include/linux/netdevice.h | 2 +
> net/core/dev.c | 4 +-
> net/core/netdev-genl.c | 117 ++++++++++++++++++++++++++++++++++++++++++++-
> 3 files changed, 119 insertions(+), 4 deletions(-)
>
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 69e363918e4b..e7321178dc1a 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -536,6 +536,8 @@ static inline bool napi_complete(struct napi_struct *n)
> return napi_complete_done(n, 0);
> }
>
> +struct napi_struct *napi_by_id(unsigned int napi_id);
> +
> int dev_set_threaded(struct net_device *dev, bool threaded);
>
> /**
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 508b1d799681..ea6b3115ee8b 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -165,7 +165,6 @@ static int netif_rx_internal(struct sk_buff *skb);
> static int call_netdevice_notifiers_extack(unsigned long val,
> struct net_device *dev,
> struct netlink_ext_ack *extack);
> -static struct napi_struct *napi_by_id(unsigned int napi_id);
>
> /*
> * The @dev_base_head list is protected by @dev_base_lock and the rtnl
> @@ -6133,7 +6132,7 @@ bool napi_complete_done(struct napi_struct *n, int work_done)
> EXPORT_SYMBOL(napi_complete_done);
>
> /* must be called under rcu_read_lock(), as we dont take a reference */
> -static struct napi_struct *napi_by_id(unsigned int napi_id)
> +struct napi_struct *napi_by_id(unsigned int napi_id)
> {
> unsigned int hash = napi_id % HASH_SIZE(napi_hash);
> struct napi_struct *napi;
> @@ -6144,6 +6143,7 @@ static struct napi_struct *napi_by_id(unsigned int napi_id)
>
> return NULL;
> }
> +EXPORT_SYMBOL(napi_by_id);
>
> #if defined(CONFIG_NET_RX_BUSY_POLL)
>
> diff --git a/net/core/netdev-genl.c b/net/core/netdev-genl.c
> index 8609884fefe4..6f4ed21ebd15 100644
> --- a/net/core/netdev-genl.c
> +++ b/net/core/netdev-genl.c
> @@ -7,6 +7,7 @@
> #include <net/sock.h>
> #include <net/xdp.h>
> #include <net/netdev_rx_queue.h>
> +#include <net/busy_poll.h>
>
> #include "netdev-genl-gen.h"
>
> @@ -14,6 +15,7 @@ struct netdev_nl_dump_ctx {
> unsigned long ifindex;
> unsigned int rxq_idx;
> unsigned int txq_idx;
> + unsigned int napi_id;
Why you need to add napi_id to the context? don't you need just such
field to do the traversing? e.g. use directly single cb[0]
[...]
> +static int
> +netdev_nl_napi_dump_one(struct net_device *netdev, struct sk_buff *rsp,
> + const struct genl_info *info, unsigned int *start)
> +{
> + struct napi_struct *napi;
> + int err = 0;
> +
> + list_for_each_entry_rcu(napi, &netdev->napi_list, dev_list) {
I'm sorry for the conflicting feedback here, but I think you don't need
any special variant, just 'list_for_each_entry'. This is under rtnl
lock, the list can't change under the hood. Also I think you should get
a RCU splat here when building with CONFIG_PROVE_RCU_LIST.
Cheers,
Paolo
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [net-next PATCH v3 06/10] netdev-genl: Add netlink framework functions for napi
2023-09-28 11:19 ` Paolo Abeni
@ 2023-09-28 23:34 ` Nambiar, Amritha
0 siblings, 0 replies; 19+ messages in thread
From: Nambiar, Amritha @ 2023-09-28 23:34 UTC (permalink / raw)
To: Paolo Abeni, netdev, kuba; +Cc: sridhar.samudrala
On 9/28/2023 4:19 AM, Paolo Abeni wrote:
> On Tue, 2023-09-19 at 15:27 -0700, Amritha Nambiar wrote:
>> Implement the netdev netlink framework functions for
>> napi support. The netdev structure tracks all the napi
>> instances and napi fields. The napi instances and associated
>> parameters can be retrieved this way.
>>
>> Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
>> Reviewed-by: Sridhar Samudrala <sridhar.samudrala@intel.com>
>> ---
>> include/linux/netdevice.h | 2 +
>> net/core/dev.c | 4 +-
>> net/core/netdev-genl.c | 117 ++++++++++++++++++++++++++++++++++++++++++++-
>> 3 files changed, 119 insertions(+), 4 deletions(-)
>>
>> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
>> index 69e363918e4b..e7321178dc1a 100644
>> --- a/include/linux/netdevice.h
>> +++ b/include/linux/netdevice.h
>> @@ -536,6 +536,8 @@ static inline bool napi_complete(struct napi_struct *n)
>> return napi_complete_done(n, 0);
>> }
>>
>> +struct napi_struct *napi_by_id(unsigned int napi_id);
>> +
>> int dev_set_threaded(struct net_device *dev, bool threaded);
>>
>> /**
>> diff --git a/net/core/dev.c b/net/core/dev.c
>> index 508b1d799681..ea6b3115ee8b 100644
>> --- a/net/core/dev.c
>> +++ b/net/core/dev.c
>> @@ -165,7 +165,6 @@ static int netif_rx_internal(struct sk_buff *skb);
>> static int call_netdevice_notifiers_extack(unsigned long val,
>> struct net_device *dev,
>> struct netlink_ext_ack *extack);
>> -static struct napi_struct *napi_by_id(unsigned int napi_id);
>>
>> /*
>> * The @dev_base_head list is protected by @dev_base_lock and the rtnl
>> @@ -6133,7 +6132,7 @@ bool napi_complete_done(struct napi_struct *n, int work_done)
>> EXPORT_SYMBOL(napi_complete_done);
>>
>> /* must be called under rcu_read_lock(), as we dont take a reference */
>> -static struct napi_struct *napi_by_id(unsigned int napi_id)
>> +struct napi_struct *napi_by_id(unsigned int napi_id)
>> {
>> unsigned int hash = napi_id % HASH_SIZE(napi_hash);
>> struct napi_struct *napi;
>> @@ -6144,6 +6143,7 @@ static struct napi_struct *napi_by_id(unsigned int napi_id)
>>
>> return NULL;
>> }
>> +EXPORT_SYMBOL(napi_by_id);
>>
>> #if defined(CONFIG_NET_RX_BUSY_POLL)
>>
>> diff --git a/net/core/netdev-genl.c b/net/core/netdev-genl.c
>> index 8609884fefe4..6f4ed21ebd15 100644
>> --- a/net/core/netdev-genl.c
>> +++ b/net/core/netdev-genl.c
>> @@ -7,6 +7,7 @@
>> #include <net/sock.h>
>> #include <net/xdp.h>
>> #include <net/netdev_rx_queue.h>
>> +#include <net/busy_poll.h>
>>
>> #include "netdev-genl-gen.h"
>>
>> @@ -14,6 +15,7 @@ struct netdev_nl_dump_ctx {
>> unsigned long ifindex;
>> unsigned int rxq_idx;
>> unsigned int txq_idx;
>> + unsigned int napi_id;
>
> Why you need to add napi_id to the context? don't you need just such
> field to do the traversing? e.g. use directly single cb[0]
>
Not sure I follow this comment. Could you please clarify.
I introduced the netdev_nl_dump_ctx structure to save the
states/counters for dump (for ifindex, queue indices, NAPI IDs etc.) if
the dump was interrupted due to EMSGSIZE error. Also, I decided to use
cb->ctx instead of cb->args[] due to a comment in the definition of
struct netlink_callback in include/linux/netlink.h that says "args is
deprecated. Cast a struct over ctx instead for proper type safety."
The 'napi_id' is saved into netdev_nl_dump_ctx since there is no need
for a separate counter when we can rely on the NAPI IDs itself (as
pointed out by Jakub's review comment on v2).
> [...]
>> +static int
>> +netdev_nl_napi_dump_one(struct net_device *netdev, struct sk_buff *rsp,
>> + const struct genl_info *info, unsigned int *start)
>> +{
>> + struct napi_struct *napi;
>> + int err = 0;
>> +
>> + list_for_each_entry_rcu(napi, &netdev->napi_list, dev_list) {
>
> I'm sorry for the conflicting feedback here, but I think you don't need
> any special variant, just 'list_for_each_entry'. This is under rtnl
> lock, the list can't change under the hood. Also I think you should get
> a RCU splat here when building with CONFIG_PROVE_RCU_LIST.
>
Makes sense. Access is protected by the rtnl_lock, so _rcu protection
isn't needed, I can just use 'list_for_each_entry' for list traversal.
>
> Cheers,
>
> Paolo
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [net-next PATCH v3 07/10] netdev-genl: spec: Add irq in netdev netlink YAML spec
2023-09-19 22:27 [net-next PATCH v3 00/10] Introduce queue and NAPI support in netdev-genl (Was: Introduce NAPI queues support) Amritha Nambiar
` (5 preceding siblings ...)
2023-09-19 22:27 ` [net-next PATCH v3 06/10] netdev-genl: Add netlink framework functions for napi Amritha Nambiar
@ 2023-09-19 22:27 ` Amritha Nambiar
2023-09-19 22:27 ` [net-next PATCH v3 08/10] net: Add NAPI IRQ support Amritha Nambiar
` (2 subsequent siblings)
9 siblings, 0 replies; 19+ messages in thread
From: Amritha Nambiar @ 2023-09-19 22:27 UTC (permalink / raw)
To: netdev, kuba; +Cc: sridhar.samudrala, amritha.nambiar
Add support in netlink spec(netdev.yaml) for interrupt number
among the NAPI attributes. Add code generated from the spec.
Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
Reviewed-by: Sridhar Samudrala <sridhar.samudrala@intel.com>
---
Documentation/netlink/specs/netdev.yaml | 5 +++++
include/uapi/linux/netdev.h | 1 +
tools/include/uapi/linux/netdev.h | 1 +
tools/net/ynl/generated/netdev-user.c | 6 ++++++
tools/net/ynl/generated/netdev-user.h | 2 ++
5 files changed, 15 insertions(+)
diff --git a/Documentation/netlink/specs/netdev.yaml b/Documentation/netlink/specs/netdev.yaml
index 446457f0c330..f346b1b559d9 100644
--- a/Documentation/netlink/specs/netdev.yaml
+++ b/Documentation/netlink/specs/netdev.yaml
@@ -106,6 +106,10 @@ attribute-sets:
name: napi-id
doc: napi id
type: u32
+ -
+ name: irq
+ doc: The associated interrupt vector number for the napi
+ type: u32
-
name: queue
attributes:
@@ -199,6 +203,7 @@ operations:
attributes:
- napi-id
- ifindex
+ - irq
dump:
request:
attributes:
diff --git a/include/uapi/linux/netdev.h b/include/uapi/linux/netdev.h
index 96535b980065..7f626a750919 100644
--- a/include/uapi/linux/netdev.h
+++ b/include/uapi/linux/netdev.h
@@ -72,6 +72,7 @@ enum {
enum {
NETDEV_A_NAPI_IFINDEX = 1,
NETDEV_A_NAPI_NAPI_ID,
+ NETDEV_A_NAPI_IRQ,
__NETDEV_A_NAPI_MAX,
NETDEV_A_NAPI_MAX = (__NETDEV_A_NAPI_MAX - 1)
diff --git a/tools/include/uapi/linux/netdev.h b/tools/include/uapi/linux/netdev.h
index 96535b980065..7f626a750919 100644
--- a/tools/include/uapi/linux/netdev.h
+++ b/tools/include/uapi/linux/netdev.h
@@ -72,6 +72,7 @@ enum {
enum {
NETDEV_A_NAPI_IFINDEX = 1,
NETDEV_A_NAPI_NAPI_ID,
+ NETDEV_A_NAPI_IRQ,
__NETDEV_A_NAPI_MAX,
NETDEV_A_NAPI_MAX = (__NETDEV_A_NAPI_MAX - 1)
diff --git a/tools/net/ynl/generated/netdev-user.c b/tools/net/ynl/generated/netdev-user.c
index 190e17c37063..866fa952fdfd 100644
--- a/tools/net/ynl/generated/netdev-user.c
+++ b/tools/net/ynl/generated/netdev-user.c
@@ -102,6 +102,7 @@ struct ynl_policy_nest netdev_queue_nest = {
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_NAPI_ID] = { .name = "napi-id", .type = YNL_PT_U32, },
+ [NETDEV_A_NAPI_IRQ] = { .name = "irq", .type = YNL_PT_U32, },
};
struct ynl_policy_nest netdev_napi_nest = {
@@ -400,6 +401,11 @@ int netdev_napi_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
return MNL_CB_ERROR;
dst->_present.ifindex = 1;
dst->ifindex = mnl_attr_get_u32(attr);
+ } else if (type == NETDEV_A_NAPI_IRQ) {
+ if (ynl_attr_validate(yarg, attr))
+ return MNL_CB_ERROR;
+ dst->_present.irq = 1;
+ dst->irq = mnl_attr_get_u32(attr);
}
}
diff --git a/tools/net/ynl/generated/netdev-user.h b/tools/net/ynl/generated/netdev-user.h
index 78b1eae9219a..fd3be582d933 100644
--- a/tools/net/ynl/generated/netdev-user.h
+++ b/tools/net/ynl/generated/netdev-user.h
@@ -215,10 +215,12 @@ struct netdev_napi_get_rsp {
struct {
__u32 napi_id:1;
__u32 ifindex:1;
+ __u32 irq:1;
} _present;
__u32 napi_id;
__u32 ifindex;
+ __u32 irq;
};
void netdev_napi_get_rsp_free(struct netdev_napi_get_rsp *rsp);
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [net-next PATCH v3 08/10] net: Add NAPI IRQ support
2023-09-19 22:27 [net-next PATCH v3 00/10] Introduce queue and NAPI support in netdev-genl (Was: Introduce NAPI queues support) Amritha Nambiar
` (6 preceding siblings ...)
2023-09-19 22:27 ` [net-next PATCH v3 07/10] netdev-genl: spec: Add irq in netdev netlink YAML spec Amritha Nambiar
@ 2023-09-19 22:27 ` Amritha Nambiar
2023-09-19 22:28 ` [net-next PATCH v3 09/10] netdev-genl: spec: Add PID in netdev netlink YAML spec Amritha Nambiar
2023-09-19 22:28 ` [net-next PATCH v3 10/10] netdev-genl: Add PID for the NAPI thread Amritha Nambiar
9 siblings, 0 replies; 19+ messages in thread
From: Amritha Nambiar @ 2023-09-19 22:27 UTC (permalink / raw)
To: netdev, kuba; +Cc: sridhar.samudrala, amritha.nambiar
Add support to associate the interrupt vector number for a
NAPI instance.
Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
Reviewed-by: Sridhar Samudrala <sridhar.samudrala@intel.com>
---
drivers/net/ethernet/intel/ice/ice_lib.c | 3 +++
include/linux/netdevice.h | 6 ++++++
net/core/dev.c | 1 +
net/core/netdev-genl.c | 4 ++++
4 files changed, 14 insertions(+)
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
index df1906566185..ede246720898 100644
--- a/drivers/net/ethernet/intel/ice/ice_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
@@ -2972,6 +2972,9 @@ int ice_q_vector_add_napi_queues(struct ice_q_vector *q_vector)
return ret;
}
+ /* Also set the interrupt number for the NAPI */
+ netif_napi_set_irq(&q_vector->napi, q_vector->irq.virq);
+
return ret;
}
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index e7321178dc1a..8be6b3aa70a9 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -382,6 +382,7 @@ struct napi_struct {
/* control-path-only fields follow */
struct list_head dev_list;
struct hlist_node napi_hash_node;
+ int irq;
};
enum {
@@ -2625,6 +2626,11 @@ static inline void *netdev_priv(const struct net_device *dev)
int netif_napi_add_queue(struct napi_struct *napi, unsigned int queue_index,
enum netdev_queue_type type);
+static inline void netif_napi_set_irq(struct napi_struct *napi, int irq)
+{
+ napi->irq = irq;
+}
+
/* Default NAPI poll() weight
* Device drivers are strongly advised to not use bigger value
*/
diff --git a/net/core/dev.c b/net/core/dev.c
index ea6b3115ee8b..5087b0e92a59 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6463,6 +6463,7 @@ void netif_napi_add_weight(struct net_device *dev, struct napi_struct *napi,
*/
if (dev->threaded && napi_kthread_create(napi))
dev->threaded = 0;
+ napi->irq = -1;
}
EXPORT_SYMBOL(netif_napi_add_weight);
diff --git a/net/core/netdev-genl.c b/net/core/netdev-genl.c
index 6f4ed21ebd15..2b3818615e1b 100644
--- a/net/core/netdev-genl.c
+++ b/net/core/netdev-genl.c
@@ -167,7 +167,11 @@ netdev_nl_napi_fill_one(struct sk_buff *rsp, struct napi_struct *napi,
if (nla_put_u32(rsp, NETDEV_A_NAPI_IFINDEX, napi->dev->ifindex))
goto nla_put_failure;
+ if (napi->irq >= 0 && nla_put_u32(rsp, NETDEV_A_NAPI_IRQ, napi->irq))
+ goto nla_put_failure;
+
genlmsg_end(rsp, hdr);
+
return 0;
nla_put_failure:
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [net-next PATCH v3 09/10] netdev-genl: spec: Add PID in netdev netlink YAML spec
2023-09-19 22:27 [net-next PATCH v3 00/10] Introduce queue and NAPI support in netdev-genl (Was: Introduce NAPI queues support) Amritha Nambiar
` (7 preceding siblings ...)
2023-09-19 22:27 ` [net-next PATCH v3 08/10] net: Add NAPI IRQ support Amritha Nambiar
@ 2023-09-19 22:28 ` Amritha Nambiar
2023-09-19 22:28 ` [net-next PATCH v3 10/10] netdev-genl: Add PID for the NAPI thread Amritha Nambiar
9 siblings, 0 replies; 19+ messages in thread
From: Amritha Nambiar @ 2023-09-19 22:28 UTC (permalink / raw)
To: netdev, kuba; +Cc: sridhar.samudrala, amritha.nambiar
Add support in netlink spec(netdev.yaml) for PID of the
NAPI thread. Add code generated from the spec.
Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
Reviewed-by: Sridhar Samudrala <sridhar.samudrala@intel.com>
---
Documentation/netlink/specs/netdev.yaml | 5 +++++
include/uapi/linux/netdev.h | 1 +
tools/include/uapi/linux/netdev.h | 1 +
tools/net/ynl/generated/netdev-user.c | 6 ++++++
tools/net/ynl/generated/netdev-user.h | 2 ++
5 files changed, 15 insertions(+)
diff --git a/Documentation/netlink/specs/netdev.yaml b/Documentation/netlink/specs/netdev.yaml
index f346b1b559d9..fc2742f1de27 100644
--- a/Documentation/netlink/specs/netdev.yaml
+++ b/Documentation/netlink/specs/netdev.yaml
@@ -110,6 +110,10 @@ attribute-sets:
name: irq
doc: The associated interrupt vector number for the napi
type: u32
+ -
+ name: pid
+ doc: PID of the napi thread
+ type: s32
-
name: queue
attributes:
@@ -204,6 +208,7 @@ operations:
- napi-id
- ifindex
- irq
+ - pid
dump:
request:
attributes:
diff --git a/include/uapi/linux/netdev.h b/include/uapi/linux/netdev.h
index 7f626a750919..4a091f100982 100644
--- a/include/uapi/linux/netdev.h
+++ b/include/uapi/linux/netdev.h
@@ -73,6 +73,7 @@ enum {
NETDEV_A_NAPI_IFINDEX = 1,
NETDEV_A_NAPI_NAPI_ID,
NETDEV_A_NAPI_IRQ,
+ NETDEV_A_NAPI_PID,
__NETDEV_A_NAPI_MAX,
NETDEV_A_NAPI_MAX = (__NETDEV_A_NAPI_MAX - 1)
diff --git a/tools/include/uapi/linux/netdev.h b/tools/include/uapi/linux/netdev.h
index 7f626a750919..4a091f100982 100644
--- a/tools/include/uapi/linux/netdev.h
+++ b/tools/include/uapi/linux/netdev.h
@@ -73,6 +73,7 @@ enum {
NETDEV_A_NAPI_IFINDEX = 1,
NETDEV_A_NAPI_NAPI_ID,
NETDEV_A_NAPI_IRQ,
+ NETDEV_A_NAPI_PID,
__NETDEV_A_NAPI_MAX,
NETDEV_A_NAPI_MAX = (__NETDEV_A_NAPI_MAX - 1)
diff --git a/tools/net/ynl/generated/netdev-user.c b/tools/net/ynl/generated/netdev-user.c
index 866fa952fdfd..8639ece6f9a6 100644
--- a/tools/net/ynl/generated/netdev-user.c
+++ b/tools/net/ynl/generated/netdev-user.c
@@ -103,6 +103,7 @@ 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_NAPI_ID] = { .name = "napi-id", .type = YNL_PT_U32, },
[NETDEV_A_NAPI_IRQ] = { .name = "irq", .type = YNL_PT_U32, },
+ [NETDEV_A_NAPI_PID] = { .name = "pid", .type = YNL_PT_U32, },
};
struct ynl_policy_nest netdev_napi_nest = {
@@ -406,6 +407,11 @@ int netdev_napi_get_rsp_parse(const struct nlmsghdr *nlh, void *data)
return MNL_CB_ERROR;
dst->_present.irq = 1;
dst->irq = mnl_attr_get_u32(attr);
+ } else if (type == NETDEV_A_NAPI_PID) {
+ if (ynl_attr_validate(yarg, attr))
+ return MNL_CB_ERROR;
+ dst->_present.pid = 1;
+ dst->pid = mnl_attr_get_u32(attr);
}
}
diff --git a/tools/net/ynl/generated/netdev-user.h b/tools/net/ynl/generated/netdev-user.h
index fd3be582d933..89aaee4af5d1 100644
--- a/tools/net/ynl/generated/netdev-user.h
+++ b/tools/net/ynl/generated/netdev-user.h
@@ -216,11 +216,13 @@ struct netdev_napi_get_rsp {
__u32 napi_id:1;
__u32 ifindex:1;
__u32 irq:1;
+ __u32 pid:1;
} _present;
__u32 napi_id;
__u32 ifindex;
__u32 irq;
+ __s32 pid;
};
void netdev_napi_get_rsp_free(struct netdev_napi_get_rsp *rsp);
^ permalink raw reply related [flat|nested] 19+ messages in thread
* [net-next PATCH v3 10/10] netdev-genl: Add PID for the NAPI thread
2023-09-19 22:27 [net-next PATCH v3 00/10] Introduce queue and NAPI support in netdev-genl (Was: Introduce NAPI queues support) Amritha Nambiar
` (8 preceding siblings ...)
2023-09-19 22:28 ` [net-next PATCH v3 09/10] netdev-genl: spec: Add PID in netdev netlink YAML spec Amritha Nambiar
@ 2023-09-19 22:28 ` Amritha Nambiar
9 siblings, 0 replies; 19+ messages in thread
From: Amritha Nambiar @ 2023-09-19 22:28 UTC (permalink / raw)
To: netdev, kuba; +Cc: sridhar.samudrala, amritha.nambiar
In the threaded NAPI mode, expose the PID of the NAPI thread.
Signed-off-by: Amritha Nambiar <amritha.nambiar@intel.com>
Reviewed-by: Sridhar Samudrala <sridhar.samudrala@intel.com>
---
net/core/netdev-genl.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/net/core/netdev-genl.c b/net/core/netdev-genl.c
index 2b3818615e1b..369fc31a4599 100644
--- a/net/core/netdev-genl.c
+++ b/net/core/netdev-genl.c
@@ -152,6 +152,7 @@ netdev_nl_napi_fill_one(struct sk_buff *rsp, struct napi_struct *napi,
const struct genl_info *info)
{
void *hdr;
+ pid_t pid;
if (WARN_ON_ONCE(!napi->dev))
return -EINVAL;
@@ -170,6 +171,12 @@ netdev_nl_napi_fill_one(struct sk_buff *rsp, struct napi_struct *napi,
if (napi->irq >= 0 && nla_put_u32(rsp, NETDEV_A_NAPI_IRQ, napi->irq))
goto nla_put_failure;
+ if (napi->thread) {
+ pid = task_pid_nr(napi->thread);
+ if (nla_put_s32(rsp, NETDEV_A_NAPI_PID, pid))
+ goto nla_put_failure;
+ }
+
genlmsg_end(rsp, hdr);
return 0;
^ permalink raw reply related [flat|nested] 19+ messages in thread