[openib-general] [PATCH] IB/SRP: allowing multiple connections from taregt to initiator

Ishai Rabinovitz ishai at mellanox.co.il
Wed Sep 27 10:00:06 PDT 2006


SRP High Availability should enable an initiator to connect to the same target
several times, e.g., once from each IB port of the target.

Some targets do not support multichannel. In order to work with them as well
we will use another identifier_extension to the initiator port for each target
connection.

Signed-off-by: Ishai Rabinovitz <ishai at mellanox.co.il>

---

I think this is the best solution. It allows users to use all four physical
connections from the initiator to target.

It also allows users to have several logical connections on one physical
connection (If they want connection with different attributes - for example
different max_cmd_per_lun).

It is SRP spec compliant.

I also added a module param, so it is possible to turn this option off.

Index: latest/drivers/infiniband/ulp/srp/ib_srp.c
===================================================================
--- latest.orig/drivers/infiniband/ulp/srp/ib_srp.c	2006-09-27 10:36:13.000000000 +0300
+++ latest/drivers/infiniband/ulp/srp/ib_srp.c	2006-09-27 16:48:12.000000000 +0300
@@ -85,6 +85,13 @@ MODULE_PARM_DESC(mellanox_workarounds,
 
 static const u8 mellanox_oui[3] = { 0x00, 0x02, 0xc9 };
 
+static int variable_identifier_extension = 1;
+
+module_param(variable_identifier_extension, int, 0444);
+MODULE_PARM_DESC(variable_identifier_extension,
+		 "Use another identifier_extension on each connection to target"
+		 ", allows multichannel connection on all targets if != 0");
+
 static void srp_add_one(struct ib_device *device);
 static void srp_remove_one(struct ib_device *device);
 static void srp_completion(struct ib_cq *cq, void *target_ptr);
@@ -329,6 +336,7 @@ static int srp_send_req(struct srp_targe
 	req->priv.req_it_iu_len = cpu_to_be32(srp_max_iu_len);
 	req->priv.req_buf_fmt 	= cpu_to_be16(SRP_BUF_FORMAT_DIRECT |
 					      SRP_BUF_FORMAT_INDIRECT);
+
 	/*
 	 * In the published SRP specification (draft rev. 16a), the 
 	 * port identifier format is 8 bytes of ID extension followed
@@ -341,13 +349,23 @@ static int srp_send_req(struct srp_targe
 	if (target->io_class == SRP_REV10_IB_IO_CLASS) {
 		memcpy(req->priv.initiator_port_id,
 		       target->srp_host->initiator_port_id + 8, 8);
-		memcpy(req->priv.initiator_port_id + 8,
-		       target->srp_host->initiator_port_id, 8);
+		if (variable_identifier_extension)
+			memcpy(req->priv.initiator_port_id + 8,
+			       &target, sizeof target);
+		else
+			memcpy(req->priv.initiator_port_id + 8,
+			       target->srp_host->initiator_port_id, 8);
 		memcpy(req->priv.target_port_id,     &target->ioc_guid, 8);
 		memcpy(req->priv.target_port_id + 8, &target->id_ext, 8);
 	} else {
-		memcpy(req->priv.initiator_port_id,
-		       target->srp_host->initiator_port_id, 16);
+		if (variable_identifier_extension)
+			memcpy(req->priv.initiator_port_id,
+			       &target, sizeof target);
+		else
+			memcpy(req->priv.initiator_port_id,
+			       target->srp_host->initiator_port_id, 8);
+		memcpy(req->priv.initiator_port_id + 8,
+		       target->srp_host->initiator_port_id + 8, 8);
 		memcpy(req->priv.target_port_id,     &target->id_ext, 8);
 		memcpy(req->priv.target_port_id + 8, &target->ioc_guid, 8);
 	}
@@ -1823,7 +1841,8 @@ static struct srp_host *srp_add_port(str
 	host->dev  = device;
 	host->port = port;
 
-	host->initiator_port_id[7] = port;
+	if (!variable_identifier_extension)
+		host->initiator_port_id[7] = port;
 	memcpy(host->initiator_port_id + 8, &device->dev->node_guid, 8);
 
 	host->class_dev.class = &srp_class;
-- 
Ishai Rabinovitz




More information about the general mailing list