git: e74e0dc9b018 - stable/13 - infiniband: Opt-in for net epoch

From: Zhenlei Huang <zlei_at_FreeBSD.org>
Date: Fri, 21 Apr 2023 10:11:28 UTC
The branch stable/13 has been updated by zlei:

URL: https://cgit.FreeBSD.org/src/commit/?id=e74e0dc9b0185e3b87a9b62161406af74cd0a56c

commit e74e0dc9b0185e3b87a9b62161406af74cd0a56c
Author:     Zhenlei Huang <zlei@FreeBSD.org>
AuthorDate: 2023-04-05 16:05:02 +0000
Commit:     Zhenlei Huang <zlei@FreeBSD.org>
CommitDate: 2023-04-21 10:10:11 +0000

    infiniband: Opt-in for net epoch
    
    This is counterpart to e87c4940156c, which did the same for ethernet.
    
    Suggested by:   hselasky
    Reviewed by:    hselasky, kib
    MFC after:      2 weeks
    Differential Revision:  https://reviews.freebsd.org/D39405
    
    (cherry picked from commit fc6c93b6a5cf14cbc099f550f745d63779499fec)
---
 sys/net/if_infiniband.c                            | 9 +++++++--
 sys/ofed/drivers/infiniband/ulp/ipoib/ipoib.h      | 2 +-
 sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c | 6 ++++--
 sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_vlan.c | 2 +-
 sys/ofed/include/rdma/ib_verbs.h                   | 1 +
 5 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/sys/net/if_infiniband.c b/sys/net/if_infiniband.c
index 9bf4756f2556..fc8ce08e0260 100644
--- a/sys/net/if_infiniband.c
+++ b/sys/net/if_infiniband.c
@@ -409,9 +409,13 @@ infiniband_input(struct ifnet *ifp, struct mbuf *m)
 	struct infiniband_header *ibh;
 	struct epoch_tracker et;
 	int isr;
+	bool needs_epoch;
+
+	needs_epoch = (ifp->if_flags & IFF_KNOWSEPOCH) == 0;
 
 	CURVNET_SET_QUIET(ifp->if_vnet);
-	NET_EPOCH_ENTER(et);
+	if (__predict_false(needs_epoch))
+		NET_EPOCH_ENTER(et);
 
 	if ((ifp->if_flags & IFF_UP) == 0) {
 		if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
@@ -501,7 +505,8 @@ infiniband_input(struct ifnet *ifp, struct mbuf *m)
 	/* Allow monitor mode to claim this frame, after stats are updated. */
 	netisr_dispatch(isr, m);
 done:
-	NET_EPOCH_EXIT(et);
+	if (__predict_false(needs_epoch))
+		NET_EPOCH_EXIT(et);
 	CURVNET_RESTORE();
 }
 
diff --git a/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib.h b/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib.h
index eb1cb87dc888..2c63b8e0117c 100644
--- a/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -459,7 +459,7 @@ void ipoib_reap_ah(struct work_struct *work);
 
 void ipoib_mark_paths_invalid(struct ipoib_dev_priv *priv);
 void ipoib_flush_paths(struct ipoib_dev_priv *priv);
-struct ipoib_dev_priv *ipoib_intf_alloc(const char *format);
+struct ipoib_dev_priv *ipoib_intf_alloc(const char *format, struct ib_device *ca);
 
 int ipoib_ib_dev_init(struct ipoib_dev_priv *priv, struct ib_device *ca,
     int port);
diff --git a/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c b/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 0982af9fb904..a1a457804169 100644
--- a/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -902,7 +902,7 @@ ipoib_priv_alloc(void)
 }
 
 struct ipoib_dev_priv *
-ipoib_intf_alloc(const char *name)
+ipoib_intf_alloc(const char *name, struct ib_device *hca)
 {
 	struct ipoib_dev_priv *priv;
 	struct ifnet *dev;
@@ -923,6 +923,8 @@ ipoib_intf_alloc(const char *name)
 	}
 	if_initname(dev, name, priv->unit);
 	dev->if_flags = IFF_BROADCAST | IFF_MULTICAST;
+	if (hca->attrs.device_cap_flags & IB_DEVICE_KNOWSEPOCH)
+		dev->if_flags |= IFF_KNOWSEPOCH;
 
 	infiniband_ifattach(priv->dev, NULL, priv->broadcastaddr);
 
@@ -977,7 +979,7 @@ ipoib_add_port(const char *format, struct ib_device *hca, u8 port)
 	struct ib_port_attr attr;
 	int result = -ENOMEM;
 
-	priv = ipoib_intf_alloc(format);
+	priv = ipoib_intf_alloc(format, hca);
 	if (!priv)
 		goto alloc_mem_failed;
 
diff --git a/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
index 1ea5cdb1a319..0256c3ee06c9 100644
--- a/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
+++ b/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_vlan.c
@@ -89,7 +89,7 @@ int ipoib_vlan_add(struct ifnet *pdev, unsigned short pkey)
 
 	snprintf(intf_name, sizeof intf_name, "%s.%04x",
 		 ppriv->dev->name, pkey);
-	priv = ipoib_intf_alloc(intf_name);
+	priv = ipoib_intf_alloc(intf_name, ppriv->ca);
 	if (!priv) {
 		result = -ENOMEM;
 		goto err;
diff --git a/sys/ofed/include/rdma/ib_verbs.h b/sys/ofed/include/rdma/ib_verbs.h
index 697dc3fbc98f..21ccfa6b08ad 100644
--- a/sys/ofed/include/rdma/ib_verbs.h
+++ b/sys/ofed/include/rdma/ib_verbs.h
@@ -229,6 +229,7 @@ enum ib_device_cap_flags {
 	IB_DEVICE_SG_GAPS_REG			= (1ULL << 32),
 	IB_DEVICE_VIRTUAL_FUNCTION		= (1ULL << 33),
 	IB_DEVICE_RAW_SCATTER_FCS		= (1ULL << 34),
+	IB_DEVICE_KNOWSEPOCH			= (1ULL << 35),
 };
 
 enum ib_signature_prot_cap {