[RFC PATCH v4 22/38] NTB: ntb_transport: Split core library and default NTB client

Koichiro Den <[email protected]>
Newsgroups dev.linux.lists.ntb,dev.linux.lists.iommu,org.kernel.vger.dmaengine,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-doc,org.kernel.vger.linux-kernel,org.kernel.vger.linux-kselftest,org.kernel.vger.linux-pci,org.kernel.vger.linux-renesas-soc,org.kernel.vger.netdev
Message-ID <[email protected]>
The transport code is being refactored to support multiple clients and
transport backends. As a first step, split the module into a core
library and a thin default client that binds to NTB ports.

Move module parameters and the legacy ntb_client glue into a new
ntb_transport.c. Export ntb_transport_attach()/ntb_transport_detach()
from the core so other clients can reuse the common transport
infrastructure.

No functional change intended for the default transport.

Signed-off-by: Koichiro Den <[email protected]>
---
 drivers/ntb/Makefile                 |  3 +-
 drivers/ntb/ntb_transport.c          | 81 ++++++++++++++++++++++++
 drivers/ntb/ntb_transport_core.c     | 93 ++++++++++------------------
 drivers/ntb/ntb_transport_internal.h | 15 +++++
 4 files changed, 128 insertions(+), 64 deletions(-)
 create mode 100644 drivers/ntb/ntb_transport.c

diff --git a/drivers/ntb/Makefile b/drivers/ntb/Makefile
index 9b66e5fafbc0..47e6b95ef7ce 100644
--- a/drivers/ntb/Makefile
+++ b/drivers/ntb/Makefile
@@ -1,8 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_NTB) += ntb.o hw/ test/
 obj-$(CONFIG_NTB_TRANSPORT) += ntb_transport.o
+obj-$(CONFIG_NTB_TRANSPORT) += ntb_transport_core.o
 
 ntb-y			:= core.o
 ntb-$(CONFIG_NTB_MSI)	+= msi.o
-
-ntb_transport-y		:= ntb_transport_core.o
diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c
new file mode 100644
index 000000000000..dafb97e38883
--- /dev/null
+++ b/drivers/ntb/ntb_transport.c
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
+/*
+ * Copyright(c) 2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2015 EMC Corporation. All Rights Reserved.
+ *
+ * Default NTB transport client module.
+ *
+ * The transport core library and backend infrastructure are implemented in
+ * ntb_transport_core.c. This module provides the default client that binds
+ * to NTB ports and instantiates the default transport for consumers such
+ * as ntb_netdev.
+ */
+
+#include <linux/module.h>
+#include <linux/ntb.h>
+
+#include "ntb_transport_internal.h"
+
+static unsigned long max_mw_size;
+module_param(max_mw_size, ulong, 0644);
+MODULE_PARM_DESC(max_mw_size, "Limit size of large memory windows");
+
+static unsigned int transport_mtu = 0x10000;
+module_param(transport_mtu, uint, 0644);
+MODULE_PARM_DESC(transport_mtu, "Maximum size of NTB transport packets");
+
+static unsigned char max_num_clients;
+module_param(max_num_clients, byte, 0644);
+MODULE_PARM_DESC(max_num_clients, "Maximum number of NTB transport clients");
+
+static unsigned int copy_bytes = 1024;
+module_param(copy_bytes, uint, 0644);
+MODULE_PARM_DESC(copy_bytes, "Threshold under which NTB will use the CPU to copy instead of DMA");
+
+static bool use_dma;
+module_param(use_dma, bool, 0644);
+MODULE_PARM_DESC(use_dma, "Use DMA engine to perform large data copy");
+
+static bool use_msi;
+#ifdef CONFIG_NTB_MSI
+module_param(use_msi, bool, 0644);
+MODULE_PARM_DESC(use_msi, "Use MSI interrupts instead of doorbells");
+#endif
+
+#define NTB_QP_DEF_NUM_ENTRIES	100
+
+static int ntb_transport_host_probe(struct ntb_client *self,
+				    struct ntb_dev *ndev)
+{
+	return ntb_transport_attach(ndev, "default", use_msi, max_mw_size,
+				    transport_mtu, max_num_clients, copy_bytes,
+				    use_dma, NTB_QP_DEF_NUM_ENTRIES);
+}
+
+static void ntb_transport_host_remove(struct ntb_client *self, struct ntb_dev *ndev)
+{
+	ntb_transport_detach(ndev);
+}
+
+static struct ntb_client ntb_transport_host_client = {
+	.ops = {
+		.probe = ntb_transport_host_probe,
+		.remove = ntb_transport_host_remove,
+	},
+};
+
+static int __init ntb_transport_host_init(void)
+{
+	return ntb_register_client(&ntb_transport_host_client);
+}
+module_init(ntb_transport_host_init);
+
+static void __exit ntb_transport_host_exit(void)
+{
+	ntb_unregister_client(&ntb_transport_host_client);
+}
+module_exit(ntb_transport_host_exit);
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_AUTHOR("Intel Corporation");
+MODULE_DESCRIPTION("Software Queue-Pair Transport over NTB");
diff --git a/drivers/ntb/ntb_transport_core.c b/drivers/ntb/ntb_transport_core.c
index 04a13fdce71c..86181fe1eadd 100644
--- a/drivers/ntb/ntb_transport_core.c
+++ b/drivers/ntb/ntb_transport_core.c
@@ -69,7 +69,7 @@
 #define NTB_TRANSPORT_VERSION	4
 #define NTB_TRANSPORT_VER	"4"
 #define NTB_TRANSPORT_NAME	"ntb_transport"
