mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Sean Hefty" <sean.hefty@intel.com>
To: "Hefty, Sean" <sean.hefty@intel.com>,
	"'Roland Dreier'" <rdreier@cisco.com>, <netdev@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>
Cc: <openib-general@openib.org>
Subject: [PATCH 2/6 v2] IB: match connection requests based on private data
Date: Mon, 6 Mar 2006 15:29:35 -0800	[thread overview]
Message-ID: <ORSMSX401FRaqbC8wSA0000000c@orsmsx401.amr.corp.intel.com> (raw)
In-Reply-To: <ORSMSX401FRaqbC8wSA00000005@orsmsx401.amr.corp.intel.com>

Extend matching connection requests to listens in the Infiniband CM to include
private data checks.

This allows applications to listen on the same service identifier, with private
data directing the request to the appropriate application.

Signed-off-by: Sean Hefty <sean.hefty@intel.com>

---

This should be the correct patch that incorporates feedback from the initial
submission.  Sorry about the mis-post.


diff -uprN -X linux-2.6.git/Documentation/dontdiff 
linux-2.6.git/drivers/infiniband/core/cm.c 
linux-2.6.ib/drivers/infiniband/core/cm.c
--- linux-2.6.git/drivers/infiniband/core/cm.c	2006-01-16 10:25:26.000000000 -0800
+++ linux-2.6.ib/drivers/infiniband/core/cm.c	2006-01-16 16:03:35.000000000 -0800
@@ -32,7 +32,7 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  *
- * $Id: cm.c 2821 2005-07-08 17:07:28Z sean.hefty $
+ * $Id: cm.c 4311 2005-12-05 18:42:01Z sean.hefty $
  */
 #include <linux/dma-mapping.h>
 #include <linux/err.h>
@@ -130,6 +130,7 @@ struct cm_id_private {
 	/* todo: use alternate port on send failure */
 	struct cm_av av;
 	struct cm_av alt_av;
+	struct ib_cm_compare_data *compare_data;
 
 	void *private_data;
 	__be64 tid;
@@ -355,6 +356,41 @@ static struct cm_id_private * cm_acquire
 	return cm_id_priv;
 }
 
+static void cm_mask_copy(u8 *dst, u8 *src, u8 *mask)
+{
+	int i;
+
+	for (i = 0; i < IB_CM_COMPARE_SIZE / sizeof(unsigned long); i++)
+		((unsigned long *) dst)[i] = ((unsigned long *) src)[i] &
+					     ((unsigned long *) mask)[i];
+}
+
+static int cm_compare_data(struct ib_cm_compare_data *src_data,
+			   struct ib_cm_compare_data *dst_data)
+{
+	u8 src[IB_CM_COMPARE_SIZE];
+	u8 dst[IB_CM_COMPARE_SIZE];
+
+	if (!src_data || !dst_data)
+		return 0;
+	
+	cm_mask_copy(src, src_data->data, dst_data->mask);
+	cm_mask_copy(dst, dst_data->data, src_data->mask);
+	return memcmp(src, dst, IB_CM_COMPARE_SIZE);
+}
+
+static int cm_compare_private_data(u8 *private_data,
+				   struct ib_cm_compare_data *dst_data)
+{
+	u8 src[IB_CM_COMPARE_SIZE];
+
+	if (!dst_data)
+		return 0;
+	
+	cm_mask_copy(src, private_data, dst_data->mask);
+	return memcmp(src, dst_data->data, IB_CM_COMPARE_SIZE);
+}
+
 static struct cm_id_private * cm_insert_listen(struct cm_id_private *cm_id_priv)
 {
 	struct rb_node **link = &cm.listen_service_table.rb_node;
@@ -362,14 +397,18 @@ static struct cm_id_private * cm_insert_
 	struct cm_id_private *cur_cm_id_priv;
 	__be64 service_id = cm_id_priv->id.service_id;
 	__be64 service_mask = cm_id_priv->id.service_mask;
+	int data_cmp;
 
 	while (*link) {
 		parent = *link;
 		cur_cm_id_priv = rb_entry(parent, struct cm_id_private,
 					  service_node);
+		data_cmp = cm_compare_data(cm_id_priv->compare_data,
+					   cur_cm_id_priv->compare_data);
 		if ((cur_cm_id_priv->id.service_mask & service_id) ==
 		    (service_mask & cur_cm_id_priv->id.service_id) &&
-		    (cm_id_priv->id.device == cur_cm_id_priv->id.device))
+		    (cm_id_priv->id.device == cur_cm_id_priv->id.device) &&
+		    !data_cmp)
 			return cur_cm_id_priv;
 
 		if (cm_id_priv->id.device < cur_cm_id_priv->id.device)
@@ -378,6 +417,10 @@ static struct cm_id_private * cm_insert_
 			link = &(*link)->rb_right;
 		else if (service_id < cur_cm_id_priv->id.service_id)
 			link = &(*link)->rb_left;
+		else if (service_id > cur_cm_id_priv->id.service_id)
+			link = &(*link)->rb_right;
+		else if (data_cmp < 0)
+			link = &(*link)->rb_left;
 		else
 			link = &(*link)->rb_right;
 	}
