git: 49ee94b291b4 - main - IB/ipoib: Prevent hung task or softlockup processing multicast response

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Mon, 22 Jun 2026 18:37:53 UTC
The branch main has been updated by jhb:

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

commit 49ee94b291b424caaafd456d52f0aa9da6ba168c
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2026-05-28 15:50:58 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2026-06-22 18:36:53 +0000

    IB/ipoib: Prevent hung task or softlockup processing multicast response
    
    Tested by:      Wafa Hamzah <wafah@nvidia.com> (mlx5_ib)
    Tested by:      John Baldwin <jhb@FreeBSD.org> (iw_cxgbe)
    Obtained from:  Linux commit 3874397c0bdec3c21ce071711cd105165179b8eb
    Sponsored by:   Chelsio Communications
---
 sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_ib.c        | 13 ++++++++-----
 sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c      |  2 +-
 sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_multicast.c |  7 +++++--
 3 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_ib.c
index f3d377d513a8..eb4fb67ca11c 100644
--- a/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+++ b/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_ib.c
@@ -59,21 +59,24 @@ struct ipoib_ah *ipoib_create_ah(struct ipoib_dev_priv *priv,
 				 struct ib_pd *pd, struct ib_ah_attr *attr)
 {
 	struct ipoib_ah *ah;
+	struct ib_ah *vah;
 
 	ah = kmalloc(sizeof *ah, GFP_KERNEL);
 	if (!ah)
-		return NULL;
+		return ERR_PTR(-ENOMEM);
 
 	ah->priv      = priv;
 	ah->last_send = 0;
 	kref_init(&ah->ref);
 
-	ah->ah = ib_create_ah(pd, attr, RDMA_CREATE_AH_SLEEPABLE);
-	if (IS_ERR(ah->ah)) {
+	vah = ib_create_ah(pd, attr, RDMA_CREATE_AH_SLEEPABLE);
+	if (IS_ERR(vah)) {
 		kfree(ah);
-		ah = NULL;
-	} else
+		ah = (struct ipoib_ah *)vah;
+	} else {
+		ah->ah = vah;
 		ipoib_dbg(priv, "Created ah %p\n", ah->ah);
+	}
 
 	return ah;
 }
diff --git a/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c b/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c
index fb1e34cfb215..d37021a54eb8 100644
--- a/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -535,7 +535,7 @@ path_rec_completion(int status, struct ib_sa_path_rec *pathrec, void *path_ptr)
 
 	spin_lock_irqsave(&priv->lock, flags);
 
-	if (ah) {
+	if (!IS_ERR_OR_NULL(ah)) {
 		path->pathrec = *pathrec;
 
 		old_ah   = path->ah;
diff --git a/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 3e8954eba4e4..23cf5c8458d8 100644
--- a/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/sys/ofed/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -211,8 +211,11 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
 		av.grh.dgid = mcast->mcmember.mgid;
 
 		ah = ipoib_create_ah(priv, priv->pd, &av);
-		if (!ah) {
-			ipoib_warn(priv, "ib_address_create failed\n");
+		if (IS_ERR(ah)) {
+			ipoib_warn(priv, "ib_address_create failed %ld\n",
+				-PTR_ERR(ah));
+			/* use original error */
+			return PTR_ERR(ah);
 		} else {
 			spin_lock_irq(&priv->lock);
 			mcast->ah = ah;