Skip to contentSkip to conversation

NTB: Add NTB hardware abstraction layer

PATCH New Allen Hubbe 1 participant 20 messages Jun 10, 2015

Subsystems (5)
lore
Share & tools
lore
#0 lore raw

v4 cover NTB: Add NTB hardware abstraction layer

The NTB drivers currently support only one hardware driver, and one client type. This patch set adds an abstraction layer, enabling hardware drivers by other vendors, and clients other than ntb_transport.

The commits in this set may also be pulled from:
github.com/allenbh/linux
tagged ntb-abh-v4

Compare against previous tags ntb-abh-v1..ntb-abh-v3 to see exactly what changed in the each revised version of this series.

Different in v4:
- Correct spelling, grammer, and capitalization grammer in commit messages.
- Zero-initialize device structure in ntb_hw_intel with kzalloc_node.
- Use __copy_from_user_inatomic_nocache only if the arch has it.
- Split adding the ntb hardware abstraction layer into two patches:
NTB: Add NTB hardware abstraction layer
Adding the abstraction layer now stands alone in its own patch.
NTB: Split ntb_hw_intel and ntb_transport drivers
This patch is still rather large, at just under 200k.
Unfortunately, since the original code in ntb_hw_intel and ntb_transport called in both directions, one driver can't be changed by itself without breaking the other.

Different in v3:
- Reschedule long running tasklets to avoid stalls in transport.
- Initialize driver .owner and .name in ntb_register_client.
- Eliminate calls to BUG() in ntb_hw_intel.
- Fix incorrect PBARXLAT split-bar address assignment in ntb_hw_intel.
- Add bugfix patch: Read peer info from local SPAD in transport.
- Arrange the above bugfix, and three patches affecting transport link down, to earlier in the series, because they are higher importance.
- Add performance patch: Increase transport MTU to 64k form 16k.
- Rebase on ff25ea8f4eee to resolve a merge conflict in MAINTAINERS (conflicting context lines only, no conflicting changes).

Different in v2:
- Rewrite shortlog descriptions for spelling and style
- Remove extraneous NTB dependency from Kconfig files
- Reindent Kconfig files with leading tabs
- Reindent some lines in ntb_transport
- Append patch NTB: Rename intel hw to proper platform names

Allen Hubbe (12):
NTB: Move files in preparation for NTB abstraction
NTB: Add NTB hardware abstraction layer
NTB: Split ntb_hw_intel and ntb_transport drivers
NTB: Differentiate transport link down messages
NTB: Do not advance transport RX on link down
NTB: Reset transport QP link stats on down
NTB: Add parameters for Intel SNB B2B addresses
NTB: Add ping pong test client
NTB: Add tool test client
NTB: Rate limit ntb_qp_link_work
NTB: Use NUMA memory and DMA chan in transport
NTB: Use NUMA memory in Intel driver

Dave Jiang (7):
NTB: Read peer info from local SPAD in transport
NTB: Enable link for Intel root port mode in probe
NTB: Check the device ID to set errata flags
NTB: Improve performance with write combining
NTB: Default to CPU memcpy for performance
NTB: Rename Intel code names to platform names
NTB: Increase transport MTU to 64k from 16k

 Documentation/ntb.txt               |  127 ++
 MAINTAINERS                         |   16 +-
 drivers/net/ntb_netdev.c            |   58 +-
 drivers/ntb/Kconfig                 |   39 +-
 drivers/ntb/Makefile                |    5 +-
 drivers/ntb/hw/Kconfig              |    1 +
 drivers/ntb/hw/Makefile             |    1 +
 drivers/ntb/hw/intel/Kconfig        |    7 +
 drivers/ntb/hw/intel/Makefile       |    1 +
 drivers/ntb/hw/intel/ntb_hw_intel.c | 2214 +++++++++++++++++++++++++++++++++++
 drivers/ntb/hw/intel/ntb_hw_intel.h |  342 ++++++
 drivers/ntb/ntb.c                   |  251 ++++
 drivers/ntb/ntb_hw.c                | 1896 ------------------------------
 drivers/ntb/ntb_hw.h                |  256 ----
 drivers/ntb/ntb_regs.h              |  177 ---
 drivers/ntb/ntb_transport.c         | 1027 +++++++++-------
 drivers/ntb/test/Kconfig            |   19 +
 drivers/ntb/test/Makefile           |    2 +
 drivers/ntb/test/ntb_pingpong.c     |  250 ++++
 drivers/ntb/test/ntb_tool.c         |  556 +++++++++
 include/linux/ntb.h                 |  970 ++++++++++++++-
 include/linux/ntb_transport.h       |   85 ++
 22 files changed, 5485 insertions(+), 2815 deletions(-)
 create mode 100644 Documentation/ntb.txt
 create mode 100644 drivers/ntb/hw/Kconfig
 create mode 100644 drivers/ntb/hw/Makefile
 create mode 100644 drivers/ntb/hw/intel/Kconfig
 create mode 100644 drivers/ntb/hw/intel/Makefile
 create mode 100644 drivers/ntb/hw/intel/ntb_hw_intel.c
 create mode 100644 drivers/ntb/hw/intel/ntb_hw_intel.h
 create mode 100644 drivers/ntb/ntb.c
 delete mode 100644 drivers/ntb/ntb_hw.c
 delete mode 100644 drivers/ntb/ntb_hw.h
 delete mode 100644 drivers/ntb/ntb_regs.h
 create mode 100644 drivers/ntb/test/Kconfig
 create mode 100644 drivers/ntb/test/Makefile
 create mode 100644 drivers/ntb/test/ntb_pingpong.c
 create mode 100644 drivers/ntb/test/ntb_tool.c
 create mode 100644 include/linux/ntb_transport.h
Signature · 1 line
2.4.0.rc0.43.gcf8a8c6
#1 lore raw

PATCH v4 1/19 NTB: Move files in preparation for NTB abstraction

This patch only moves files to their new locations, before applying the next two patches adding the NTB Abstraction layer. Splitting this patch from the next is intended make distinct which code is changed only due to moving the files, versus which are substantial code changes in adding the NTB Abstraction layer.

---
 drivers/net/ntb_netdev.c            |    2 +-
 drivers/ntb/Makefile                |    4 +-
 drivers/ntb/hw/intel/ntb_hw_intel.c | 1895 ++++++++++++++++++++++++++++++++++
 drivers/ntb/hw/intel/ntb_hw_intel.h |  385 +++++++
 drivers/ntb/ntb_hw.c                | 1896 -----------------------------------
 drivers/ntb/ntb_hw.h                |  256 -----
 drivers/ntb/ntb_regs.h              |  177 ----
 drivers/ntb/ntb_transport.c         |    2 +-
 include/linux/ntb.h                 |   88 --
 include/linux/ntb_transport.h       |   88 ++
 10 files changed, 2372 insertions(+), 2421 deletions(-)
 create mode 100644 drivers/ntb/hw/intel/ntb_hw_intel.c
 create mode 100644 drivers/ntb/hw/intel/ntb_hw_intel.h
 delete mode 100644 drivers/ntb/ntb_hw.c
 delete mode 100644 drivers/ntb/ntb_hw.h
 delete mode 100644 drivers/ntb/ntb_regs.h
 delete mode 100644 include/linux/ntb.h
 create mode 100644 include/linux/ntb_transport.h
drivers/net/ntb_netdev.c +1 -1
index 5a7e6397440a..dcf80009f50d 100644
@@ -49,7 +49,7 @@
 #include <linux/ethtool.h>
 #include <linux/module.h>
 #include <linux/pci.h>
-#include <linux/ntb.h>
+#include <linux/ntb_transport.h>
 
 #define NTB_NETDEV_VER	"0.7"
 
drivers/ntb/Makefile +2 -2
index 15cb59fd354e..545b10a131af 100644
@@ -1,3 +1,3 @@
-obj-$(CONFIG_NTB) += ntb.o
+obj-$(CONFIG_NTB) += ntb_hw_intel.o
 
-ntb-objs := ntb_hw.o ntb_transport.o
+ntb_hw_intel-objs := hw/intel/ntb_hw_intel.o ntb_transport.o
drivers/ntb/hw/intel/ntb_hw_intel.c new file +1895 -0

1,895 lines not on this page · raw message