@@ -387,16 +430,20 @@ static struct cm_id_private * cm_insert_
 }
 
 static struct cm_id_private * cm_find_listen(struct ib_device *device,
-					     __be64 service_id)
+					     __be64 service_id,
+					     u8 *private_data)
 {
 	struct rb_node *node = cm.listen_service_table.rb_node;
 	struct cm_id_private *cm_id_priv;
+	int data_cmp;
 
 	while (node) {
 		cm_id_priv = rb_entry(node, struct cm_id_private, service_node);
+		data_cmp = cm_compare_private_data(private_data,
+						   cm_id_priv->compare_data);
 		if ((cm_id_priv->id.service_mask & service_id) ==
 		     cm_id_priv->id.service_id &&
-		    (cm_id_priv->id.device == device))
+		    (cm_id_priv->id.device == device) && !data_cmp)
 			return cm_id_priv;
 
 		if (device < cm_id_priv->id.device)
@@ -405,6 +452,10 @@ static struct cm_id_private * cm_find_li
 			node = node->rb_right;
 		else if (service_id < cm_id_priv->id.service_id)
 			node = node->rb_left;
+		else if (service_id > cm_id_priv->id.service_id)
+			node = node->rb_right;
+		else if (data_cmp < 0)
+			node = node->rb_left;
 		else
 			node = node->rb_right;
 	}
@@ -728,15 +779,14 @@ retest:
 	wait_event(cm_id_priv->wait, !atomic_read(&cm_id_priv->refcount));
 	while ((work = cm_dequeue_work(cm_id_priv)) != NULL)
 		cm_free_work(work);
-	if (cm_id_priv->private_data && cm_id_priv->private_data_len)
-		kfree(cm_id_priv->private_data);
+	kfree(cm_id_priv->compare_data);
+	kfree(cm_id_priv->private_data);
 	kfree(cm_id_priv);
 }
 EXPORT_SYMBOL(ib_destroy_cm_id);
 
