Skip to contentSkip to conversation

iscsi bugfixes and small cleanups

PATCH New [email protected] 1 participant 8 messages Feb 28, 2007

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

The following patches are some small bug fixes or cleanups we have had in our tree. The patches are not critical and could just go into scsi-misc. The patches are also small and not adding features so I guess they could also go to scsi-rc-fixes if more patches are being sent for 2.6.21.

The patches were made over scsi-misc.

#1 lore raw

PATCH 1/7 flush iscsi work before freeing connection

From: Mike Christie <[email protected]>

It's possible that we call iscsi_xmitworker after iscsi_conn_release which causes a oops. This patch flushes the workqueue.

---
 drivers/scsi/libiscsi.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)
drivers/scsi/libiscsi.c +3 -0
index 7c75771..6346a91 100644
@@ -1597,6 +1597,9 @@ void iscsi_conn_teardown(struct iscsi_cl
 		wake_up(&conn->ehwait);
 	}
 
+	/* flush queued up work because we free the connection below */
+	scsi_flush_work(session->host);
+
 	spin_lock_bh(&session->lock);
 	kfree(conn->data);
 	kfree(conn->persistent_address);
Signature · 1 line
1.4.1.1
#2 lore raw

PATCH 2/7 clear mtask

From: Mike Christie <[email protected]>

Consolidate the mtask clearing code.

---
 drivers/scsi/libiscsi.c |   19 ++++++++-----------
 1 files changed, 8 insertions(+), 11 deletions(-)
drivers/scsi/libiscsi.c +8 -11
index 6346a91..5c176ab 100644
@@ -577,7 +577,7 @@ void iscsi_conn_failure(struct iscsi_con
 }
 EXPORT_SYMBOL_GPL(iscsi_conn_failure);
 