drivers/ntb/hw/intel/ntb_hw_intel.h new file +385 -0

385 lines not on this page · raw message

drivers/ntb/ntb_hw.c deleted +0 -1896

707 lines not on this page · raw message

drivers/ntb/ntb_hw.h deleted +0 -256

256 lines not on this page · raw message

drivers/ntb/ntb_regs.h deleted +0 -177

177 lines not on this page · raw message

drivers/ntb/ntb_transport.c +1 -1
index e9bf2f47b61a..b9d8e197dc3e 100644

Lines of this file are not shown. View the raw message.

include/linux/ntb.h deleted +0 -88

88 lines not on this page · raw message

include/linux/ntb_transport.h new file +88 -0

88 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Signature · 1 line
2.4.0.rc0.43.gcf8a8c6

Part of the diff is not shown here. View the raw message.

#2 lore raw

PATCH v4 2/19 NTB: Add NTB hardware abstraction layer

In reply to Allen Hubbe

Abstract the NTB device behind a programming interface, so that it can support different hardware and client drivers.

---

This was split from the larger patch in v1..v3. This is the first part of the split.

The new NTB api is added in this patch, without the noise of changing the existing drivers to use it. After applying this patch, the new NTB API exists, but the existing hardware and client drivers do not use it. The next patch changes hardware and client drivers.

 Documentation/ntb.txt |  32 ++
 MAINTAINERS           |   5 +-
 drivers/ntb/Makefile  |   1 +
 drivers/ntb/ntb.c     | 251 +++++++++++++
 include/linux/ntb.h   | 984 ++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 1272 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ntb.txt
 create mode 100644 drivers/ntb/ntb.c
 create mode 100644 include/linux/ntb.h
Documentation/ntb.txt new file +32 -0
new file mode 100644
index 000000000000..9d46dc9712a8
@@ -0,0 +1,32 @@
+# NTB Drivers
+
+NTB (Non-Transparent Bridge) is a type of PCI-Express bridge chip that connects
+the separate memory systems of two computers to the same PCI-Express fabric.
+Existing NTB hardware supports a common feature set, including scratchpad
+registers, doorbell registers, and memory translation windows.  Scratchpad
+registers are read-and-writable registers that are accessible from either side
+of the device, so that peers can exchange a small amount of information at a
+fixed address.  Doorbell registers provide a way for peers to send interrupt
+events.  Memory windows allow translated read and write access to the peer
+memory.
+
+## NTB Core Driver (ntb)
+
+The NTB core driver defines an api wrapping the common feature set, and allows
+clients interested in NTB features to discover NTB the devices supported by
+hardware drivers.  The term "client" is used here to mean an upper layer
+component making use of the NTB api.  The term "driver," or "hardware driver,"
+is used here to mean a driver for a specific vendor and model of NTB hardware.
+
+## NTB Client Drivers
+
+NTB client drivers should register with the NTB core driver.  After
+registering, the client probe and remove functions will be called appropriately
+as ntb hardware, or hardware drivers, are inserted and removed.  The
+registration uses the Linux Device framework, so it should feel familiar to
+anyone who has written a pci driver.
+
+## NTB Hardware Drivers
+
+NTB hardware drivers should register devices with the NTB core driver.  After
+registering, clients probe and remove functions will be called.
MAINTAINERS +4 -1
index a5b8584da5bf..2e351265d544 100644
@@ -6978,7 +6978,7 @@ F:	drivers/power/bq27x00_battery.c
 F:	drivers/power/isp1704_charger.c
 F:	drivers/power/rx51_battery.c
 
-NTB DRIVER
+NTB DRIVER CORE
 M:	Jon Mason <[email protected]>
 M:	Dave Jiang <[email protected]>
 S:	Supported
@@ -6986,7 +6986,10 @@ W:	https://github.com/jonmason/ntb/wiki
 T:	git git://github.com/jonmason/ntb.git
 F:	drivers/ntb/
 F:	drivers/net/ntb_netdev.c
+F:	drivers/ntb/ntb.c
+F:	drivers/ntb/ntb_transport.c
 F:	include/linux/ntb.h
+F:	include/linux/ntb_transport.h
 
 NTFS FILESYSTEM
 M:	Anton Altaparmakov <[email protected]>
drivers/ntb/Makefile +1 -0
index 545b10a131af..712e953a8fda 100644
@@ -1,3 +1,4 @@
+obj-$(CONFIG_NTB) += ntb.o
 obj-$(CONFIG_NTB) += ntb_hw_intel.o
 
 ntb_hw_intel-objs := hw/intel/ntb_hw_intel.o ntb_transport.o
drivers/ntb/ntb.c new file +251 -0

251 lines not on this page · raw message

include/linux/ntb.h new file +984 -0

984 lines not on this page · raw message

Signature · 1 line
2.4.0.rc0.43.gcf8a8c6
#3 lore raw

PATCH v4 3/19 NTB: Split ntb_hw_intel and ntb_transport drivers

In reply to Allen Hubbe

Change ntb_hw_intel to use the new NTB hardware abstraction layer.

Split ntb_transport into its own driver. Change it to use the new NTB hardware abstraction layer.

---

This was split from the larger patch in v1..v3. This is the second part of the split.

The existing NTB driver, which comprised the the Intel NTB hardware driver and the NTB transport driver, are split into ntb_hw_intel and ntb_transport, using the new NTB hardware abstraction layer.

This patch is still large, now at just under 200k. Since the original driver comprised both ntb_hw_intel and ntb_transport in the same driver, both pieces have to be changed at the same time.

 Documentation/ntb.txt               |   26 +
 MAINTAINERS                         |    9 +
 drivers/net/ntb_netdev.c            |   58 +-
 drivers/ntb/Kconfig                 |   37 +-
 drivers/ntb/Makefile                |    6 +-
 drivers/ntb/hw/Kconfig              |    1 +
 drivers/ntb/hw/Makefile             |    1 +
 drivers/ntb/hw/intel/Kconfig        |    7 +
 drivers/ntb/hw/intel/Makefile       |    1 +
 drivers/ntb/hw/intel/ntb_hw_intel.c | 3077 +++++++++++++++++++----------------
 drivers/ntb/hw/intel/ntb_hw_intel.h |  607 ++++---
 drivers/ntb/ntb_transport.c         |  944 ++++++-----
 include/linux/ntb_transport.h       |   25 +-
 13 files changed, 2599 insertions(+), 2200 deletions(-)
 create mode 100644 drivers/ntb/hw/Kconfig
 create mode 100644 drivers/ntb/hw/Makefile
 create mode 100644 drivers/ntb/hw/intel/Kconfig
 create mode 100644 drivers/ntb/hw/intel/Makefile
Documentation/ntb.txt +26 -0
index 9d46dc9712a8..725ba1e6c127 100644
@@ -26,7 +26,33 @@ as ntb hardware, or hardware drivers, are inserted and removed.  The
 registration uses the Linux Device framework, so it should feel familiar to
 anyone who has written a pci driver.
 
+### NTB Transport Client (ntb\_transport) and NTB Netdev (ntb\_netdev)
+
+The primary client for NTB is the Transport client, used in tandem with NTB
+Netdev.  These drivers function together to create a logical link to the peer,
+across the ntb, to exchange packets of network data.  The Transport client
+establishes a logical link to the peer, and creates queue pairs to exchange
+messages and data.  The NTB Netdev then creates an ethernet device using a
+Transport queue pair.  Network data is copied between socket buffers and the
+Transport queue pair buffer.  The Transport client may be used for other things
+besides Netdev, however no other applications have yet been written.
+
 ## NTB Hardware Drivers
 
 NTB hardware drivers should register devices with the NTB core driver.  After
 registering, clients probe and remove functions will be called.
+
+### NTB Intel Hardware Driver (ntb\_hw\_intel)
+
+The Intel hardware driver supports NTB on Xeon and Atom CPUs.
+
+Module Parameters:
+
+* b2b\_mw\_idx - If the peer ntb is to be accessed via a memory window, then use
+	this memory window to access the peer ntb.  A value of zero or positive
+	starts from the first mw idx, and a negative value starts from the last
+	mw idx.  Both sides MUST set the same value here!  The default value is
+	`-1`.
+* b2b\_mw\_share - If the peer ntb is to be accessed via a memory window, and if
+	the memory window is large enough, still allow the client to use the
+	second half of the memory window for address translation to the peer.
MAINTAINERS +9 -0
index 2e351265d544..1a09fd12b6d2 100644
@@ -6991,6 +6991,15 @@ F:	drivers/ntb/ntb_transport.c
 F:	include/linux/ntb.h
 F:	include/linux/ntb_transport.h
 
