[openib-general] [PATCH] cm: fix for service_id/service_mask hole

Jordan, Bill bjordan at silverstorm.com
Thu Jun 16 13:49:59 PDT 2005


Sean,

Here is a to fix a bug in service_id/service_mask
handling in CM.

Previously, if you tried to listen on service_id:
service_mask of 0x00:0x0F, followed by a listen
on 0xF0:0xF0, the second listen would fail because
the two ranges overlap (0xF0 appears in both ranges).
But, if you tried the listens in the reverse order,
both would succeed leading to an ambigious listen.

This patch forces both service_ids in the compare to be
masked against both mask values first.

Signed-off-by: Bill Jordan <bjordan at silverstorm.com>

Index: src/linux-kernel/infiniband/core/cm.c
===================================================================
--- src/linux-kernel/infiniband/core/cm.c	(revision 2636)
+++ src/linux-kernel/infiniband/core/cm.c	(working copy)
@@ -354,14 +354,14 @@ static struct cm_id_private * cm_insert_
 	struct rb_node *parent = NULL;
 	struct cm_id_private *cur_cm_id_priv;
 	u64 service_id = cm_id_priv->id.service_id;
+	u64 service_mask = cm_id_priv->id.service_mask;
 
 	while (*link) {
 		parent = *link;
 		cur_cm_id_priv = rb_entry(parent, struct cm_id_private,
 					  service_node);
 		if ((cur_cm_id_priv->id.service_mask & service_id) ==
-		    (cur_cm_id_priv->id.service_mask &
-		     cur_cm_id_priv->id.service_id))
+		    (service_mask & cur_cm_id_priv->id.service_id))
 			return cm_id_priv;
 		if (service_id < cur_cm_id_priv->id.service_id)
 			link = &(*link)->rb_left;
@@ -719,6 +719,8 @@ int ib_cm_listen(struct ib_cm_id *cm_id,
 	unsigned long flags;
 	int ret = 0;
 
+	service_mask = service_mask ? service_mask : ~0ULL;
+	service_id &= service_mask;
 	if ((service_id & IB_SERVICE_ID_AGN_MASK) == IB_CM_ASSIGN_SERVICE_ID &&
 	    (service_id != IB_CM_ASSIGN_SERVICE_ID))
 		return -EINVAL;
@@ -734,7 +736,7 @@ int ib_cm_listen(struct ib_cm_id *cm_id,
 		cm_id->service_mask = ~0ULL;
 	} else {
 		cm_id->service_id = service_id;
-		cm_id->service_mask = service_mask ? service_mask : ~0ULL;
+		cm_id->service_mask = service_mask;
 	}
 	cur_cm_id_priv = cm_insert_listen(cm_id_priv);
 	spin_unlock_irqrestore(&cm.lock, flags);



More information about the general mailing list