-static int iscsi_xmit_imm_task(struct iscsi_conn *conn)
+static int iscsi_xmit_mtask(struct iscsi_conn *conn)
 {
 	struct iscsi_hdr *hdr = conn->mtask->hdr;
 	int rc, was_logout = 0;
@@ -591,6 +591,9 @@ static int iscsi_xmit_imm_task(struct is
 	if (rc)
 		return rc;
 
+	/* done with this in-progress mtask */
+	conn->mtask = NULL;
+
 	if (was_logout) {
 		set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
 		return -ENODATA;
@@ -643,11 +646,9 @@ static int iscsi_data_xmit(struct iscsi_
 		conn->ctask = NULL;
 	}
 	if (conn->mtask) {
-		rc = iscsi_xmit_imm_task(conn);
+		rc = iscsi_xmit_mtask(conn);
 	        if (rc)
 		        goto again;
-		/* done with this in-progress mtask */
-		conn->mtask = NULL;
 	}
 
 	/* process immediate first */
@@ -658,12 +659,10 @@ static int iscsi_data_xmit(struct iscsi_
 			list_add_tail(&conn->mtask->running,
 				      &conn->mgmt_run_list);
 			spin_unlock_bh(&conn->session->lock);
-			rc = iscsi_xmit_imm_task(conn);
+			rc = iscsi_xmit_mtask(conn);
 		        if (rc)
 			        goto again;
 	        }
-		/* done with this mtask */
-		conn->mtask = NULL;
 	}
 
 	/* process command queue */
@@ -701,12 +700,10 @@ static int iscsi_data_xmit(struct iscsi_
 			list_add_tail(&conn->mtask->running,
 				      &conn->mgmt_run_list);
 			spin_unlock_bh(&conn->session->lock);
-		        rc = tt->xmit_mgmt_task(conn, conn->mtask);
-			if (rc)
+		       	rc = iscsi_xmit_mtask(conn);
+		        if (rc)
 			        goto again;
 	        }
-		/* done with this mtask */
-		conn->mtask = NULL;
 	}
 
 	return -ENODATA;
Signature · 1 line
1.4.1.1
#3 lore raw

PATCH 3/7 rename DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH

From: Mike Christie <[email protected]>

This patch renames DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH to avoid confusion with the drivers default values (DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH is the iscsi RFC specific default).

---
 drivers/infiniband/ulp/iser/iser_initiator.c |    2 +-
 drivers/scsi/iscsi_tcp.c                     |    6 +++---
 drivers/scsi/libiscsi.c                      |    2 +-
 include/scsi/iscsi_proto.h                   |   12 +++++++++++-
 4 files changed, 16 insertions(+), 6 deletions(-)
drivers/infiniband/ulp/iser/iser_initiator.c +1 -1
index 89e3728..3261bb3 100644
@@ -201,7 +201,7 @@ static int iser_post_receive_control(str
 	 * what's common for both schemes is that the connection is not started
 	 */
 	if (conn->c_stage != ISCSI_CONN_STARTED)
-		rx_data_size = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH;
+		rx_data_size = ISCSI_DEF_MAX_RECV_SEG_LEN;
 	else /* FIXME till user space sets conn->max_recv_dlength correctly */
 		rx_data_size = 128;
 
drivers/scsi/iscsi_tcp.c +3 -3
index 8f55e14..6fd0845 100644
@@ -527,12 +527,12 @@ iscsi_tcp_hdr_recv(struct iscsi_conn *co
 		 * than 8K, but there are no targets that currently do this.
 		 * For now we fail until we find a vendor that needs it
 		 */
-		if (DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH <
+		if (ISCSI_DEF_MAX_RECV_SEG_LEN <
 		    tcp_conn->in.datalen) {
 			printk(KERN_ERR "iscsi_tcp: received buffer of len %u "
 			      "but conn buffer is only %u (opcode %0x)\n",
 			      tcp_conn->in.datalen,
-			      DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH, opcode);
+			      ISCSI_DEF_MAX_RECV_SEG_LEN, opcode);
 			rc = ISCSI_ERR_PROTO;
 			break;
 		}
@@ -1762,7 +1762,7 @@ iscsi_tcp_conn_create(struct iscsi_cls_s
 	 * due to strange issues with iser these are not set
 	 * in iscsi_conn_setup
 	 */
-	conn->max_recv_dlength = DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH;
+	conn->max_recv_dlength = ISCSI_DEF_MAX_RECV_SEG_LEN;
 
 	tcp_conn = kzalloc(sizeof(*tcp_conn), GFP_KERNEL);
 	if (!tcp_conn)
drivers/scsi/libiscsi.c +1 -1
index 5c176ab..6913466 100644
@@ -1520,7 +1520,7 @@ iscsi_conn_setup(struct iscsi_cls_sessio
 	}
 	spin_unlock_bh(&session->lock);
 
-	data = kmalloc(DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH, GFP_KERNEL);
+	data = kmalloc(ISCSI_DEF_MAX_RECV_SEG_LEN, GFP_KERNEL);
 	if (!data)
 		goto login_mtask_data_alloc_fail;
 	conn->login_mtask->data = conn->data = data;
include/scsi/iscsi_proto.h +11 -1
index 4a44278..8d1e4e8 100644
@@ -588,7 +588,17 @@ #define KEY_MAXLEN		64
 #define VALUE_MAXLEN		255
 #define TARGET_NAME_MAXLEN	VALUE_MAXLEN
 
-#define DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH	8192
+#define ISCSI_DEF_MAX_RECV_SEG_LEN		8192
+#define ISCSI_MIN_MAX_RECV_SEG_LEN		512
+#define ISCSI_MAX_MAX_RECV_SEG_LEN		16777215
+
+#define ISCSI_DEF_FIRST_BURST_LEN		65536
+#define ISCSI_MIN_FIRST_BURST_LEN		512
+#define ISCSI_MAX_FIRST_BURST_LEN		16777215
+
+#define ISCSI_DEF_MAX_BURST_LEN			262144
+#define ISCSI_MIN_MAX_BURST_LEN			512
+#define ISCSI_MAX_MAX_BURST_LEN			16777215
 
 /************************* RFC 3720 End *****************************/
 
Signature · 1 line
1.4.1.1
#4 lore raw

PATCH 4/7 use atomic for session_nr allocations

From: Mike Christie <[email protected]>

qla4xxx and iscsi_tcp or iser could be creating
sessions at the same time, so make session_nr id
allocation atomic.

---
 drivers/scsi/scsi_transport_iscsi.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)
drivers/scsi/scsi_transport_iscsi.c +4 -2
index ce0d14a..ff05c84 100644
@@ -49,7 +49,7 @@ struct iscsi_internal {
 	struct class_device_attribute *session_attrs[ISCSI_SESSION_ATTRS + 1];
 };
 
-static int iscsi_session_nr;	/* sysfs session id for next new session */
+static atomic_t iscsi_session_nr; /* sysfs session id for next new session */
 
 /*
  * list of registered transports and lock that must
@@ -300,7 +300,7 @@ int iscsi_add_session(struct iscsi_cls_s
 	int err;
 
 	ihost = shost->shost_data;
-	session->sid = iscsi_session_nr++;
+	session->sid = atomic_add_return(1, &iscsi_session_nr);
 	session->target_id = target_id;
 
 	snprintf(session->dev.bus_id, BUS_ID_SIZE, "session%u",
@@ -1419,6 +1419,8 @@ static __init int iscsi_transport_init(v
 	printk(KERN_INFO "Loading iSCSI transport class v%s.\n",
 		ISCSI_TRANSPORT_VERSION);
 
+	atomic_set(&iscsi_session_nr, 0);
+
 	err = class_register(&iscsi_transport_class);
 	if (err)
 		return err;
Signature · 1 line
1.4.1.1
#5 lore raw

PATCH 5/7 use get_unaligned

From: Mike Christie <[email protected]>

Dave Miller meantioned that the data buffer in a past sense fixup patch was not gauranteed to be aligned properly for ia64. This patch has libiscsi use get_unalinged to make sure. There are a couple more places in the digest handling we may need to do this, but we are in the middle of fixing that code for big endien systems so just the sense access is fixed here.

---
 drivers/scsi/libiscsi.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)
drivers/scsi/libiscsi.c +3 -2
index 6913466..e226433 100644
@@ -25,6 +25,7 @@ #include <linux/types.h>
 #include <linux/mutex.h>
 #include <linux/kfifo.h>
 #include <linux/delay.h>
+#include <asm/unaligned.h>
 #include <net/tcp.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_device.h>
@@ -269,14 +270,14 @@ invalid_datalen:
 			goto out;
 		}
 
-		senselen = be16_to_cpu(*(__be16 *)data);
+		senselen = be16_to_cpu(get_unaligned((__be16 *) data));
 		if (datalen < senselen)
 			goto invalid_datalen;
 
 		memcpy(sc->sense_buffer, data + 2,
 		       min_t(uint16_t, senselen, SCSI_SENSE_BUFFERSIZE));
 		debug_scsi("copied %d bytes of sense\n",
-			   min(senselen, SCSI_SENSE_BUFFERSIZE));
+			   min_t(uint16_t, senselen, SCSI_SENSE_BUFFERSIZE));
 	}
 
 	if (sc->sc_data_direction == DMA_TO_DEVICE)
Signature · 1 line
1.4.1.1
#6 lore raw

PATCH 6/7 Increase iscsi tcp max_sectors

From: Mike Christie <[email protected]>

For a while now, the block layer has seperated max sectors and max hw sectors. Software iscsi has no limit so this patch increases max hw sectors, so we can support large pass through commands.

---
 drivers/scsi/iscsi_tcp.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
drivers/scsi/iscsi_tcp.c +1 -0
index 6fd0845..861cb9b 100644
@@ -2138,6 +2138,7 @@ static struct scsi_host_template iscsi_s
 	.change_queue_depth	= iscsi_change_queue_depth,
 	.can_queue		= ISCSI_XMIT_CMDS_MAX - 1,
 	.sg_tablesize		= ISCSI_SG_TABLESIZE,
+	.max_sectors		= 0xFFFF,
 	.cmd_per_lun		= ISCSI_DEF_CMD_PER_LUN,
 	.eh_abort_handler       = iscsi_eh_abort,
 	.eh_host_reset_handler	= iscsi_eh_host_reset,
Signature · 1 line
1.4.1.1
#7 lore raw

PATCH 7/7 Print useful error message when iscsi crc23c allocation fails

From: Mike Christie <[email protected]>

People do not read the README and seem to like to unselect the crc32c module even though iscsi_tcp selects it for them. This patch spits a error that tells the user that they really do need the module. Hopefully, we will get less people asking about this now.

---
 drivers/scsi/iscsi_tcp.c |   14 ++++++++++++--
 1 files changed, 12 insertions(+), 2 deletions(-)
drivers/scsi/iscsi_tcp.c +12 -2
index 861cb9b..c9a3abf 100644
@@ -1777,14 +1777,24 @@ iscsi_tcp_conn_create(struct iscsi_cls_s
 	tcp_conn->tx_hash.tfm = crypto_alloc_hash("crc32c", 0,
 						  CRYPTO_ALG_ASYNC);
 	tcp_conn->tx_hash.flags = 0;
-	if (IS_ERR(tcp_conn->tx_hash.tfm))
+	if (IS_ERR(tcp_conn->tx_hash.tfm)) {
+		printk(KERN_ERR "Could not create connection due to crc32c "
+		       "loading error %ld. Make sure the crc32c module is "
+		       "built as a module or into the kernel\n",
+			PTR_ERR(tcp_conn->tx_hash.tfm));
 		goto free_tcp_conn;
+	}
 
 	tcp_conn->rx_hash.tfm = crypto_alloc_hash("crc32c", 0,
 						  CRYPTO_ALG_ASYNC);
 	tcp_conn->rx_hash.flags = 0;
-	if (IS_ERR(tcp_conn->rx_hash.tfm))
+	if (IS_ERR(tcp_conn->rx_hash.tfm)) {
+		printk(KERN_ERR "Could not create connection due to crc32c "
+		       "loading error %ld. Make sure the crc32c module is "
+		       "built as a module or into the kernel\n",
+			PTR_ERR(tcp_conn->rx_hash.tfm));
 		goto free_tx_tfm;
+	}
 
 	return cls_conn;
 
Signature · 1 line
1.4.1.1