+NTB INTEL DRIVER
+M:	Jon Mason <[email protected]>
+M:	Dave Jiang <[email protected]>
+S:	Supported
+W:	https://github.com/jonmason/ntb/wiki
+T:	git git://github.com/jonmason/ntb.git
+F:	drivers/ntb/hw/intel/ntb_hw_intel.c
+F:	drivers/ntb/hw/intel/ntb_hw_intel.h
+
 NTFS FILESYSTEM
 M:	Anton Altaparmakov <[email protected]>
 L:	[email protected]
drivers/net/ntb_netdev.c +32 -26

153 lines not on this page · raw message

drivers/ntb/Kconfig +25 -12
index f69df793dbe2..53b042429673 100644
@@ -1,13 +1,26 @@
-config NTB
-       tristate "Intel Non-Transparent Bridge support"
-       depends on PCI
-       depends on X86
-       help
-        The PCI-E Non-transparent bridge hardware is a point-to-point PCI-E bus
-        connecting 2 systems.  When configured, writes to the device's PCI
-        mapped memory will be mirrored to a buffer on the remote system.  The
-        ntb Linux driver uses this point-to-point communication as a method to
-        transfer data from one system to the other.
-
-        If unsure, say N.
+menuconfig NTB
+	tristate "Non-Transparent Bridge support"
+	depends on PCI
+	help
+	 The PCI-E Non-transparent bridge hardware is a point-to-point PCI-E bus
+	 connecting 2 systems.  When configured, writes to the device's PCI
+	 mapped memory will be mirrored to a buffer on the remote system.  The
+	 ntb Linux driver uses this point-to-point communication as a method to
+	 transfer data from one system to the other.
 
+	 If unsure, say N.
+
+if NTB
+
+source "drivers/ntb/hw/Kconfig"
+
+config NTB_TRANSPORT
+	tristate "NTB Transport Client"
+	help
+	 This is a transport driver that enables connected systems to exchange
+	 messages over the ntb hardware.  The transport exposes a queue pair api
+	 to client drivers.
+
+	 If unsure, say N.
+
+endif # NTB
drivers/ntb/Makefile +2 -4
index 712e953a8fda..b9fa663ecfec 100644
@@ -1,4 +1,2 @@
-obj-$(CONFIG_NTB) += ntb.o
-obj-$(CONFIG_NTB) += ntb_hw_intel.o
-
-ntb_hw_intel-objs := hw/intel/ntb_hw_intel.o ntb_transport.o
+obj-$(CONFIG_NTB) += ntb.o hw/
+obj-$(CONFIG_NTB_TRANSPORT) += ntb_transport.o
drivers/ntb/hw/Kconfig new file +1 -0
new file mode 100644
index 000000000000..4d5535c4cddf
@@ -0,0 +1 @@
+source "drivers/ntb/hw/intel/Kconfig"
drivers/ntb/hw/Makefile new file +1 -0
new file mode 100644
index 000000000000..175d7c92a569
@@ -0,0 +1 @@
+obj-$(CONFIG_NTB_INTEL)	+= intel/
drivers/ntb/hw/intel/Kconfig new file +7 -0
new file mode 100644
index 000000000000..1955ca26d212
@@ -0,0 +1,7 @@
+config NTB_INTEL
+	tristate "Intel Non-Transparent Bridge support"
+	depends on X86
+	help
+	 This driver supports Intel NTB on capable Xeon and Atom hardware.
+
+	 If unsure, say N.
drivers/ntb/hw/intel/Makefile new file +1 -0
new file mode 100644
index 000000000000..1b434568d2ad
@@ -0,0 +1 @@
+obj-$(CONFIG_NTB_INTEL) += ntb_hw_intel.o
drivers/ntb/hw/intel/ntb_hw_intel.c +1651 -1426

2,745 lines not on this page · raw message

drivers/ntb/hw/intel/ntb_hw_intel.h +282 -325

607 lines not on this page · raw message

drivers/ntb/ntb_transport.c +551 -393

944 lines not on this page · raw message

include/linux/ntb_transport.h +11 -14
index 9ac1a62fc6f5..2862861366a5 100644

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Signature · 1 line
2.4.0.rc0.43.gcf8a8c6

Part of the diff is not shown here. View the raw message.

#4 lore raw

PATCH v4 4/19 NTB: Read peer info from local SPAD in transport

In reply to Allen Hubbe

From: Dave Jiang <[email protected]>

The transport was writing and then reading the peer scratch pad, essentially reading what it just wrote instead of exchanging any information with the peer. The transport expects the peer values to be the same as the local values, so this issue was not obvious.

---
 drivers/ntb/ntb_transport.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/ntb/ntb_transport.c +5 -5
index 9faf1c6029af..d9538e911df6 100644
@@ -761,17 +761,17 @@ static void ntb_transport_link_work(struct work_struct *work)
 	ntb_peer_spad_write(ndev, VERSION, NTB_TRANSPORT_VERSION);
 
 	/* Query the remote side for its info */
-	val = ntb_peer_spad_read(ndev, VERSION);
+	val = ntb_spad_read(ndev, VERSION);
 	dev_dbg(&pdev->dev, "Remote version = %d\n", val);
 	if (val != NTB_TRANSPORT_VERSION)
 		goto out;
 
-	val = ntb_peer_spad_read(ndev, NUM_QPS);
+	val = ntb_spad_read(ndev, NUM_QPS);
 	dev_dbg(&pdev->dev, "Remote max number of qps = %d\n", val);
 	if (val != nt->qp_count)
 		goto out;
 
-	val = ntb_peer_spad_read(ndev, NUM_MWS);
+	val = ntb_spad_read(ndev, NUM_MWS);
 	dev_dbg(&pdev->dev, "Remote number of mws = %d\n", val);
 	if (val != nt->mw_count)
 		goto out;