-#define NTB_TRANSPORT_DESC	"Software Queue-Pair Transport over NTB"
+#define NTB_TRANSPORT_DESC	"NTB transport core library"
 #define NTB_TRANSPORT_MIN_SPADS (MW0_SZ_HIGH + 2)
 
 MODULE_DESCRIPTION(NTB_TRANSPORT_DESC);
@@ -77,31 +77,6 @@ MODULE_VERSION(NTB_TRANSPORT_VER);
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_AUTHOR("Intel Corporation");
 
-static unsigned long max_mw_size;
-module_param(max_mw_size, ulong, 0644);
-MODULE_PARM_DESC(max_mw_size, "Limit size of large memory windows");
-
-static unsigned int transport_mtu = 0x10000;
-module_param(transport_mtu, uint, 0644);
-MODULE_PARM_DESC(transport_mtu, "Maximum size of NTB transport packets");
-
-static unsigned char max_num_clients;
-module_param(max_num_clients, byte, 0644);
-MODULE_PARM_DESC(max_num_clients, "Maximum number of NTB transport clients");
-
-static unsigned int copy_bytes = 1024;
-module_param(copy_bytes, uint, 0644);
-MODULE_PARM_DESC(copy_bytes, "Threshold under which NTB will use the CPU to copy instead of DMA");
-
-static bool use_dma;
-module_param(use_dma, bool, 0644);
-MODULE_PARM_DESC(use_dma, "Use DMA engine to perform large data copy");
-
-static bool use_msi;
-#ifdef CONFIG_NTB_MSI
-module_param(use_msi, bool, 0644);
-MODULE_PARM_DESC(use_msi, "Use MSI interrupts instead of doorbells");
-#endif
 
 static struct dentry *nt_debugfs_dir;
 