-int ib_cm_listen(struct ib_cm_id *cm_id,
-		 __be64 service_id,
-		 __be64 service_mask)
+int ib_cm_listen(struct ib_cm_id *cm_id, __be64 service_id, __be64 service_mask,
+		 struct ib_cm_compare_data *compare_data)
 {
 	struct cm_id_private *cm_id_priv, *cur_cm_id_priv;
 	unsigned long flags;
@@ -750,7 +800,19 @@ int ib_cm_listen(struct ib_cm_id *cm_id,
 		return -EINVAL;
 
 	cm_id_priv = container_of(cm_id, struct cm_id_private, id);
-	BUG_ON(cm_id->state != IB_CM_IDLE);
+	if (cm_id->state != IB_CM_IDLE)
+		return -EINVAL;
+
+	if (compare_data) {
+		cm_id_priv->compare_data = kzalloc(sizeof *compare_data,
+						   GFP_KERNEL);
+		if (!cm_id_priv->compare_data)
+			return -ENOMEM;
+		cm_mask_copy(cm_id_priv->compare_data->data,
+			     compare_data->data, compare_data->mask);
+		memcpy(cm_id_priv->compare_data->mask, compare_data->mask,
+		       IB_CM_COMPARE_SIZE);
+	}
 
 	cm_id->state = IB_CM_LISTEN;
 
@@ -767,6 +829,8 @@ int ib_cm_listen(struct ib_cm_id *cm_id,
 
 	if (cur_cm_id_priv) {
 		cm_id->state = IB_CM_IDLE;
+		kfree(cm_id_priv->compare_data);
+		cm_id_priv->compare_data = NULL;
 		ret = -EBUSY;
 	}
 	return ret;
@@ -1239,7 +1303,8 @@ static struct cm_id_private * cm_match_r
 
 	/* Find matching listen request. */
 	listen_cm_id_priv = cm_find_listen(cm_id_priv->id.device,
-					   req_msg->service_id);
+					   req_msg->service_id,
+					   req_msg->private_data);
 	if (!listen_cm_id_priv) {
 		spin_unlock_irqrestore(&cm.lock, flags);
 		cm_issue_rej(work->port, work->mad_recv_wc,
@@ -2646,7 +2711,8 @@ static int cm_sidr_req_handler(struct cm
 		goto out; /* Duplicate message. */
 	}
 	cur_cm_id_priv = cm_find_listen(cm_id->device,
-					sidr_req_msg->service_id);
+					sidr_req_msg->service_id,
+					sidr_req_msg->private_data);
 	if (!cur_cm_id_priv) {
 		rb_erase(&cm_id_priv->sidr_id_node, &cm.remote_sidr_table);
 		spin_unlock_irqrestore(&cm.lock, flags);
diff -uprN -X linux-2.6.git/Documentation/dontdiff 
linux-2.6.git/drivers/infiniband/core/ucm.c 
linux-2.6.ib/drivers/infiniband/core/ucm.c
--- linux-2.6.git/drivers/infiniband/core/ucm.c	2006-01-16 16:03:08.000000000 -0800
+++ linux-2.6.ib/drivers/infiniband/core/ucm.c	2006-01-16 16:03:35.000000000 -0800
@@ -646,6 +646,17 @@ out:
 	return result;
 }
 
+static int ucm_validate_listen(__be64 service_id, __be64 service_mask)
+{
+	service_id &= service_mask;
+
+	if (((service_id & IB_CMA_SERVICE_ID_MASK) == IB_CMA_SERVICE_ID) ||
+	    ((service_id & IB_SDP_SERVICE_ID_MASK) == IB_SDP_SERVICE_ID))
+		return -EINVAL;
+
+	return 0;
+}
+
 static ssize_t ib_ucm_listen(struct ib_ucm_file *file,
 			     const char __user *inbuf,
 			     int in_len, int out_len)
@@ -661,7 +672,13 @@ static ssize_t ib_ucm_listen(struct ib_u
 	if (IS_ERR(ctx))
 		return PTR_ERR(ctx);
 
-	result = ib_cm_listen(ctx->cm_id, cmd.service_id, cmd.service_mask);
+	result = ucm_validate_listen(cmd.service_id, cmd.service_mask);
+	if (result)
+		goto out;
+
+	result = ib_cm_listen(ctx->cm_id, cmd.service_id, cmd.service_mask,
+			      NULL);
+out:
 	ib_ucm_ctx_put(ctx);
 	return result;
 }
diff -uprN -X linux-2.6.git/Documentation/dontdiff 
linux-2.6.git/include/rdma/ib_cm.h 
linux-2.6.ib/include/rdma/ib_cm.h
--- linux-2.6.git/include/rdma/ib_cm.h	2006-01-16 10:26:47.000000000 -0800
+++ linux-2.6.ib/include/rdma/ib_cm.h	2006-01-16 16:03:35.000000000 -0800
@@ -32,7 +32,7 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  *
- * $Id: ib_cm.h 2730 2005-06-28 16:43:03Z sean.hefty $
+ * $Id: ib_cm.h 4311 2005-12-05 18:42:01Z sean.hefty $
  */
 #if !defined(IB_CM_H)
 #define IB_CM_H
@@ -102,7 +102,8 @@ enum ib_cm_data_size {
 	IB_CM_APR_INFO_LENGTH		 = 72,
 	IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE = 216,
 	IB_CM_SIDR_REP_PRIVATE_DATA_SIZE = 136,
-	IB_CM_SIDR_REP_INFO_LENGTH	 = 72
+	IB_CM_SIDR_REP_INFO_LENGTH	 = 72,
+	IB_CM_COMPARE_SIZE		 = 64
 };
 
 struct ib_cm_id;
@@ -238,7 +239,6 @@ struct ib_cm_sidr_rep_event_param {
 	u32			qpn;
 	void			*info;
 	u8			info_len;
-
 };
 
 struct ib_cm_event {
@@ -317,6 +317,15 @@ void ib_destroy_cm_id(struct ib_cm_id *c
 
 #define IB_SERVICE_ID_AGN_MASK	__constant_cpu_to_be64(0xFF00000000000000ULL)
 #define IB_CM_ASSIGN_SERVICE_ID __constant_cpu_to_be64(0x0200000000000000ULL)
+#define IB_CMA_SERVICE_ID	__constant_cpu_to_be64(0x0000000001000000ULL)
+#define IB_CMA_SERVICE_ID_MASK	__constant_cpu_to_be64(0xFFFFFFFFFF000000ULL)
+#define IB_SDP_SERVICE_ID	__constant_cpu_to_be64(0x0000000000010000ULL)
+#define IB_SDP_SERVICE_ID_MASK	__constant_cpu_to_be64(0xFFFFFFFFFFFF0000ULL)
+
+struct ib_cm_compare_data {
+	u8  data[IB_CM_COMPARE_SIZE];
+	u8  mask[IB_CM_COMPARE_SIZE];
+};
 
 /**
  * ib_cm_listen - Initiates listening on the specified service ID for
@@ -330,10 +339,12 @@ void ib_destroy_cm_id(struct ib_cm_id *c
  *   range of service IDs.  If set to 0, the service ID is matched
  *   exactly.  This parameter is ignored if %service_id is set to
  *   IB_CM_ASSIGN_SERVICE_ID.
+ * @compare_data: This parameter is optional.  It specifies data that must
+ *   appear in the private data of a connection request for the specified
+ *   listen request.
  */
-int ib_cm_listen(struct ib_cm_id *cm_id,
-		 __be64 service_id,
-		 __be64 service_mask);
+int ib_cm_listen(struct ib_cm_id *cm_id, __be64 service_id, __be64 service_mask,
+		 struct ib_cm_compare_data *compare_data);
 
 struct ib_cm_req_param {
 	struct ib_sa_path_rec	*primary_path;




  parent reply	other threads:[~2006-03-06 23:29 UTC|newest]

Thread overview: 97+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-02-01 20:03 [PATCH 0/5] Infiniband: connection abstraction Sean Hefty
2006-02-01 20:07 ` [PATCH 1/5] " Sean Hefty
2006-02-01 20:10 ` [PATCH 2/5] " Sean Hefty
2006-02-01 20:15 ` [PATCH 3/5] " Sean Hefty
2006-03-03 21:14   ` [PATCH 3/5] export of ip_dev_find as part of Infiniband " Sean Hefty
2006-02-01 20:18 ` [PATCH 4/5] Infiniband: " Sean Hefty
2006-02-01 20:19 ` [PATCH 5/5] " Sean Hefty
2006-03-03 21:13 ` [PATCH 0/5] " Sean Hefty
2006-03-03 22:53   ` [openib-general] " Roland Dreier
2006-03-06 18:59     ` [PATCH 1/6] IB: common handling for marshalling parameters to/from userspace Sean Hefty
2006-03-19  1:19       ` 2.6.16-rc6-mm2: new RDMA CM EXPORT_SYMBOL's Andrew Morton
2006-03-19  4:11         ` Matthew Frost
2006-03-20 18:32           ` [openib-general] " Sean Hefty
2006-03-20 18:47             ` Arjan van de Ven
2006-03-20 18:47         ` Roland Dreier
2006-03-20 19:18           ` [openib-general] " Sean Hefty
2006-03-06 19:04     ` [PATCH 2/6] IB: match connection requests based on private data Sean Hefty
2006-03-06 22:05       ` [openib-general] " Sean Hefty
2006-03-06 23:29       ` Sean Hefty [this message]
2006-03-06 19:07     ` [PATCH 3/6] net/IB: export ip_dev_find Sean Hefty
2006-03-06 21:31       ` Roland Dreier
2006-03-06 21:42         ` David S. Miller
2006-03-06 19:10     ` [PATCH 4/6] IB: address translation to map IP to IB addresses (GIDs) Sean Hefty
2006-03-06 23:31       ` [PATCH 4/6 v2] IB: address translation to map IP toIB " Sean Hefty
2006-03-11  1:14         ` Roland Dreier
2006-03-11  6:10           ` Sean Hefty
2006-03-21 20:57         ` Roland Dreier
2006-03-21 21:08           ` [openib-general] " Sean Hefty
2006-03-21 22:39             ` Roland Dreier
2006-03-06 19:18     ` [PATCH 5/6] IB: IP address based RDMA connection manager Sean Hefty
2006-03-06 19:21     ` [PATCH 6/6] IB: userspace support for " Sean Hefty
2006-03-06 21:33       ` Roland Dreier
2006-03-06 21:42         ` [openib-general] " Sean Hefty
2006-03-06 21:58           ` Roland Dreier
2006-03-06 22:28             ` David S. Miller
2006-03-06 22:32               ` Roland Dreier
2006-03-06 22:39                 ` David S. Miller
2006-03-06 22:41                   ` Roland Dreier
2006-03-06 22:50                     ` David S. Miller
2006-03-06 23:40                       ` Roland Dreier
2006-03-07  0:05                         ` Bryan O'Sullivan
2006-03-07  0:10                           ` Roland Dreier
2006-03-07  0:26                         ` David S. Miller
2006-03-06 21:35       ` Roland Dreier
2006-03-06 21:43         ` [openib-general] " Sean Hefty
2006-03-06 23:41       ` [PATCH 6/6 v2] " Sean Hefty
2006-03-22  1:40         ` Roland Dreier
2006-03-22  8:30           ` Michael S. Tsirkin
2006-03-22 15:18             ` Roland Dreier
2006-03-18 12:40 2.6.16-rc6-mm2 Andrew Morton
2006-03-18 15:10 ` sata_mv success on 2.6.16-rc6-mm2 (was: Re: 2.6.16-rc6-mm2) Sander
2006-03-18 17:25 ` 2.6.16-rc6-mm2: new RDMA CM EXPORT_SYMBOL's Adrian Bunk
2006-03-19  1:44   ` Tom Tucker
2006-03-19  1:57     ` Lee Revell
2006-03-18 18:45 ` [-mm patch] drivers/edac/e752x_edac.c: make sysbus_message static Adrian Bunk
2006-03-18 18:45 ` [-mm patch] drivers/scsi/aic7xxx/aic79xx_core.c: make ahd_match_scb() static Adrian Bunk
2006-03-18 18:45 ` [-mm patch] nfs4proc.c: make _nfs4_proc_setclientid_confirm() static Adrian Bunk
2006-03-18 18:45 ` [-mm patch] net/core/scm.c: make scm_detach_fds() static Adrian Bunk
2006-03-18 20:21 ` 2.6.16-rc6-mm2 Rafael J. Wysocki
2006-03-18 20:54   ` 2.6.16-rc6-mm2 Andrew Morton
2006-03-18 21:24     ` 2.6.16-rc6-mm2 Rafael J. Wysocki
2006-03-18 21:25     ` Emulex IP over FC support shogunx
2006-03-19 23:03     ` 2.6.16-rc6-mm2 - BUG when flushing a ramdisk Neil Brown
2006-03-19  1:09 ` 2.6.16-rc6-mm2 uninitialized online_policy_cpus.bits[0] Con Kolivas
2006-03-19  1:29   ` Con Kolivas
2006-03-19  1:35   ` Andrew Morton
2006-03-19  2:37     ` Con Kolivas
2006-03-19  6:13     ` Venkatesh Pallipadi
2006-03-20  3:26 ` New Areca driver in 2.6.16-rc6-mm2 Dax Kelson
2006-03-21 23:49   ` Chris Caputo
2006-03-22  3:37     ` Matti Aarnio
2006-03-22  3:56       ` Randy.Dunlap
2006-03-22  3:56         ` Al Viro
2006-03-22  4:41       ` erich
2006-03-20 13:02 ` RAID5 grow success (was: Re: 2.6.16-rc6-mm2) Sander
2006-03-20 13:33 ` Some sata_mv error messages " Sander
2006-03-21  1:02   ` Some sata_mv error messages Jeff Garzik
2006-03-21  2:25     ` Dave Jones
2006-03-21  2:35       ` Jeff Garzik
2006-03-21 16:06         ` Peter Jones
2006-03-21  4:48     ` Mark Lord
2006-03-21  7:28       ` Sander
2006-03-21 19:33       ` Denis Leroy
2006-03-21 19:37         ` Jeff Garzik
2006-03-21 19:42         ` Mark Lord
2006-03-21  7:26     ` Sander
2006-03-21 20:27 ` 2.6.16-rc6-mm2: reiser4 BUG when unmounting fs Laurent Riffard
2006-03-21 20:38   ` Laurent Riffard
2006-03-22  7:43     ` Vladimir V. Saveliev
2006-03-22 18:38       ` Laurent Riffard
2006-03-23 17:32       ` Alexander Gran
2006-03-21 22:54 ` 2.6.16-rc6-mm2: Why is CONFIG_MIGRATION available for everyone? Adrian Bunk
2006-03-21 22:57   ` Christoph Lameter
2006-03-21 23:40   ` Christoph Lameter
2006-03-22  8:41 ` 2.6.16-rc6-mm2 J.A. Magallon
2006-03-22  8:48   ` 2.6.16-rc6-mm2 Andrew Morton
2006-03-22 10:40 ` [2.6 patch] kernel/time.c: remove unused pps_* variables Adrian Bunk

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ORSMSX401FRaqbC8wSA0000000c@orsmsx401.amr.corp.intel.com \
    --to=sean.hefty@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=openib-general@openib.org \
    --cc=rdreier@cisco.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®