@@ -779,10 +779,10 @@ static void ntb_transport_link_work(struct work_struct *work)
 	for (i = 0; i < nt->mw_count; i++) {
 		u64 val64;
 
-		val = ntb_peer_spad_read(ndev, MW0_SZ_HIGH + (i * 2));
+		val = ntb_spad_read(ndev, MW0_SZ_HIGH + (i * 2));
 		val64 = (u64)val << 32;
 
-		val = ntb_peer_spad_read(ndev, MW0_SZ_LOW + (i * 2));
+		val = ntb_spad_read(ndev, MW0_SZ_LOW + (i * 2));
 		val64 |= val;
 
 		dev_dbg(&pdev->dev, "Remote MW%d size = %#llx\n", i, val64);
Signature · 1 line
2.4.0.rc0.43.gcf8a8c6
#5 lore raw

PATCH v4 5/19 NTB: Enable link for Intel root port mode in probe

In reply to Allen Hubbe

From: Dave Jiang <[email protected]>

Link training should be enabled in the driver probe for root port mode. We should not have to wait for transport to be loaded for this to happen. Otherwise the ntb device will not show up on the transparent bridge side of the link.

---
 drivers/ntb/hw/intel/ntb_hw_intel.c | 10 ++++++++++
 1 file changed, 10 insertions(+)
drivers/ntb/hw/intel/ntb_hw_intel.c +10 -0
index e4a22d7963fa..8ad4a6343d96 100644
@@ -1318,6 +1318,9 @@ static int snb_poll_link(struct intel_ntb_dev *ndev)
 
 static int snb_link_is_up(struct intel_ntb_dev *ndev)
 {
+	if (ndev->ntb.topo == NTB_TOPO_SEC)
+		return 1;
+
 	return NTB_LNK_STA_ACTIVE(ndev->lnk_sta);
 }
 
@@ -1614,6 +1617,7 @@ static int snb_setup_b2b_mw(struct intel_ntb_dev *ndev,
 static int snb_init_ntb(struct intel_ntb_dev *ndev)
 {
 	int rc;
+	u32 ntb_ctl;
 
 	if (ndev->bar4_split)
 		ndev->mw_count = HSX_SPLIT_BAR_MW_COUNT;
@@ -1630,6 +1634,12 @@ static int snb_init_ntb(struct intel_ntb_dev *ndev)
 			dev_err(ndev_dev(ndev), "NTB Primary config disabled\n");
 			return -EINVAL;
 		}
+
+		/* enable link to allow secondary side device to appear */
+		ntb_ctl = ioread32(ndev->self_mmio + ndev->reg->ntb_ctl);
+		ntb_ctl &= ~NTB_CTL_DISABLE;
+		iowrite32(ntb_ctl, ndev->self_mmio + ndev->reg->ntb_ctl);
+
 		/* use half the spads for the peer */
 		ndev->spad_count >>= 1;
 		ndev->self_reg = &snb_pri_reg;
Signature · 1 line
2.4.0.rc0.43.gcf8a8c6
#6 lore raw

PATCH v4 6/19 NTB: Check the device ID to set errata flags

In reply to Allen Hubbe

From: Dave Jiang <[email protected]>

Set errata flags for the specific device IDs to which they apply, instead of the whole Xeon hardware class.

---
 drivers/ntb/hw/intel/ntb_hw_intel.c | 49 +++++++++++++++++++++++++++++++++----
 1 file changed, 44 insertions(+), 5 deletions(-)
drivers/ntb/hw/intel/ntb_hw_intel.c +44 -5
index 8ad4a6343d96..ff397fae9cf4 100644
@@ -1719,29 +1719,68 @@ static int snb_init_dev(struct intel_ntb_dev *ndev)
 	u8 ppd;
 	int rc, mem;
 
+	pdev = ndev_pdev(ndev);
+
+	switch (pdev->device) {
 	/* There is a Xeon hardware errata related to writes to SDOORBELL or
 	 * B2BDOORBELL in conjunction with inbound access to NTB MMIO Space,
 	 * which may hang the system.  To workaround this use the second memory
 	 * window to access the interrupt and scratch pad registers on the
 	 * remote system.
 	 */
-	ndev->hwerr_flags |= NTB_HWERR_SDOORBELL_LOCKUP;
+	case PCI_DEVICE_ID_INTEL_NTB_SS_JSF:
+	case PCI_DEVICE_ID_INTEL_NTB_PS_JSF:
+	case PCI_DEVICE_ID_INTEL_NTB_B2B_JSF:
+	case PCI_DEVICE_ID_INTEL_NTB_SS_SNB:
+	case PCI_DEVICE_ID_INTEL_NTB_PS_SNB:
+	case PCI_DEVICE_ID_INTEL_NTB_B2B_SNB:
+	case PCI_DEVICE_ID_INTEL_NTB_SS_IVT:
+	case PCI_DEVICE_ID_INTEL_NTB_PS_IVT:
+	case PCI_DEVICE_ID_INTEL_NTB_B2B_IVT:
+	case PCI_DEVICE_ID_INTEL_NTB_SS_HSX:
+	case PCI_DEVICE_ID_INTEL_NTB_PS_HSX:
+	case PCI_DEVICE_ID_INTEL_NTB_B2B_HSX:
+		ndev->hwerr_flags |= NTB_HWERR_SDOORBELL_LOCKUP;
+		break;
+	}
 
+	switch (pdev->device) {
 	/* There is a hardware errata related to accessing any register in
 	 * SB01BASE in the presence of bidirectional traffic crossing the NTB.
 	 */
-	ndev->hwerr_flags |= NTB_HWERR_SB01BASE_LOCKUP;
+	case PCI_DEVICE_ID_INTEL_NTB_SS_IVT:
+	case PCI_DEVICE_ID_INTEL_NTB_PS_IVT:
+	case PCI_DEVICE_ID_INTEL_NTB_B2B_IVT:
+	case PCI_DEVICE_ID_INTEL_NTB_SS_HSX:
+	case PCI_DEVICE_ID_INTEL_NTB_PS_HSX:
+	case PCI_DEVICE_ID_INTEL_NTB_B2B_HSX:
+		ndev->hwerr_flags |= NTB_HWERR_SB01BASE_LOCKUP;
+		break;
+	}
 
+	switch (pdev->device) {
 	/* HW Errata on bit 14 of b2bdoorbell register.  Writes will not be
 	 * mirrored to the remote system.  Shrink the number of bits by one,
 	 * since bit 14 is the last bit.
 	 */
-	ndev->hwerr_flags |= NTB_HWERR_B2BDOORBELL_BIT14;
+	case PCI_DEVICE_ID_INTEL_NTB_SS_JSF:
+	case PCI_DEVICE_ID_INTEL_NTB_PS_JSF:
+	case PCI_DEVICE_ID_INTEL_NTB_B2B_JSF:
+	case PCI_DEVICE_ID_INTEL_NTB_SS_SNB:
+	case PCI_DEVICE_ID_INTEL_NTB_PS_SNB:
+	case PCI_DEVICE_ID_INTEL_NTB_B2B_SNB:
+	case PCI_DEVICE_ID_INTEL_NTB_SS_IVT:
+	case PCI_DEVICE_ID_INTEL_NTB_PS_IVT:
+	case PCI_DEVICE_ID_INTEL_NTB_B2B_IVT:
+	case PCI_DEVICE_ID_INTEL_NTB_SS_HSX:
+	case PCI_DEVICE_ID_INTEL_NTB_PS_HSX:
+	case PCI_DEVICE_ID_INTEL_NTB_B2B_HSX:
+		ndev->hwerr_flags |= NTB_HWERR_B2BDOORBELL_BIT14;
+		break;
+	}
 
 	ndev->reg = &snb_reg;
 
-	pdev = ndev_pdev(ndev);
-
 	rc = pci_read_config_byte(pdev, SNB_PPD_OFFSET, &ppd);
 	if (rc)
 		return -EIO;
Signature · 1 line
2.4.0.rc0.43.gcf8a8c6
#7 lore raw

PATCH v4 7/19 NTB: Differentiate transport link down messages

In reply to Allen Hubbe

The same message "qp %d: Link Down\n" was printed at two locations in ntb_transport. Change the messages so they are distinct.

---
 drivers/ntb/ntb_transport.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/ntb/ntb_transport.c +2 -2
index d9538e911df6..8d9b59f7fa07 100644
@@ -658,7 +658,7 @@ static void ntb_qp_link_cleanup(struct ntb_transport_qp *qp)
 		return;
 	}
 
-	dev_info(&pdev->dev, "qp %d: Link Down\n", qp->qp_num);
+	dev_info(&pdev->dev, "qp %d: Link Cleanup\n", qp->qp_num);
 	qp->link_is_up = false;
 
 	if (qp->event_handler)
@@ -1470,7 +1470,7 @@ static void ntb_send_link_down(struct ntb_transport_qp *qp)
 		return;
 
 	qp->link_is_up = false;
-	dev_info(&pdev->dev, "qp %d: Link Down\n", qp->qp_num);
+	dev_info(&pdev->dev, "qp %d: Send Link Down\n", qp->qp_num);
 
 	for (i = 0; i < NTB_LINK_DOWN_TIMEOUT; i++) {
 		entry = ntb_list_rm(&qp->ntb_tx_free_q_lock, &qp->tx_free_q);
Signature · 1 line
2.4.0.rc0.43.gcf8a8c6
#8 lore raw

PATCH v4 8/19 NTB: Do not advance transport RX on link down

In reply to Allen Hubbe

On link down, don't advance RX index to the next entry. The next entry should never be valid after receiving the link down flag.

---
 drivers/ntb/ntb_transport.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/ntb/ntb_transport.c +1 -2
index 8d9b59f7fa07..0f86b60a0c0e 100644
@@ -1212,8 +1212,7 @@ static int ntb_process_rxc(struct ntb_transport_qp *qp)
 		dev_dbg(&qp->ndev->pdev->dev, "link down flag set\n");
 		ntb_qp_link_down(qp);
 		hdr->flags = 0;
-		iowrite32(qp->rx_index, &qp->rx_info->entry);
-		return 0;
+		return -EAGAIN;
 	}
 
 	if (hdr->ver != (u32)qp->rx_pkts) {
Signature · 1 line
2.4.0.rc0.43.gcf8a8c6
#9 lore raw

PATCH v4 9/19 NTB: Reset transport QP link stats on down

In reply to Allen Hubbe

Reset the link stats when the link goes down. In particular, the TX and RX index and count must be reset, or else the TX side will be sending packets to the RX side where the RX side is not expecting them. Reset all the stats, to be consistent.

---
 drivers/ntb/ntb_transport.c | 36 ++++++++++++++++++++++++++++--------
 1 file changed, 28 insertions(+), 8 deletions(-)
drivers/ntb/ntb_transport.c +28 -8
index 0f86b60a0c0e..2efd1eae9a7c 100644
@@ -648,18 +648,37 @@ static int ntb_set_mw(struct ntb_transport_ctx *nt, int num_mw,
 	return 0;
 }
 
+static void ntb_qp_link_down_reset(struct ntb_transport_qp *qp)
+{
+	qp->link_is_up = false;
+
+	qp->tx_index = 0;
+	qp->rx_index = 0;
+	qp->rx_bytes = 0;
+	qp->rx_pkts = 0;
+	qp->rx_ring_empty = 0;
+	qp->rx_err_no_buf = 0;
+	qp->rx_err_oflow = 0;
+	qp->rx_err_ver = 0;
+	qp->rx_memcpy = 0;
+	qp->rx_async = 0;
+	qp->tx_bytes = 0;
+	qp->tx_pkts = 0;
+	qp->tx_ring_full = 0;
+	qp->tx_err_no_buf = 0;
+	qp->tx_memcpy = 0;
+	qp->tx_async = 0;
+}
+
 static void ntb_qp_link_cleanup(struct ntb_transport_qp *qp)
 {
 	struct ntb_transport_ctx *nt = qp->transport;
 	struct pci_dev *pdev = nt->ndev->pdev;
 
-	if (qp->link_is_up) {
-		cancel_delayed_work_sync(&qp->link_work);
-		return;
-	}
-
 	dev_info(&pdev->dev, "qp %d: Link Cleanup\n", qp->qp_num);
-	qp->link_is_up = false;
+
+	cancel_delayed_work_sync(&qp->link_work);
+	ntb_qp_link_down_reset(qp);
 
 	if (qp->event_handler)
 		qp->event_handler(qp->cb_data, qp->link_is_up);
@@ -866,9 +885,9 @@ static int ntb_transport_init_queue(struct ntb_transport_ctx *nt,
 	qp->qp_num = qp_num;
 	qp->transport = nt;
 	qp->ndev = nt->ndev;
-	qp->link_is_up = false;
 	qp->client_ready = false;
 	qp->event_handler = NULL;
+	ntb_qp_link_down_reset(qp);
 
 	if (qp_count % mw_count && mw_num + 1 < qp_count / mw_count)
 		num_qps_mw = qp_count / mw_count + 1;
@@ -1468,7 +1487,6 @@ static void ntb_send_link_down(struct ntb_transport_qp *qp)
 	if (!qp->link_is_up)
 		return;
 
-	qp->link_is_up = false;
 	dev_info(&pdev->dev, "qp %d: Send Link Down\n", qp->qp_num);
 
 	for (i = 0; i < NTB_LINK_DOWN_TIMEOUT; i++) {
@@ -1490,6 +1508,8 @@ static void ntb_send_link_down(struct ntb_transport_qp *qp)
 	if (rc)
 		dev_err(&pdev->dev, "ntb: QP%d unable to send linkdown msg\n",
 			qp->qp_num);
+
+	ntb_qp_link_down_reset(qp);
 }
 
 /**
Signature · 1 line
2.4.0.rc0.43.gcf8a8c6
#10 lore raw

PATCH v4 10/19 NTB: Add parameters for Intel SNB B2B addresses

In reply to Allen Hubbe

Add module parameters for the addresses to be used in B2B topology.

---
 Documentation/ntb.txt               | 10 +++++
 drivers/ntb/hw/intel/ntb_hw_intel.c | 77 ++++++++++++++++++++++++++++---------
 2 files changed, 68 insertions(+), 19 deletions(-)
Documentation/ntb.txt +10 -0
index 725ba1e6c127..00a3f92832a5 100644
@@ -56,3 +56,13 @@ Module Parameters:
 * b2b\_mw\_share - If the peer ntb is to be accessed via a memory window, and if
 	the memory window is large enough, still allow the client to use the
 	second half of the memory window for address translation to the peer.
+* snb\_b2b\_usd\_bar2\_addr64 - If using B2B topology on Xeon hardware, use this
+	64 bit address on the bus between the NTB devices for the window at
+	BAR2, on the upstream side of the link.
+* snb\_b2b\_usd\_bar4\_addr64 - See *snb\_b2b\_bar2\_addr64*.
+* snb\_b2b\_usd\_bar4\_addr32 - See *snb\_b2b\_bar2\_addr64*.
+* snb\_b2b\_usd\_bar5\_addr32 - See *snb\_b2b\_bar2\_addr64*.
+* snb\_b2b\_dsd\_bar2\_addr64 - See *snb\_b2b\_bar2\_addr64*.
+* snb\_b2b\_dsd\_bar4\_addr64 - See *snb\_b2b\_bar2\_addr64*.
+* snb\_b2b\_dsd\_bar4\_addr32 - See *snb\_b2b\_bar2\_addr64*.
+* snb\_b2b\_dsd\_bar5\_addr32 - See *snb\_b2b\_bar2\_addr64*.
drivers/ntb/hw/intel/ntb_hw_intel.c +58 -19

106 lines not on this page · raw message

Signature · 1 line
2.4.0.rc0.43.gcf8a8c6
#11 lore raw

PATCH v4 11/19 NTB: Add ping pong test client

In reply to Allen Hubbe

This is a simple ping pong driver that exercises the scratch pads and doorbells of the ntb hardware. This driver may be used to test that your ntb hardware and drivers are functioning at a basic level.

---
 Documentation/ntb.txt           |  27 +++++
 MAINTAINERS                     |   1 +
 drivers/ntb/Kconfig             |   2 +
 drivers/ntb/Makefile            |   2 +-
 drivers/ntb/test/Kconfig        |   8 ++
 drivers/ntb/test/Makefile       |   1 +
 drivers/ntb/test/ntb_pingpong.c | 250 ++++++++++++++++++++++++++++++++++++++++
 7 files changed, 290 insertions(+), 1 deletion(-)
 create mode 100644 drivers/ntb/test/Kconfig
 create mode 100644 drivers/ntb/test/Makefile
 create mode 100644 drivers/ntb/test/ntb_pingpong.c
Documentation/ntb.txt +27 -0
index 00a3f92832a5..e5d1591478ca 100644
@@ -37,6 +37,33 @@ Transport queue pair.  Network data is copied between socket buffers and the
 Transport queue pair buffer.  The Transport client may be used for other things
 besides Netdev, however no other applications have yet been written.
 
+### NTB Ping Pong Test Client (ntb\_pingpong)
+
+The Ping Pong test client serves as a demonstration to exercise the doorbell
+and scratchpad registers of NTB hardware, and as an example simple NTB client.
+Ping Pong enables the link when started, waits for the NTB link to come up, and
+then proceeds to read and write the doorbell scratchpad registers of the NTB.
+The peers interrupt each other using a bit mask of doorbell bits, which is
+shifted by one in each round, to test the behavior of multiple doorbell bits
+and interrupt vectors.  The Ping Pong driver also reads the first local
+scratchpad, and writes the value plus one to the first peer scratchpad, each
+round before writing the peer doorbell register.
+
+Module Parameters:
+
+* unsafe - Some hardware has known issues with scratchpad and doorbell
+	registers.  By default, Ping Pong will not attempt to exercise such
+	hardware.  You may override this behavior at your own risk by setting
+	unsafe=1.
+* delay\_ms - Specify the delay between receiving a doorbell
+	interrupt event and setting the peer doorbell register for the next
+	round.
+* init\_db - Specify the doorbell bits to start new series of rounds.  A new
+	series begins once all the doorbell bits have been shifted out of
+	range.
+* dyndbg - It is suggested to specify dyndbg=+p when loading this module, and
+	then to observe debugging output on the console.
+
 ## NTB Hardware Drivers
 
 NTB hardware drivers should register devices with the NTB core driver.  After
MAINTAINERS +1 -0
index 1a09fd12b6d2..69dad8e01d80 100644
@@ -6987,6 +6987,7 @@ T:	git git://github.com/jonmason/ntb.git
 F:	drivers/ntb/
 F:	drivers/net/ntb_netdev.c
 F:	drivers/ntb/ntb.c
+F:	drivers/ntb/ntb_pingpong.c
 F:	drivers/ntb/ntb_transport.c
 F:	include/linux/ntb.h
 F:	include/linux/ntb_transport.h
drivers/ntb/Kconfig +2 -0
index 53b042429673..95944e52fa36 100644
@@ -14,6 +14,8 @@ if NTB
 
 source "drivers/ntb/hw/Kconfig"
 
+source "drivers/ntb/test/Kconfig"
+
 config NTB_TRANSPORT
 	tristate "NTB Transport Client"
 	help
drivers/ntb/Makefile +1 -1
index b9fa663ecfec..1921dec1949d 100644
@@ -1,2 +1,2 @@
-obj-$(CONFIG_NTB) += ntb.o hw/
+obj-$(CONFIG_NTB) += ntb.o hw/ test/
 obj-$(CONFIG_NTB_TRANSPORT) += ntb_transport.o
drivers/ntb/test/Kconfig new file +8 -0
new file mode 100644
index 000000000000..72d255d220c8
@@ -0,0 +1,8 @@
+config NTB_PINGPONG
+	tristate "NTB Ping Pong Test Client"
+	help
+	 This is a simple ping pong driver that exercises the scratchpads and
+	 doorbells of the ntb hardware.  This driver may be used to test that
+	 your ntb hardware and drivers are functioning at a basic level.
+
+	 If unsure, say N.
drivers/ntb/test/Makefile new file +1 -0
new file mode 100644
index 000000000000..b32309307771
@@ -0,0 +1 @@
+obj-$(CONFIG_NTB_PINGPONG) += ntb_pingpong.o
drivers/ntb/test/ntb_pingpong.c new file +250 -0

250 lines not on this page · raw message

Signature · 1 line
2.4.0.rc0.43.gcf8a8c6
#12 lore raw

PATCH v4 12/19 NTB: Add tool test client

In reply to Allen Hubbe

This is a simple debugging driver that enables the doorbell and scratch pad registers to be read and written from the debugfs. This tool enables more complicated debugging to be scripted from user space. This driver may be used to test that your ntb hardware and drivers are functioning at a basic level.

---
 Documentation/ntb.txt       |  32 +++
 MAINTAINERS                 |   1 +
 drivers/ntb/test/Kconfig    |  11 +
 drivers/ntb/test/Makefile   |   1 +
 drivers/ntb/test/ntb_tool.c | 556 ++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 601 insertions(+)
 create mode 100644 drivers/ntb/test/ntb_tool.c
Documentation/ntb.txt +32 -0
index e5d1591478ca..b48249a7b607 100644
@@ -64,6 +64,38 @@ Module Parameters:
 * dyndbg - It is suggested to specify dyndbg=+p when loading this module, and
 	then to observe debugging output on the console.
 
+### NTB Tool Test Client (ntb\_tool)
+
+The Tool test client serves for debugging, primarily, ntb hardware and drivers.
+The Tool provides access through debugfs for reading, setting, and clearing the
+NTB doorbell, and reading and writing scratchpads.
+
+The Tool does not currently have any module parameters.
+
+Debugfs Files:
+
+* *debugfs*/ntb\_tool/*hw*/ - A directory in debugfs will be created for each
+	NTB device probed by the tool.  This directory is shortened to *hw*
+	below.
+* *hw*/db - This file is used to read, set, and clear the local doorbell.  Not
+	all operations may be supported by all hardware.  To read the doorbell,
+	read the file.  To set the doorbell, write `s` followed by the bits to
+	set (eg: `echo 's 0x0101' > db`).  To clear the doorbell, write `c`
+	followed by the bits to clear.
+* *hw*/mask - This file is used to read, set, and clear the local doorbell mask.
+	See *db* for details.
+* *hw*/peer\_db - This file is used to read, set, and clear the peer doorbell.
+	See *db* for details.
+* *hw*/peer\_mask - This file is used to read, set, and clear the peer doorbell
+	mask.  See *db* for details.
+* *hw*/spad - This file is used to read and write local scratchpads.  To read
+	the values of all scratchpads, read the file.  To write values, write a
+	series of pairs of scratchpad number and value
+	(eg: `echo '4 0x123 7 0xabc' > spad`
+	# to set scratchpads `4` and `7` to `0x123` and `0xabc`, respectively).
+* *hw*/peer\_spad - This file is used to read and write peer scratchpads.  See
+	*spad* for details.
+
 ## NTB Hardware Drivers
 
 NTB hardware drivers should register devices with the NTB core driver.  After
MAINTAINERS +1 -0
index 69dad8e01d80..ec19f09f6c0c 100644
@@ -6988,6 +6988,7 @@ F:	drivers/ntb/
 F:	drivers/net/ntb_netdev.c
 F:	drivers/ntb/ntb.c
 F:	drivers/ntb/ntb_pingpong.c
+F:	drivers/ntb/ntb_tool.c
 F:	drivers/ntb/ntb_transport.c
 F:	include/linux/ntb.h
 F:	include/linux/ntb_transport.h
drivers/ntb/test/Kconfig +11 -0
index 72d255d220c8..01852f98a843 100644
@@ -6,3 +6,14 @@ config NTB_PINGPONG
 	 your ntb hardware and drivers are functioning at a basic level.
 
 	 If unsure, say N.
+
+config NTB_TOOL
+	tristate "NTB Debugging Tool Test Client"
+	help
+	 This is a simple debugging driver that enables the doorbell and
+	 scratchpad registers to be read and written from the debugfs.  This
+	 enables more complicated debugging to be scripted from user space.
+	 This driver may be used to test that your ntb hardware and drivers are
+	 functioning at a basic level.
+
+	 If unsure, say N.
drivers/ntb/test/Makefile +1 -0
index b32309307771..0ea32a324b6c 100644
@@ -1 +1,2 @@
 obj-$(CONFIG_NTB_PINGPONG) += ntb_pingpong.o
+obj-$(CONFIG_NTB_TOOL) += ntb_tool.o
drivers/ntb/test/ntb_tool.c new file +556 -0

556 lines not on this page · raw message

Signature · 1 line
2.4.0.rc0.43.gcf8a8c6
#13 lore raw

PATCH v4 13/19 NTB: Rate limit ntb_qp_link_work

In reply to Allen Hubbe

When the ntb transport is connecting and waiting for the peer, the debug console receives lots of debug level messages about the remote qp link status being down. Rate limit those messages.

---
 drivers/ntb/ntb_transport.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/ntb/ntb_transport.c +1 -1
index 2efd1eae9a7c..8ce0bf67ac20 100644
@@ -850,7 +850,7 @@ static void ntb_qp_link_work(struct work_struct *work)
 
 	/* query remote spad for qp ready bits */
 	ntb_peer_spad_read(nt->ndev, QP_LINKS);
-	dev_dbg(&pdev->dev, "Remote QP link status = %x\n", val);
+	dev_dbg_ratelimited(&pdev->dev, "Remote QP link status = %x\n", val);
 
 	/* See if the remote side is up */
 	if (val & BIT(qp->qp_num)) {
Signature · 1 line
2.4.0.rc0.43.gcf8a8c6
#14 lore raw

PATCH v4 14/19 NTB: Use NUMA memory and DMA chan in transport

In reply to Allen Hubbe

Allocate memory and request the DMA channel for the same NUMA node as the NTB device.

---
 drivers/ntb/ntb_transport.c | 46 +++++++++++++++++++++++++++++++--------------
 1 file changed, 32 insertions(+), 14 deletions(-)
drivers/ntb/ntb_transport.c +32 -14
index 8ce0bf67ac20..dc14ec81c43e 100644
@@ -346,6 +346,7 @@ int ntb_transport_register_client_dev(char *device_name)
 {
 	struct ntb_transport_client_dev *client_dev;
 	struct ntb_transport_ctx *nt;
+	int node;
 	int rc, i = 0;
 
 	if (list_empty(&ntb_transport_list))
@@ -354,8 +355,10 @@ int ntb_transport_register_client_dev(char *device_name)
 	list_for_each_entry(nt, &ntb_transport_list, entry) {
 		struct device *dev;
 
-		client_dev = kzalloc(sizeof(*client_dev),
-				     GFP_KERNEL);
+		node = dev_to_node(&nt->ndev->dev);
+
+		client_dev = kzalloc_node(sizeof(*client_dev),
+					  GFP_KERNEL, node);
 		if (!client_dev) {
 			rc = -ENOMEM;
 			goto err;
@@ -953,6 +956,7 @@ static int ntb_transport_probe(struct ntb_client *self, struct ntb_dev *ndev)
 	struct ntb_transport_mw *mw;
 	unsigned int mw_count, qp_count;
 	u64 qp_bitmap;
+	int node;
 	int rc, i;
 
 	if (ntb_db_is_unsafe(ndev))
@@ -962,7 +966,9 @@ static int ntb_transport_probe(struct ntb_client *self, struct ntb_dev *ndev)
 		dev_dbg(&ndev->dev,
 			"scratchpad is unsafe, proceed anyway...\n");
 
-	nt = kzalloc(sizeof(*nt), GFP_KERNEL);
+	node = dev_to_node(&ndev->dev);
+
+	nt = kzalloc_node(sizeof(*nt), GFP_KERNEL, node);
 	if (!nt)
 		return -ENOMEM;
 
@@ -972,7 +978,8 @@ static int ntb_transport_probe(struct ntb_client *self, struct ntb_dev *ndev)
 
 	nt->mw_count = mw_count;
 
-	nt->mw_vec = kcalloc(mw_count, sizeof(*nt->mw_vec), GFP_KERNEL);
+	nt->mw_vec = kzalloc_node(mw_count * sizeof(*nt->mw_vec),
+				  GFP_KERNEL, node);
 	if (!nt->mw_vec) {
 		rc = -ENOMEM;
 		goto err;
@@ -1012,7 +1019,8 @@ static int ntb_transport_probe(struct ntb_client *self, struct ntb_dev *ndev)
 	nt->qp_bitmap = qp_bitmap;
 	nt->qp_bitmap_free = qp_bitmap;
 
-	nt->qp_vec = kcalloc(qp_count, sizeof(*nt->qp_vec), GFP_KERNEL);
+	nt->qp_vec = kzalloc_node(qp_count * sizeof(*nt->qp_vec),
+				  GFP_KERNEL, node);
 	if (!nt->qp_vec) {
 		rc = -ENOMEM;
 		goto err2;
@@ -1512,6 +1520,11 @@ static void ntb_send_link_down(struct ntb_transport_qp *qp)
 	ntb_qp_link_down_reset(qp);
 }
 
+static bool ntb_dma_filter_fn(struct dma_chan *chan, void *node)
+{
+	return dev_to_node(&chan->dev->device) == (int)(unsigned long)node;
+}
+
 /**
  * ntb_transport_create_queue - Create a new NTB transport layer queue
  * @rx_handler: receive callback function
@@ -1537,12 +1550,16 @@ ntb_transport_create_queue(void *data, struct device *client_dev,
 	struct ntb_transport_qp *qp;
 	u64 qp_bit;
 	unsigned int free_queue;
+	dma_cap_mask_t dma_mask;
+	int node;
 	int i;
 
 	ndev = dev_ntb(client_dev->parent);
 	pdev = ndev->pdev;
 	nt = ndev->ctx;
 
+	node = dev_to_node(&ndev->dev);
+
 	free_queue = ffs(nt->qp_bitmap);
 	if (!free_queue)
 		goto err;
@@ -1560,15 +1577,16 @@ ntb_transport_create_queue(void *data, struct device *client_dev,
 	qp->tx_handler = handlers->tx_handler;
 	qp->event_handler = handlers->event_handler;
 
-	dmaengine_get();
-	qp->dma_chan = dma_find_channel(DMA_MEMCPY);
-	if (!qp->dma_chan) {
-		dmaengine_put();
+	dma_cap_zero(dma_mask);
+	dma_cap_set(DMA_MEMCPY, dma_mask);
+
+	qp->dma_chan = dma_request_channel(dma_mask, ntb_dma_filter_fn,
+					   (void *)(unsigned long)node);
+	if (!qp->dma_chan)
 		dev_info(&pdev->dev, "Unable to allocate DMA channel, using CPU instead\n");
-	}
 
 	for (i = 0; i < NTB_QP_DEF_NUM_ENTRIES; i++) {
-		entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
+		entry = kzalloc_node(sizeof(*entry), GFP_ATOMIC, node);
 		if (!entry)
 			goto err1;
 
@@ -1578,7 +1596,7 @@ ntb_transport_create_queue(void *data, struct device *client_dev,
 	}
 
 	for (i = 0; i < NTB_QP_DEF_NUM_ENTRIES; i++) {
-		entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
+		entry = kzalloc_node(sizeof(*entry), GFP_ATOMIC, node);
 		if (!entry)
 			goto err2;
 
@@ -1601,7 +1619,7 @@ err1:
 	while ((entry = ntb_list_rm(&qp->ntb_rx_free_q_lock, &qp->rx_free_q)))
 		kfree(entry);
 	if (qp->dma_chan)
-		dmaengine_put();
+		dma_release_channel(qp->dma_chan);
 	nt->qp_bitmap_free |= qp_bit;
 err:
 	return NULL;
@@ -1638,7 +1656,7 @@ void ntb_transport_free_queue(struct ntb_transport_qp *qp)
 		 */
 		dma_sync_wait(chan, qp->last_cookie);
 		dmaengine_terminate_all(chan);
-		dmaengine_put();
+		dma_release_channel(chan);
 	}
 
 	qp_bit = BIT_ULL(qp->qp_num);
Signature · 1 line
2.4.0.rc0.43.gcf8a8c6
#15 lore raw

PATCH v4 15/19 NTB: Use NUMA memory in Intel driver

In reply to Allen Hubbe

Allocate memory for the NUMA node of the NTB device.

---
 drivers/ntb/hw/intel/ntb_hw_intel.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)
drivers/ntb/hw/intel/ntb_hw_intel.c +12 -6
index 3448d5fbd003..4ac0b77ec788 100644
@@ -413,10 +413,12 @@ static int ndev_init_isr(struct intel_ntb_dev *ndev,
 			 int msix_shift, int total_shift)
 {
 	struct pci_dev *pdev;
-	int rc, i, msix_count;
+	int rc, i, msix_count, node;
 
 	pdev = ndev_pdev(ndev);
 
+	node = dev_to_node(&pdev->dev);
+
 	/* Mask all doorbell interrupts */
 	ndev->db_mask = ndev->db_valid_mask;
 	ndev->reg->db_iowrite(ndev->db_mask,
@@ -425,11 +427,13 @@ static int ndev_init_isr(struct intel_ntb_dev *ndev,
 
 	/* Try to set up msix irq */
 
-	ndev->vec = kcalloc(msix_max, sizeof(*ndev->vec), GFP_KERNEL);
+	ndev->vec = kzalloc_node(msix_max * sizeof(*ndev->vec),
+				 GFP_KERNEL, node);
 	if (!ndev->vec)
 		goto err_msix_vec_alloc;
 
-	ndev->msix = kcalloc(msix_max, sizeof(*ndev->msix), GFP_KERNEL);
+	ndev->msix = kzalloc_node(msix_max * sizeof(*ndev->msix),
+				  GFP_KERNEL, node);
 	if (!ndev->msix)
 		goto err_msix_alloc;
 
@@ -1960,10 +1964,12 @@ static int intel_ntb_pci_probe(struct pci_dev *pdev,
 			       const struct pci_device_id *id)
 {
 	struct intel_ntb_dev *ndev;
-	int rc;
+	int rc, node;
+
+	node = dev_to_node(&pdev->dev);
 
 	if (pdev_is_bwd(pdev)) {
-		ndev = kzalloc(sizeof(*ndev), GFP_KERNEL);
+		ndev = kzalloc_node(sizeof(*ndev), GFP_KERNEL, node);
 		if (!ndev) {
 			rc = -ENOMEM;
 			goto err_ndev;
@@ -1980,7 +1986,7 @@ static int intel_ntb_pci_probe(struct pci_dev *pdev,
 			goto err_init_dev;
 
 	} else if (pdev_is_snb(pdev)) {
-		ndev = kzalloc(sizeof(*ndev), GFP_KERNEL);
+		ndev = kzalloc_node(sizeof(*ndev), GFP_KERNEL, node);
 		if (!ndev) {
 			rc = -ENOMEM;
 			goto err_ndev;
Signature · 1 line
2.4.0.rc0.43.gcf8a8c6
#16 lore raw

PATCH v4 16/19 NTB: Improve performance with write combining

In reply to Allen Hubbe

From: Dave Jiang <[email protected]>

Changing the memory window BAR mappings to write combining significantly boosts the performance. We will also use memcpy that uses non-temporal store, which showed performance improvement when doing non-cached memcpys.

---

Added #ifdef ARCH_HAS_NOCACHE_UACCESS around
__copy_from_user_inatomic_nocache.

Following the example set by here:
https://lists.01.org/pipermail/linux-nvdimm/2015-June/001087.html

 drivers/ntb/ntb_transport.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)
drivers/ntb/ntb_transport.c +10 -1
index dc14ec81c43e..7a765d3230d8 100644
@@ -58,6 +58,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/types.h>
+#include <linux/uaccess.h>
 #include "linux/ntb.h"
 #include "linux/ntb_transport.h"
 
@@ -993,7 +994,7 @@ static int ntb_transport_probe(struct ntb_client *self, struct ntb_dev *ndev)
 		if (rc)
 			goto err1;
 
-		mw->vbase = ioremap(mw->phys_addr, mw->phys_size);
+		mw->vbase = ioremap_wc(mw->phys_addr, mw->phys_size);
 		if (!mw->vbase) {
 			rc = -ENOMEM;
 			goto err1;
@@ -1375,7 +1376,15 @@ static void ntb_tx_copy_callback(void *data)
 
 static void ntb_memcpy_tx(struct ntb_queue_entry *entry, void __iomem *offset)
 {
+#ifdef ARCH_HAS_NOCACHE_UACCESS
+	/*
+	 * Using non-temporal mov to improve performance on non-cached
+	 * writes, even though we aren't actually copying from user space.
+	 */
+	__copy_from_user_inatomic_nocache(offset, entry->buf, entry->len);
+#else
 	memcpy_toio(offset, entry->buf, entry->len);
+#endif
 
 	/* Ensure that the data is fully copied out before setting the flags */
 	wmb();
Signature · 1 line
2.4.0.rc0.43.gcf8a8c6
#17 lore raw

PATCH v4 17/19 NTB: Default to CPU memcpy for performance

In reply to Allen Hubbe

From: Dave Jiang <[email protected]>

Disable DMA usage by default, since the CPU provides much better performance with write combining. Provide a module parameter to enable DMA usage when offloading the memcpy is preferred.

---
 drivers/ntb/ntb_transport.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)
drivers/ntb/ntb_transport.c +13 -4
index 7a765d3230d8..e07b056af3be 100644
@@ -88,6 +88,10 @@ 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 struct dentry *nt_debugfs_dir;
 
 struct ntb_queue_entry {
@@ -1589,10 +1593,15 @@ ntb_transport_create_queue(void *data, struct device *client_dev,
 	dma_cap_zero(dma_mask);
 	dma_cap_set(DMA_MEMCPY, dma_mask);
 
-	qp->dma_chan = dma_request_channel(dma_mask, ntb_dma_filter_fn,
-					   (void *)(unsigned long)node);
-	if (!qp->dma_chan)
-		dev_info(&pdev->dev, "Unable to allocate DMA channel, using CPU instead\n");
+	if (use_dma) {
+		qp->dma_chan = dma_request_channel(dma_mask, ntb_dma_filter_fn,
+						   (void *)(unsigned long)node);
+		if (!qp->dma_chan)
+			dev_info(&pdev->dev, "Unable to allocate DMA channel\n");
+	} else {
+		qp->dma_chan = NULL;
+	}
+	dev_dbg(&pdev->dev, "Using %s memcpy\n", qp->dma_chan ? "DMA" : "CPU");
 
 	for (i = 0; i < NTB_QP_DEF_NUM_ENTRIES; i++) {
 		entry = kzalloc_node(sizeof(*entry), GFP_ATOMIC, node);
Signature · 1 line
2.4.0.rc0.43.gcf8a8c6
#18 lore raw

PATCH v4 18/19 NTB: Rename Intel code names to platform names

In reply to Allen Hubbe

From: Dave Jiang <[email protected]>

Instead of using the platform code names, use the correct platform names to identify the respective Intel NTB hardware.

---
 Documentation/ntb.txt               |  20 +-
 drivers/ntb/hw/intel/ntb_hw_intel.c | 620 ++++++++++++++++++------------------
 drivers/ntb/hw/intel/ntb_hw_intel.h | 290 ++++++++---------
 3 files changed, 465 insertions(+), 465 deletions(-)
Documentation/ntb.txt +10 -10
index b48249a7b607..1d9bbabb6c79 100644
@@ -115,13 +115,13 @@ Module Parameters:
 * b2b\_mw\_share - If the peer ntb is to be accessed via a memory window, and if
 	the memory window is large enough, still allow the client to use the
 	second half of the memory window for address translation to the peer.
-* snb\_b2b\_usd\_bar2\_addr64 - If using B2B topology on Xeon hardware, use this
-	64 bit address on the bus between the NTB devices for the window at
-	BAR2, on the upstream side of the link.
-* snb\_b2b\_usd\_bar4\_addr64 - See *snb\_b2b\_bar2\_addr64*.
-* snb\_b2b\_usd\_bar4\_addr32 - See *snb\_b2b\_bar2\_addr64*.
-* snb\_b2b\_usd\_bar5\_addr32 - See *snb\_b2b\_bar2\_addr64*.
-* snb\_b2b\_dsd\_bar2\_addr64 - See *snb\_b2b\_bar2\_addr64*.
-* snb\_b2b\_dsd\_bar4\_addr64 - See *snb\_b2b\_bar2\_addr64*.
-* snb\_b2b\_dsd\_bar4\_addr32 - See *snb\_b2b\_bar2\_addr64*.
-* snb\_b2b\_dsd\_bar5\_addr32 - See *snb\_b2b\_bar2\_addr64*.
+* xeon\_b2b\_usd\_bar2\_addr64 - If using B2B topology on Xeon hardware, use
+	this 64 bit address on the bus between the NTB devices for the window
+	at BAR2, on the upstream side of the link.
+* xeon\_b2b\_usd\_bar4\_addr64 - See *xeon\_b2b\_bar2\_addr64*.
+* xeon\_b2b\_usd\_bar4\_addr32 - See *xeon\_b2b\_bar2\_addr64*.
+* xeon\_b2b\_usd\_bar5\_addr32 - See *xeon\_b2b\_bar2\_addr64*.
+* xeon\_b2b\_dsd\_bar2\_addr64 - See *xeon\_b2b\_bar2\_addr64*.
+* xeon\_b2b\_dsd\_bar4\_addr64 - See *xeon\_b2b\_bar2\_addr64*.
+* xeon\_b2b\_dsd\_bar4\_addr32 - See *xeon\_b2b\_bar2\_addr64*.
+* xeon\_b2b\_dsd\_bar5\_addr32 - See *xeon\_b2b\_bar2\_addr64*.
drivers/ntb/hw/intel/ntb_hw_intel.c +310 -310

1,188 lines not on this page · raw message

drivers/ntb/hw/intel/ntb_hw_intel.h +145 -145

305 lines not on this page · raw message

Signature · 1 line
2.4.0.rc0.43.gcf8a8c6
#19 lore raw

PATCH v4 19/19 NTB: Increase transport MTU to 64k from 16k

In reply to Allen Hubbe

From: Dave Jiang <[email protected]>

Benchmarking showed a significant performance increase with the MTU size to 64k instead of 16k. Change the driver default to 64k.

---
 drivers/ntb/ntb_transport.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/ntb/ntb_transport.c +1 -1
index e07b056af3be..1551493197b4 100644
@@ -76,7 +76,7 @@ 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 = 0x401E;
+static unsigned int transport_mtu = 0x10000;
 module_param(transport_mtu, uint, 0644);
 MODULE_PARM_DESC(transport_mtu, "Maximum size of NTB transport packets");
 
Signature · 1 line
2.4.0.rc0.43.gcf8a8c6