@@ -135,12 +110,10 @@ enum {
 #define drv_client(__drv) \
 	container_of((__drv), struct ntb_transport_client, driver)
 
-#define NTB_QP_DEF_NUM_ENTRIES	100
 #define NTB_LINK_DOWN_TIMEOUT	10
 
 static void ntb_transport_rxc_db(unsigned long data);
 static const struct ntb_ctx_ops ntb_transport_ops;
-static struct ntb_client ntb_transport_client;
 static int ntb_async_tx_submit(struct ntb_transport_qp *qp,
 			       struct ntb_queue_entry *entry);
 static void ntb_memcpy_tx(struct ntb_queue_entry *entry, void __iomem *offset);
@@ -456,8 +429,8 @@ static int ntb_transport_setup_qp_mw(struct ntb_transport_ctx *nt,
 
 	if (mw_size > mw->xlat_size)
 		mw_size = mw->xlat_size;
-	if (max_mw_size && mw_size > max_mw_size)
-		mw_size = max_mw_size;
+	if (nt->max_mw_size && mw_size > nt->max_mw_size)
+		mw_size = nt->max_mw_size;
 
 	tx_size = (unsigned int)mw_size / num_qps_mw;
 	qp_offset = tx_size * (qp_num / mw_count);
@@ -481,9 +454,9 @@ static int ntb_transport_setup_qp_mw(struct ntb_transport_ctx *nt,
 	qp->rx_info = qp->tx_mw + tx_size;
 
 	/* Due to housekeeping, there must be atleast 2 buffs */
-	qp->tx_max_frame = min(transport_mtu, tx_size / 2);
+	qp->tx_max_frame = min(nt->transport_mtu, tx_size / 2);
 	qp->tx_max_entry = tx_size / qp->tx_max_frame;
-	qp->rx_max_frame = min(transport_mtu, rx_size / 2);
+	qp->rx_max_frame = min(nt->transport_mtu, rx_size / 2);
 	qp->rx_max_entry = rx_size / qp->rx_max_frame;
 	qp->rx_index = 0;
 
@@ -909,8 +882,8 @@ static void ntb_transport_link_work(struct work_struct *work)
 	for (i = 0; i < nt->mw_count; i++) {
 		size = nt->mw_vec[i].phys_size;
 
-		if (max_mw_size && size > max_mw_size)
-			size = max_mw_size;
+		if (nt->max_mw_size && size > nt->max_mw_size)
+			size = nt->max_mw_size;
 
 		spad = MW0_SZ_HIGH + (i * 2);
 		ntb_peer_spad_write(ndev, PIDX, spad, upper_32_bits(size));
@@ -1084,7 +1057,12 @@ static int ntb_transport_init_queue(struct ntb_transport_ctx *nt,
 	return 0;
 }
 
-static int ntb_transport_probe(struct ntb_client *self, struct ntb_dev *ndev)
+int ntb_transport_attach(struct ntb_dev *ndev, const char *backend_name,
+			 bool use_msi, unsigned long max_mw_size,
+			 unsigned int transport_mtu,
+			 unsigned char max_num_clients,
+			 unsigned int copy_bytes, bool use_dma,
+			 unsigned int num_rx_entries)
 {
 	struct ntb_transport_ctx *nt;
 	struct ntb_transport_mw *mw;
@@ -1117,6 +1095,11 @@ static int ntb_transport_probe(struct ntb_client *self, struct ntb_dev *ndev)
 		return -ENOMEM;
 
 	nt->ndev = ndev;
+	nt->max_mw_size = max_mw_size;
+	nt->transport_mtu = transport_mtu;
+	nt->copy_bytes = copy_bytes;
+	nt->use_dma = use_dma;
+	nt->num_rx_entries = num_rx_entries;
 
 	/*
 	 * If we are using MSI, and have at least one extra memory window,
@@ -1241,8 +1224,9 @@ static int ntb_transport_probe(struct ntb_client *self, struct ntb_dev *ndev)
 	kfree(nt);
 	return rc;
 }
+EXPORT_SYMBOL_GPL(ntb_transport_attach);
 
-static void ntb_transport_free(struct ntb_client *self, struct ntb_dev *ndev)
+void ntb_transport_detach(struct ntb_dev *ndev)
 {
 	struct ntb_transport_ctx *nt = ndev->ctx;
 	struct ntb_transport_qp *qp;
@@ -1262,6 +1246,7 @@ static void ntb_transport_free(struct ntb_client *self, struct ntb_dev *ndev)
 			ntb_transport_free_queue(qp);
 		debugfs_remove_recursive(qp->debugfs_dir);
 	}
+	debugfs_remove(nt->debugfs_node_dir);
 
 	ntb_link_disable(ndev);
 	ntb_clear_ctx(ndev);
@@ -1277,6 +1262,7 @@ static void ntb_transport_free(struct ntb_client *self, struct ntb_dev *ndev)
 	kfree(nt->mw_vec);
 	kfree(nt);
 }
+EXPORT_SYMBOL_GPL(ntb_transport_detach);
 
 static void ntb_complete_rxc(struct ntb_transport_qp *qp)
 {
@@ -1438,7 +1424,7 @@ static void ntb_async_rx(struct ntb_queue_entry *entry, void *offset)
 	if (!chan)
 		goto err;
 
-	if (entry->len < copy_bytes)
+	if (entry->len < qp->transport->copy_bytes)
 		goto err;
 
 	res = ntb_async_rx_submit(entry, offset);
@@ -1718,7 +1704,7 @@ static void ntb_async_tx(struct ntb_transport_qp *qp,
 	if (!chan)
 		goto err;
 
-	if (entry->len < copy_bytes)
+	if (entry->len < qp->transport->copy_bytes)
 		goto err;
 
 	res = ntb_async_tx_submit(qp, entry);
@@ -1856,7 +1842,7 @@ ntb_transport_create_queue(void *data, struct device *client_dev,
 	dma_cap_zero(dma_mask);
 	dma_cap_set(DMA_MEMCPY, dma_mask);
 
-	if (use_dma) {
+	if (nt->use_dma) {
 		qp->tx_dma_chan =
 			dma_request_channel(dma_mask, ntb_dma_filter_fn,
 					    (void *)(unsigned long)node);
@@ -1892,7 +1878,7 @@ ntb_transport_create_queue(void *data, struct device *client_dev,
 	dev_dbg(&pdev->dev, "Using %s memcpy for RX\n",
 		qp->rx_dma_chan ? "DMA" : "CPU");
 
-	for (i = 0; i < NTB_QP_DEF_NUM_ENTRIES; i++) {
+	for (i = 0; i < nt->num_rx_entries; i++) {
 		entry = kzalloc_node(sizeof(*entry), GFP_KERNEL, node);
 		if (!entry)
 			goto err1;
@@ -1901,7 +1887,7 @@ ntb_transport_create_queue(void *data, struct device *client_dev,
 		ntb_list_add(&qp->ntb_rx_q_lock, &entry->entry,
 			     &qp->rx_free_q);
 	}
-	qp->rx_alloc_entry = NTB_QP_DEF_NUM_ENTRIES;
+	qp->rx_alloc_entry = nt->num_rx_entries;
 
 	for (i = 0; i < qp->tx_max_entry; i++) {
 		entry = kzalloc_node(sizeof(*entry), GFP_KERNEL, node);
@@ -2301,13 +2287,6 @@ static const struct ntb_ctx_ops ntb_transport_ops = {
 	.db_event = ntb_transport_doorbell_callback,
 };
 
-static struct ntb_client ntb_transport_client = {
-	.ops = {
-		.probe = ntb_transport_probe,
-		.remove = ntb_transport_free,
-	},
-};
-
 static int __init ntb_transport_init(void)
 {
 	int rc;
@@ -2318,26 +2297,16 @@ static int __init ntb_transport_init(void)
 		nt_debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL);
 
 	rc = bus_register(&ntb_transport_bus);
-	if (rc)
-		goto err_bus;
-
-	rc = ntb_register_client(&ntb_transport_client);
-	if (rc)
-		goto err_client;
-
-	return 0;
-
-err_client:
-	bus_unregister(&ntb_transport_bus);
-err_bus:
-	debugfs_remove_recursive(nt_debugfs_dir);
+	if (rc) {
+		bus_unregister(&ntb_transport_bus);
+		debugfs_remove_recursive(nt_debugfs_dir);
+	}
 	return rc;
 }
 module_init(ntb_transport_init);
 
 static void __exit ntb_transport_exit(void)
 {
-	ntb_unregister_client(&ntb_transport_client);
 	bus_unregister(&ntb_transport_bus);
 	debugfs_remove_recursive(nt_debugfs_dir);
 }
diff --git a/drivers/ntb/ntb_transport_internal.h b/drivers/ntb/ntb_transport_internal.h
index 6b45790cc88e..406033dbddb7 100644
--- a/drivers/ntb/ntb_transport_internal.h
+++ b/drivers/ntb/ntb_transport_internal.h
@@ -134,9 +134,17 @@ struct ntb_transport_ctx {
 	struct ntb_transport_qp *qp_vec;
 	unsigned int mw_count;
 	unsigned int qp_count;
+	unsigned int max_qp_count;
 	u64 qp_bitmap;
 	u64 qp_bitmap_free;
 
+	/* Parameters */
+	unsigned int num_rx_entries;
+	unsigned int transport_mtu;
+	unsigned long max_mw_size;
+	unsigned int copy_bytes;
+	bool use_dma;
+
 	bool use_msi;
 	unsigned int msi_spad_offset;
 	u64 msi_db_mask;
@@ -162,5 +170,12 @@ struct ntb_queue_entry *ntb_list_rm(spinlock_t *lock, struct list_head *list);
 struct ntb_queue_entry *ntb_list_mv(spinlock_t *lock, struct list_head *list,
 				    struct list_head *to_list);
 void ntb_qp_link_down(struct ntb_transport_qp *qp);
+int ntb_transport_attach(struct ntb_dev *ndev, const char *backend_name,
+			 bool use_msi, unsigned long max_mw_size,
+			 unsigned int transport_mtu,
+			 unsigned char max_num_clients,
+			 unsigned int copy_bytes, bool use_dma,
+			 unsigned int num_rx_entries);
+void ntb_transport_detach(struct ntb_dev *ndev);
 
 #endif /* _NTB_TRANSPORT_INTERNAL_H_ */
-- 
2.51.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.