From: Aurelien Aptel <aaptel@nvidia.com>
To: linux-nvme@lists.infradead.org, netdev@vger.kernel.org,
sagi@grimberg.me, hch@lst.de, kbusch@kernel.org, axboe@fb.com,
chaitanyak@nvidia.com, davem@davemloft.net, kuba@kernel.org
Cc: Aurelien Aptel <aaptel@nvidia.com>,
aurelien.aptel@gmail.com, smalin@nvidia.com, malin1024@gmail.com,
ogerlitz@nvidia.com, yorayz@nvidia.com, borisp@nvidia.com,
galshalom@nvidia.com, mgurtovoy@nvidia.com, edumazet@google.com,
pabeni@redhat.com, imagedong@tencent.com
Subject: [PATCH v15 02/20] netlink: add new family to manage ULP_DDP enablement and stats
Date: Tue, 12 Sep 2023 09:59:31 +0000 [thread overview]
Message-ID: <20230912095949.5474-3-aaptel@nvidia.com> (raw)
In-Reply-To: <20230912095949.5474-1-aaptel@nvidia.com>
Add a new netlink family to get/set ULP DDP capabilities on a network
device and to retrieve statistics.
The messages use the genetlink infrastructure and are specified in a
YAML file which was used to generate some of the files in this commit:
./tools/net/ynl/ynl-gen-c.py --mode kernel \
--spec ./Documentation/netlink/specs/ulp_ddp.yaml --header \
-o net/core/ulp_ddp_gen_nl.h
./tools/net/ynl/ynl-gen-c.py --mode kernel \
--spec ./Documentation/netlink/specs/ulp_ddp.yaml --source \
-o net/core/ulp_ddp_gen_nl.c
./tools/net/ynl/ynl-gen-c.py --mode uapi \
--spec ./Documentation/netlink/specs/ulp_ddp.yaml --header \
> include/uapi/linux/ulp_ddp_nl.h
Signed-off-by: Shai Malin <smalin@nvidia.com>
Signed-off-by: Aurelien Aptel <aaptel@nvidia.com>
---
Documentation/netlink/specs/ulp_ddp.yaml | 183 +++++++++++
include/uapi/linux/ulp_ddp_nl.h | 59 ++++
net/core/Makefile | 2 +-
net/core/ulp_ddp_gen_nl.c | 85 +++++
net/core/ulp_ddp_gen_nl.h | 32 ++
net/core/ulp_ddp_nl.c | 388 +++++++++++++++++++++++
6 files changed, 748 insertions(+), 1 deletion(-)
create mode 100644 Documentation/netlink/specs/ulp_ddp.yaml
create mode 100644 include/uapi/linux/ulp_ddp_nl.h
create mode 100644 net/core/ulp_ddp_gen_nl.c
create mode 100644 net/core/ulp_ddp_gen_nl.h
create mode 100644 net/core/ulp_ddp_nl.c
diff --git a/Documentation/netlink/specs/ulp_ddp.yaml b/Documentation/netlink/specs/ulp_ddp.yaml
new file mode 100644
index 000000000000..882aa4e52992
--- /dev/null
+++ b/Documentation/netlink/specs/ulp_ddp.yaml
@@ -0,0 +1,183 @@
+# SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
+#
+# Author: Aurelien Aptel <aaptel@nvidia.com>
+#
+# Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+#
+
+name: ulp_ddp
+
+protocol: genetlink
+
+doc: Netlink protocol to manage ULP DPP on network devices.
+
+definitions:
+ -
+ type: enum
+ name: cap
+ entries:
+ - nvme-tcp
+ - nvme-tcp-ddgst-rx
+
+uapi-header: linux/ulp_ddp_nl.h
+
+attribute-sets:
+ -
+ name: stat
+ attributes:
+ -
+ name: ifindex
+ doc: interface index of the net device.
+ type: u32
+ -
+ name: pad
+ type: pad
+ -
+ name: rx-nvmeotcp-sk-add
+ doc: Sockets successfully configured for NVMeTCP offloading.
+ type: u64
+ -
+ name: rx-nvmeotcp-sk-add-fail
+ doc: Sockets failed to be configured for NVMeTCP offloading.
+ type: u64
+ -
+ name: rx-nvmeotcp-sk-del
+ doc: Sockets with NVMeTCP offloading configuration removed.
+ type: u64
+ -
+ name: rx-nvmeotcp-setup
+ doc: NVMe-TCP IOs successfully configured for Rx Direct Data Placement.
+ type: u64
+ -
+ name: rx-nvmeotcp-setup-fail
+ doc: NVMe-TCP IOs failed to be configured for Rx Direct Data Placement.
+ type: u64
+ -
+ name: rx-nvmeotcp-teardown
+ doc: NVMe-TCP IOs with Rx Direct Data Placement configuration removed.
+ type: u64
+ -
+ name: rx-nvmeotcp-drop
+ doc: Packets failed the NVMeTCP offload validation.
+ type: u64
+ -
+ name: rx-nvmeotcp-resync
+ doc: >
+ NVMe-TCP resync operations were processed due to Rx TCP packets
+ re-ordering.
+ type: u64
+ -
+ name: rx-nvmeotcp-packets
+ doc: TCP packets successfully processed by the NVMeTCP offload.
+ type: u64
+ -
+ name: rx-nvmeotcp-bytes
+ doc: Bytes were successfully processed by the NVMeTCP offload.
+ type: u64
+ -
+ name: dev
+ attributes:
+ -
+ name: ifindex
+ doc: interface index of the net device.
+ type: u32
+ -
+ name: hw
+ doc: bitmask of the capabilities supported by the device.
+ type: u64
+ enum: cap
+ enum-as-flags: true
+ -
+ name: active
+ doc: bitmask of the capabilities currently enabled on the device.
+ type: u64
+ enum: cap
+ enum-as-flags: true
+ -
+ name: wanted
+ doc: >
+ new active bit values of the capabilities we want to set on the
+ device.
+ type: u64
+ enum: cap
+ enum-as-flags: true
+ -
+ name: wanted_mask
+ doc: bitmask of the meaningful bits in the wanted field.
+ type: u64
+ enum: cap
+ enum-as-flags: true
+ -
+ name: pad
+ type: pad
+
+operations:
+ list:
+ -
+ name: get
+ doc: Get ULP DDP capabilities.
+ attribute-set: dev
+ do:
+ request:
+ attributes:
+ - ifindex
+ reply: &dev-all
+ attributes:
+ - ifindex
+ - hw
+ - active
+ pre: ulp_ddp_get_netdev
+ post: ulp_ddp_put_netdev
+ dump:
+ reply: *dev-all
+ -
+ name: stats
+ doc: Get ULP DDP stats.
+ attribute-set: stat
+ do:
+ request:
+ attributes:
+ - ifindex
+ reply: &stats-all
+ attributes:
+ - ifindex
+ - rx-nvmeotcp-sk-add
+ - rx-nvmeotcp-sk-add-fail
+ - rx-nvmeotcp-sk-del
+ - rx-nvmeotcp-setup
+ - rx-nvmeotcp-setup-fail
+ - rx-nvmeotcp-teardown
+ - rx-nvmeotcp-drop
+ - rx-nvmeotcp-resync
+ - rx-nvmeotcp-packets
+ - rx-nvmeotcp-bytes
+ pre: ulp_ddp_get_netdev
+ post: ulp_ddp_put_netdev
+ dump:
+ reply: *stats-all
+ -
+ name: set
+ doc: Set ULP DDP capabilities.
+ attribute-set: dev
+ do:
+ request:
+ attributes:
+ - ifindex
+ - wanted
+ - wanted_mask
+ reply:
+ attributes:
+ - ifindex
+ - hw
+ - active
+ pre: ulp_ddp_get_netdev
+ post: ulp_ddp_put_netdev
+ -
+ name: set-ntf
+ doc: Notification for change in ULP DDP capabilities.
+ notify: get
+
+mcast-groups:
+ list:
+ -
+ name: mgmt
diff --git a/include/uapi/linux/ulp_ddp_nl.h b/include/uapi/linux/ulp_ddp_nl.h
new file mode 100644
index 000000000000..fc63749c9251
--- /dev/null
+++ b/include/uapi/linux/ulp_ddp_nl.h
@@ -0,0 +1,59 @@
+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
+/* Do not edit directly, auto-generated from: */
+/* Documentation/netlink/specs/ulp_ddp.yaml */
+/* YNL-GEN uapi header */
+
+#ifndef _UAPI_LINUX_ULP_DDP_H
+#define _UAPI_LINUX_ULP_DDP_H
+
+#define ULP_DDP_FAMILY_NAME "ulp_ddp"
+#define ULP_DDP_FAMILY_VERSION 1
+
+enum ulp_ddp_cap {
+ ULP_DDP_CAP_NVME_TCP,
+ ULP_DDP_CAP_NVME_TCP_DDGST_RX,
+};
+
+enum {
+ ULP_DDP_A_STAT_IFINDEX = 1,
+ ULP_DDP_A_STAT_PAD,
+ ULP_DDP_A_STAT_RX_NVMEOTCP_SK_ADD,
+ ULP_DDP_A_STAT_RX_NVMEOTCP_SK_ADD_FAIL,
+ ULP_DDP_A_STAT_RX_NVMEOTCP_SK_DEL,
+ ULP_DDP_A_STAT_RX_NVMEOTCP_SETUP,
+ ULP_DDP_A_STAT_RX_NVMEOTCP_SETUP_FAIL,
+ ULP_DDP_A_STAT_RX_NVMEOTCP_TEARDOWN,
+ ULP_DDP_A_STAT_RX_NVMEOTCP_DROP,
+ ULP_DDP_A_STAT_RX_NVMEOTCP_RESYNC,
+ ULP_DDP_A_STAT_RX_NVMEOTCP_PACKETS,
+ ULP_DDP_A_STAT_RX_NVMEOTCP_BYTES,
+
+ __ULP_DDP_A_STAT_MAX,
+ ULP_DDP_A_STAT_MAX = (__ULP_DDP_A_STAT_MAX - 1)
+};
+
+enum {
+ ULP_DDP_A_DEV_IFINDEX = 1,
+ ULP_DDP_A_DEV_HW,
+ ULP_DDP_A_DEV_ACTIVE,
+ ULP_DDP_A_DEV_WANTED,
+ ULP_DDP_A_DEV_WANTED_MASK,
+ ULP_DDP_A_DEV_PAD,
+
+ __ULP_DDP_A_DEV_MAX,
+ ULP_DDP_A_DEV_MAX = (__ULP_DDP_A_DEV_MAX - 1)
+};
+
+enum {
+ ULP_DDP_CMD_GET = 1,
+ ULP_DDP_CMD_STATS,
+ ULP_DDP_CMD_SET,
+ ULP_DDP_CMD_SET_NTF,
+
+ __ULP_DDP_CMD_MAX,
+ ULP_DDP_CMD_MAX = (__ULP_DDP_CMD_MAX - 1)
+};
+
+#define ULP_DDP_MCGRP_MGMT "mgmt"
+
+#endif /* _UAPI_LINUX_ULP_DDP_H */
diff --git a/net/core/Makefile b/net/core/Makefile
index 09da9ed3f9ff..35a882e7276d 100644
--- a/net/core/Makefile
+++ b/net/core/Makefile
@@ -18,7 +18,7 @@ obj-y += dev.o dev_addr_lists.o dst.o netevent.o \
obj-$(CONFIG_NETDEV_ADDR_LIST_TEST) += dev_addr_lists_test.o
obj-y += net-sysfs.o
-obj-$(CONFIG_ULP_DDP) += ulp_ddp.o
+obj-$(CONFIG_ULP_DDP) += ulp_ddp.o ulp_ddp_nl.o ulp_ddp_gen_nl.o
obj-$(CONFIG_PAGE_POOL) += page_pool.o
obj-$(CONFIG_PROC_FS) += net-procfs.o
obj-$(CONFIG_NET_PKTGEN) += pktgen.o
diff --git a/net/core/ulp_ddp_gen_nl.c b/net/core/ulp_ddp_gen_nl.c
new file mode 100644
index 000000000000..505bdc69b215
--- /dev/null
+++ b/net/core/ulp_ddp_gen_nl.c
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause)
+/* Do not edit directly, auto-generated from: */
+/* Documentation/netlink/specs/ulp_ddp.yaml */
+/* YNL-GEN kernel source */
+
+#include <net/netlink.h>
+#include <net/genetlink.h>
+
+#include "ulp_ddp_gen_nl.h"
+
+#include <uapi/linux/ulp_ddp_nl.h>
+
+/* ULP_DDP_CMD_GET - do */
+static const struct nla_policy ulp_ddp_get_nl_policy[ULP_DDP_A_DEV_IFINDEX + 1] = {
+ [ULP_DDP_A_DEV_IFINDEX] = { .type = NLA_U32, },
+};
+
+/* ULP_DDP_CMD_STATS - do */
+static const struct nla_policy ulp_ddp_stats_nl_policy[ULP_DDP_A_STAT_IFINDEX + 1] = {
+ [ULP_DDP_A_STAT_IFINDEX] = { .type = NLA_U32, },
+};
+
+/* ULP_DDP_CMD_SET - do */
+static const struct nla_policy ulp_ddp_set_nl_policy[ULP_DDP_A_DEV_WANTED_MASK + 1] = {
+ [ULP_DDP_A_DEV_IFINDEX] = { .type = NLA_U32, },
+ [ULP_DDP_A_DEV_WANTED] = NLA_POLICY_MASK(NLA_U64, 0x3),
+ [ULP_DDP_A_DEV_WANTED_MASK] = NLA_POLICY_MASK(NLA_U64, 0x3),
+};
+
+/* Ops table for ulp_ddp */
+static const struct genl_split_ops ulp_ddp_nl_ops[] = {
+ {
+ .cmd = ULP_DDP_CMD_GET,
+ .pre_doit = ulp_ddp_get_netdev,
+ .doit = ulp_ddp_nl_get_doit,
+ .post_doit = ulp_ddp_put_netdev,
+ .policy = ulp_ddp_get_nl_policy,
+ .maxattr = ULP_DDP_A_DEV_IFINDEX,
+ .flags = GENL_CMD_CAP_DO,
+ },
+ {
+ .cmd = ULP_DDP_CMD_GET,
+ .dumpit = ulp_ddp_nl_get_dumpit,
+ .flags = GENL_CMD_CAP_DUMP,
+ },
+ {
+ .cmd = ULP_DDP_CMD_STATS,
+ .pre_doit = ulp_ddp_get_netdev,
+ .doit = ulp_ddp_nl_stats_doit,
+ .post_doit = ulp_ddp_put_netdev,
+ .policy = ulp_ddp_stats_nl_policy,
+ .maxattr = ULP_DDP_A_STAT_IFINDEX,
+ .flags = GENL_CMD_CAP_DO,
+ },
+ {
+ .cmd = ULP_DDP_CMD_STATS,
+ .dumpit = ulp_ddp_nl_stats_dumpit,
+ .flags = GENL_CMD_CAP_DUMP,
+ },
+ {
+ .cmd = ULP_DDP_CMD_SET,
+ .pre_doit = ulp_ddp_get_netdev,
+ .doit = ulp_ddp_nl_set_doit,
+ .post_doit = ulp_ddp_put_netdev,
+ .policy = ulp_ddp_set_nl_policy,
+ .maxattr = ULP_DDP_A_DEV_WANTED_MASK,
+ .flags = GENL_CMD_CAP_DO,
+ },
+};
+
+static const struct genl_multicast_group ulp_ddp_nl_mcgrps[] = {
+ [ULP_DDP_NLGRP_MGMT] = { "mgmt", },
+};
+
+struct genl_family ulp_ddp_nl_family __ro_after_init = {
+ .name = ULP_DDP_FAMILY_NAME,
+ .version = ULP_DDP_FAMILY_VERSION,
+ .netnsok = true,
+ .parallel_ops = true,
+ .module = THIS_MODULE,
+ .split_ops = ulp_ddp_nl_ops,
+ .n_split_ops = ARRAY_SIZE(ulp_ddp_nl_ops),
+ .mcgrps = ulp_ddp_nl_mcgrps,
+ .n_mcgrps = ARRAY_SIZE(ulp_ddp_nl_mcgrps),
+};
diff --git a/net/core/ulp_ddp_gen_nl.h b/net/core/ulp_ddp_gen_nl.h
new file mode 100644
index 000000000000..277fb9dbfdcd
--- /dev/null
+++ b/net/core/ulp_ddp_gen_nl.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
+/* Do not edit directly, auto-generated from: */
+/* Documentation/netlink/specs/ulp_ddp.yaml */
+/* YNL-GEN kernel header */
+
+#ifndef _LINUX_ULP_DDP_GEN_H
+#define _LINUX_ULP_DDP_GEN_H
+
+#include <net/netlink.h>
+#include <net/genetlink.h>
+
+#include <uapi/linux/ulp_ddp_nl.h>
+
+int ulp_ddp_get_netdev(const struct genl_split_ops *ops, struct sk_buff *skb,
+ struct genl_info *info);
+void
+ulp_ddp_put_netdev(const struct genl_split_ops *ops, struct sk_buff *skb,
+ struct genl_info *info);
+
+int ulp_ddp_nl_get_doit(struct sk_buff *skb, struct genl_info *info);
+int ulp_ddp_nl_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb);
+int ulp_ddp_nl_stats_doit(struct sk_buff *skb, struct genl_info *info);
+int ulp_ddp_nl_stats_dumpit(struct sk_buff *skb, struct netlink_callback *cb);
+int ulp_ddp_nl_set_doit(struct sk_buff *skb, struct genl_info *info);
+
+enum {
+ ULP_DDP_NLGRP_MGMT,
+};
+
+extern struct genl_family ulp_ddp_nl_family;
+
+#endif /* _LINUX_ULP_DDP_GEN_H */
diff --git a/net/core/ulp_ddp_nl.c b/net/core/ulp_ddp_nl.c
new file mode 100644
index 000000000000..55e5c51b6d88
--- /dev/null
+++ b/net/core/ulp_ddp_nl.c
@@ -0,0 +1,388 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ulp_ddp.c
+ * Author: Aurelien Aptel <aaptel@nvidia.com>
+ * Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+ */
+#include <net/ulp_ddp.h>
+#include "ulp_ddp_gen_nl.h"
+
+#define ULP_DDP_STATS_CNT (sizeof(struct netlink_ulp_ddp_stats) / sizeof(u64))
+
+struct reply_data {
+ struct net_device *dev;
+ netdevice_tracker tracker;
+ void *hdr;
+ u32 ifindex;
+ DECLARE_BITMAP(hw, ULP_DDP_C_COUNT);
+ DECLARE_BITMAP(active, ULP_DDP_C_COUNT);
+ struct netlink_ulp_ddp_stats stats;
+};
+
+static size_t reply_size(int cmd)
+{
+ size_t len = 0;
+
+ BUILD_BUG_ON(ULP_DDP_C_COUNT > 64);
+
+ /* ifindex */
+ len += nla_total_size(sizeof(u32));
+
+ switch (cmd) {
+ case ULP_DDP_CMD_GET:
+ case ULP_DDP_CMD_SET:
+ case ULP_DDP_CMD_SET_NTF:
+ /* hw */
+ len += nla_total_size_64bit(sizeof(u64));
+
+ /* active */
+ len += nla_total_size_64bit(sizeof(u64));
+ break;
+ case ULP_DDP_CMD_STATS:
+ /* stats */
+ len += nla_total_size_64bit(sizeof(u64)) * ULP_DDP_STATS_CNT;
+ break;
+ }
+
+ return len;
+}
+
+/* pre_doit */
+int ulp_ddp_get_netdev(const struct genl_split_ops *ops,
+ struct sk_buff *skb, struct genl_info *info)
+{
+ struct reply_data *data;
+
+ if (GENL_REQ_ATTR_CHECK(info, ULP_DDP_A_DEV_IFINDEX))
+ return -EINVAL;
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->ifindex = nla_get_u32(info->attrs[ULP_DDP_A_DEV_IFINDEX]);
+ data->dev = netdev_get_by_index(genl_info_net(info),
+ data->ifindex,
+ &data->tracker,
+ GFP_KERNEL);
+ if (!data->dev) {
+ kfree(data);
+ NL_SET_BAD_ATTR(info->extack,
+ info->attrs[ULP_DDP_A_DEV_IFINDEX]);
+ return -ENOENT;
+ }
+
+ info->user_ptr[0] = data;
+ return 0;
+}
+
+/* post_doit */
+void ulp_ddp_put_netdev(const struct genl_split_ops *ops, struct sk_buff *skb,
+ struct genl_info *info)
+{
+ struct reply_data *data = info->user_ptr[0];
+
+ if (data) {
+ if (data->dev)
+ netdev_put(data->dev, &data->tracker);
+ kfree(data);
+ }
+}
+
+static int prepare_data(struct reply_data *data, int cmd)
+{
+ const struct ulp_ddp_dev_ops *ops = data->dev->netdev_ops->ulp_ddp_ops;
+ struct ulp_ddp_netdev_caps *caps = &data->dev->ulp_ddp_caps;
+
+ if (!ops)
+ return -EOPNOTSUPP;
+
+ switch (cmd) {
+ case ULP_DDP_CMD_GET:
+ case ULP_DDP_CMD_SET:
+ case ULP_DDP_CMD_SET_NTF:
+ bitmap_copy(data->hw, caps->hw, ULP_DDP_C_COUNT);
+ bitmap_copy(data->active, caps->active, ULP_DDP_C_COUNT);
+ break;
+ case ULP_DDP_CMD_STATS:
+ ops->get_stats(data->dev, &data->stats);
+ break;
+ }
+
+ return 0;
+}
+
+static int fill_data(struct sk_buff *rsp, struct reply_data *data, int cmd,
+ const struct genl_info *info)
+{
+ u64 *val = (u64 *)&data->stats;
+ int attr, i;
+
+ data->hdr = genlmsg_iput(rsp, info);
+ if (!data->hdr)
+ return -EMSGSIZE;
+
+ switch (cmd) {
+ case ULP_DDP_CMD_GET:
+ case ULP_DDP_CMD_SET:
+ case ULP_DDP_CMD_SET_NTF:
+ if (nla_put_u32(rsp, ULP_DDP_A_DEV_IFINDEX, data->ifindex) ||
+ nla_put_u64_64bit(rsp, ULP_DDP_A_DEV_HW,
+ data->hw[0], ULP_DDP_A_DEV_PAD) ||
+ nla_put_u64_64bit(rsp, ULP_DDP_A_DEV_ACTIVE,
+ data->active[0], ULP_DDP_A_DEV_PAD))
+ goto err_cancel_msg;
+ break;
+ case ULP_DDP_CMD_STATS:
+ if (nla_put_u32(rsp, ULP_DDP_A_STAT_IFINDEX, data->ifindex))
+ goto err_cancel_msg;
+
+ attr = ULP_DDP_A_STAT_PAD + 1;
+ for (i = 0; i < ULP_DDP_STATS_CNT; i++, attr++)
+ if (nla_put_u64_64bit(rsp, attr, val[i],
+ ULP_DDP_A_STAT_PAD))
+ goto err_cancel_msg;
+ }
+ genlmsg_end(rsp, data->hdr);
+
+ return 0;
+
+err_cancel_msg:
+ genlmsg_cancel(rsp, data->hdr);
+
+ return -EMSGSIZE;
+}
+
+int ulp_ddp_nl_get_doit(struct sk_buff *req, struct genl_info *info)
+{
+ struct reply_data *data = info->user_ptr[0];
+ struct sk_buff *rsp;
+ int ret = 0;
+
+ ret = prepare_data(data, ULP_DDP_CMD_GET);
+ if (ret)
+ return ret;
+
+ rsp = genlmsg_new(reply_size(ULP_DDP_CMD_GET), GFP_KERNEL);
+ if (!rsp)
+ return -EMSGSIZE;
+
+ ret = fill_data(rsp, data, ULP_DDP_CMD_GET, info);
+ if (ret < 0)
+ goto err_rsp;
+
+ return genlmsg_reply(rsp, info);
+
+err_rsp:
+ nlmsg_free(rsp);
+ return ret;
+}
+
+static void ulp_ddp_nl_notify_dev(struct reply_data *data)
+{
+ struct genl_info info;
+ struct sk_buff *ntf;
+
+ if (!genl_has_listeners(&ulp_ddp_nl_family, dev_net(data->dev),
+ ULP_DDP_NLGRP_MGMT))
+ return;
+
+ genl_info_init_ntf(&info, &ulp_ddp_nl_family, ULP_DDP_CMD_SET_NTF);
+ ntf = genlmsg_new(reply_size(ULP_DDP_CMD_GET), GFP_KERNEL);
+ if (!ntf)
+ return;
+
+ if (fill_data(ntf, data, ULP_DDP_CMD_SET_NTF, &info)) {
+ nlmsg_free(ntf);
+ return;
+ }
+
+ genlmsg_multicast_netns(&ulp_ddp_nl_family, dev_net(data->dev), ntf,
+ 0, ULP_DDP_NLGRP_MGMT, GFP_KERNEL);
+}
+
+static int apply_bits(struct reply_data *data,
+ unsigned long *req_wanted,
+ unsigned long *req_mask,
+ struct netlink_ext_ack *extack)
+{
+ DECLARE_BITMAP(old_active, ULP_DDP_C_COUNT);
+ DECLARE_BITMAP(new_active, ULP_DDP_C_COUNT);
+ DECLARE_BITMAP(all_bits, ULP_DDP_C_COUNT);
+ DECLARE_BITMAP(tmp, ULP_DDP_C_COUNT);
+ const struct ulp_ddp_dev_ops *ops;
+ struct ulp_ddp_netdev_caps *caps;
+ int ret;
+
+ caps = &data->dev->ulp_ddp_caps;
+ ops = data->dev->netdev_ops->ulp_ddp_ops;
+
+ if (!ops)
+ return -EOPNOTSUPP;
+
+ /* if (req_mask & ~all_bits) */
+ bitmap_fill(all_bits, ULP_DDP_C_COUNT);
+ bitmap_andnot(tmp, req_mask, all_bits, ULP_DDP_C_COUNT);
+ if (!bitmap_empty(tmp, ULP_DDP_C_COUNT))
+ return -EINVAL;
+
+ /* new_active = (old_active & ~req_mask) | (wanted & req_mask)
+ * new_active &= caps_hw
+ */
+ bitmap_copy(old_active, caps->active, ULP_DDP_C_COUNT);
+ bitmap_and(req_wanted, req_wanted, req_mask, ULP_DDP_C_COUNT);
+ bitmap_andnot(new_active, old_active, req_mask, ULP_DDP_C_COUNT);
+ bitmap_or(new_active, new_active, req_wanted, ULP_DDP_C_COUNT);
+ bitmap_and(new_active, new_active, caps->hw, ULP_DDP_C_COUNT);
+ if (!bitmap_equal(old_active, new_active, ULP_DDP_C_COUNT)) {
+ ret = ops->set_caps(data->dev, new_active, extack);
+ if (ret < 0)
+ return ret;
+ bitmap_copy(new_active, caps->active, ULP_DDP_C_COUNT);
+ }
+
+ /* return 1 to notify */
+ return !bitmap_equal(old_active, new_active, ULP_DDP_C_COUNT);
+}
+
+int ulp_ddp_nl_set_doit(struct sk_buff *skb, struct genl_info *info)
+{
+ struct reply_data *data = info->user_ptr[0];
+ unsigned long wanted, wanted_mask;
+ struct sk_buff *rsp;
+ bool notify;
+ int ret;
+
+ if (GENL_REQ_ATTR_CHECK(info, ULP_DDP_A_DEV_WANTED) ||
+ GENL_REQ_ATTR_CHECK(info, ULP_DDP_A_DEV_WANTED_MASK))
+ return -EINVAL;
+
+ rsp = genlmsg_new(reply_size(ULP_DDP_CMD_STATS), GFP_KERNEL);
+ if (!rsp)
+ return -EMSGSIZE;
+
+ wanted = nla_get_u64(info->attrs[ULP_DDP_A_DEV_WANTED]);
+ wanted_mask = nla_get_u64(info->attrs[ULP_DDP_A_DEV_WANTED_MASK]);
+
+ ret = apply_bits(data, &wanted, &wanted_mask, info->extack);
+ if (ret < 0)
+ goto err_rsp;
+
+ notify = !!ret;
+ ret = prepare_data(data, ULP_DDP_CMD_SET);
+ if (ret)
+ goto err_rsp;
+
+ ret = fill_data(rsp, data, ULP_DDP_CMD_SET, info);
+ if (ret < 0)
+ goto err_rsp;
+
+ ret = genlmsg_reply(rsp, info);
+ if (notify)
+ ulp_ddp_nl_notify_dev(data);
+
+ return ret;
+
+err_rsp:
+ nlmsg_free(rsp);
+
+ return ret;
+}
+
+int ulp_ddp_nl_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
+{
+ struct net *net = sock_net(skb->sk);
+ struct net_device *netdev;
+ struct reply_data data;
+ int err = 0;
+
+ rtnl_lock();
+ for_each_netdev_dump(net, netdev, cb->args[0]) {
+ memset(&data, 0, sizeof(data));
+ data.dev = netdev;
+ data.ifindex = netdev->ifindex;
+
+ err = prepare_data(&data, ULP_DDP_CMD_GET);
+ if (err)
+ continue;
+
+ err = fill_data(skb, &data, ULP_DDP_CMD_GET,
+ genl_info_dump(cb));
+ if (err < 0)
+ break;
+ }
+ rtnl_unlock();
+
+ if (err != -EMSGSIZE)
+ return err;
+
+ return skb->len;
+}
+
+int ulp_ddp_nl_stats_doit(struct sk_buff *skb, struct genl_info *info)
+{
+ struct reply_data *data = info->user_ptr[0];
+ struct sk_buff *rsp;
+ int ret = 0;
+
+ ret = prepare_data(data, ULP_DDP_CMD_STATS);
+ if (ret)
+ return ret;
+
+ rsp = genlmsg_new(reply_size(ULP_DDP_CMD_STATS), GFP_KERNEL);
+ if (!rsp)
+ return -EMSGSIZE;
+
+ ret = fill_data(rsp, data, ULP_DDP_CMD_STATS, info);
+ if (ret < 0)
+ goto err_rsp;
+
+ return genlmsg_reply(rsp, info);
+
+err_rsp:
+ nlmsg_free(rsp);
+ return ret;
+}
+
+int ulp_ddp_nl_stats_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
+{
+ struct net *net = sock_net(skb->sk);
+ struct net_device *netdev;
+ struct reply_data data;
+ int err = 0;
+
+ rtnl_lock();
+ for_each_netdev_dump(net, netdev, cb->args[0]) {
+ memset(&data, 0, sizeof(data));
+ data.dev = netdev;
+ data.ifindex = netdev->ifindex;
+
+ err = prepare_data(&data, ULP_DDP_CMD_STATS);
+ if (err)
+ continue;
+
+ err = fill_data(skb, &data, ULP_DDP_CMD_STATS,
+ genl_info_dump(cb));
+ if (err < 0)
+ break;
+ }
+ rtnl_unlock();
+
+ if (err != -EMSGSIZE)
+ return err;
+
+ return skb->len;
+}
+
+static int __init ulp_ddp_init(void)
+{
+ int err;
+
+ err = genl_register_family(&ulp_ddp_nl_family);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+subsys_initcall(ulp_ddp_init);
--
2.34.1
next prev parent reply other threads:[~2023-09-12 10:00 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-09-12 9:59 [PATCH v15 00/20] nvme-tcp receive offloads Aurelien Aptel
2023-09-12 9:59 ` [PATCH v15 01/20] net: Introduce direct data placement tcp offload Aurelien Aptel
2023-09-12 16:17 ` David Ahern
2023-09-21 7:43 ` Aurelien Aptel
2023-09-21 12:33 ` David Ahern
2023-09-21 13:02 ` Aurelien Aptel
2023-09-12 9:59 ` Aurelien Aptel [this message]
2023-09-12 9:59 ` [PATCH v15 03/20] iov_iter: skip copy if src == dst for direct data placement Aurelien Aptel
2023-09-12 9:59 ` [PATCH v15 04/20] net/tls,core: export get_netdev_for_sock Aurelien Aptel
2023-09-12 9:59 ` [PATCH v15 05/20] nvme-tcp: Add DDP offload control path Aurelien Aptel
2023-09-12 13:24 ` Sagi Grimberg
2023-09-13 9:10 ` Aurelien Aptel
2023-09-13 10:46 ` Sagi Grimberg
2023-09-18 12:53 ` Aurelien Aptel
2023-09-13 10:49 ` Sagi Grimberg
2023-09-18 18:30 ` Aurelien Aptel
2023-09-12 9:59 ` [PATCH v15 06/20] nvme-tcp: Add DDP data-path Aurelien Aptel
2023-09-13 10:51 ` Sagi Grimberg
2023-09-18 18:26 ` Aurelien Aptel
2023-09-19 7:04 ` Sagi Grimberg
2023-09-20 8:39 ` Aurelien Aptel
2023-09-20 10:11 ` Sagi Grimberg
2023-09-20 16:04 ` Aurelien Aptel
2023-09-12 9:59 ` [PATCH v15 07/20] nvme-tcp: RX DDGST offload Aurelien Aptel
2023-09-12 9:59 ` [PATCH v15 08/20] nvme-tcp: Deal with netdevice DOWN events Aurelien Aptel
2023-09-12 9:59 ` [PATCH v15 09/20] Documentation: add ULP DDP offload documentation Aurelien Aptel
2023-09-12 9:59 ` [PATCH v15 10/20] net/mlx5e: Rename from tls to transport static params Aurelien Aptel
2023-09-12 9:59 ` [PATCH v15 11/20] net/mlx5e: Refactor ico sq polling to get budget Aurelien Aptel
2023-09-12 9:59 ` [PATCH v15 12/20] net/mlx5: Add NVMEoTCP caps, HW bits, 128B CQE and enumerations Aurelien Aptel
2023-09-12 9:59 ` [PATCH v15 13/20] net/mlx5e: NVMEoTCP, offload initialization Aurelien Aptel
2023-09-12 9:59 ` [PATCH v15 14/20] net/mlx5e: TCP flow steering for nvme-tcp acceleration Aurelien Aptel
2023-09-12 9:59 ` [PATCH v15 15/20] net/mlx5e: NVMEoTCP, use KLM UMRs for buffer registration Aurelien Aptel
2023-09-12 9:59 ` [PATCH v15 16/20] net/mlx5e: NVMEoTCP, queue init/teardown Aurelien Aptel
2023-09-12 9:59 ` [PATCH v15 17/20] net/mlx5e: NVMEoTCP, ddp setup and resync Aurelien Aptel
2023-09-12 9:59 ` [PATCH v15 18/20] net/mlx5e: NVMEoTCP, async ddp invalidation Aurelien Aptel
2023-09-12 9:59 ` [PATCH v15 19/20] net/mlx5e: NVMEoTCP, data-path for DDP+DDGST offload Aurelien Aptel
2023-09-12 9:59 ` [PATCH v15 20/20] net/mlx5e: NVMEoTCP, statistics Aurelien Aptel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230912095949.5474-3-aaptel@nvidia.com \
--to=aaptel@nvidia.com \
--cc=aurelien.aptel@gmail.com \
--cc=axboe@fb.com \
--cc=borisp@nvidia.com \
--cc=chaitanyak@nvidia.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=galshalom@nvidia.com \
--cc=hch@lst.de \
--cc=imagedong@tencent.com \
--cc=kbusch@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-nvme@lists.infradead.org \
--cc=malin1024@gmail.com \
--cc=mgurtovoy@nvidia.com \
--cc=netdev@vger.kernel.org \
--cc=ogerlitz@nvidia.com \
--cc=pabeni@redhat.com \
--cc=sagi@grimberg.me \
--cc=smalin@nvidia.com \
--cc=yorayz@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).