[openib-general] return error when rdma_listen fails

Pete Wyckoff pw at osc.edu
Tue Aug 8 11:19:28 PDT 2006


Calling rdma_listen() on a cm_id bound to INADDR_ANY can fail, e.g.
with EADDRINUSE, but report no error back to the user.  This patch
fixes that by propagating the error.  Success occurs only if at
least one of the possibly multiple devices in the system was able to
listen.  In the case of multiple devices reporting errors on listen,
only the first error value is returned.  iwarp branch.

Signed-off-by: Pete Wyckoff <pw at osc.edu>

Index: infiniband/core/cma.c
===================================================================
--- infiniband/core/cma.c	(revision 8688)
+++ infiniband/core/cma.c	(working copy)
@@ -1189,7 +1189,7 @@ static int cma_listen_handler(struct rdm
 	return id_priv->id.event_handler(id, event);
 }
 
-static void cma_listen_on_dev(struct rdma_id_private *id_priv,
+static int cma_listen_on_dev(struct rdma_id_private *id_priv,
 			      struct cma_device *cma_dev)
 {
 	struct rdma_id_private *dev_id_priv;
@@ -1198,7 +1198,7 @@ static void cma_listen_on_dev(struct rdm
 
 	id = rdma_create_id(cma_listen_handler, id_priv, id_priv->id.ps);
 	if (IS_ERR(id))
-		return;
+		return PTR_ERR(id);
 
 	dev_id_priv = container_of(id, struct rdma_id_private, id);
 
@@ -1213,20 +1213,34 @@ static void cma_listen_on_dev(struct rdm
 	if (ret)
 		goto err;
 
-	return;
+	return 0;
 err:
 	cma_destroy_listen(dev_id_priv);
+	return ret;
 }
 
-static void cma_listen_on_all(struct rdma_id_private *id_priv)
+/*
+ * Try to listen on all devices.  Return 0 if success on any device,
+ * else return the first error reported.
+ */
+static int cma_listen_on_all(struct rdma_id_private *id_priv)
 {
 	struct cma_device *cma_dev;
+	int any_success = 0;
+	int ret, ret_first = 0;
 
 	mutex_lock(&lock);
 	list_add_tail(&id_priv->list, &listen_any_list);
-	list_for_each_entry(cma_dev, &dev_list, list)
-		cma_listen_on_dev(id_priv, cma_dev);
+	list_for_each_entry(cma_dev, &dev_list, list) {
+		ret = cma_listen_on_dev(id_priv, cma_dev);
+		if (ret) {
+			if (!ret_first)
+				ret_first = ret;
+		} else
+			any_success = 1;
+	}
 	mutex_unlock(&lock);
+	return any_success ? 0 : ret_first;
 }
 
 static int cma_bind_any(struct rdma_cm_id *id, sa_family_t af)
@@ -1269,8 +1283,11 @@ int rdma_listen(struct rdma_cm_id *id, i
 			ret = -ENOSYS;
 			goto err;
 		}
-	} else
-		cma_listen_on_all(id_priv);
+	} else {
+		ret = cma_listen_on_all(id_priv);
+		if (ret)
+			goto err;
+	}
 
 	id_priv->backlog = backlog;
 	return 0;




More information about the general mailing list