Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 3331

kernel-2.6.18-194.11.1.el5.src.rpm

From: mchristi@redhat.com <mchristi@redhat.com>
Date: Thu, 30 Jul 2009 15:33:58 -0500
Subject: [scsi] bnx2i: fix conn disconnection bugs
Message-id: 1248986038-23673-1-git-send-email-mchristi@redhat.com
O-Subject: [PATCH] RHEL 5.4: bnx2i: fix conn disconnection bugs
Bugzilla: 513802
RH-Acked-by: David Miller <davem@redhat.com>

From: Mike Christie <mchristi@redhat.com>

This is for BZ 513802.

This patch fixes the following bugs:

- When a net device is brought down or bnx2i is unloaded, the
ISCSI_KEVENT_IF_DOWN message was not sent correctly and this could lead
to uip in userspace crashing. Userspace was also fixed to be more
resiliant in bz 513726.

This is upstream here:
http://git.kernel.org/?p=linux/kernel/git/davem/net-2.6.git;a=commit;h=6d7760a88c25057c2c2243e5dfe2d731064bd31d
and
http://git.kernel.org/?p=linux/kernel/git/davem/net-2.6.git;a=commit;h=a541f8401d8e9113a89ee902cb8d8e412d6d3569

- When the link goes down the iscsi cmdsn number is incremented
even though the command transfer is failed and does not even start.
When the link goes down, the driver also starts failing commands.
The iscsi layer might be able to handle this less destructively,
so queue the IO and let the iscsi layer handle it.

This part of the patch is not upstream. It was just sent yesterday:
http://marc.info/?l=linux-scsi&m=124892942116884&w=2

- If the link is down or going down or adapter is not completely setup,
the driver will try to free a connection that is not yet setup.

This part of the patch is not upstream. It was just sent yesterday:
http://marc.info/?l=linux-scsi&m=124892940716876&w=2

I have done some basic tests on the driver, and confirmed it fixed
the problems mentioned. I have pulled cables and
ran tests to login/logout of targets, and restarted targets while IO
is running.

I found one problem while doing a ifdown then ifup, but
that is not caused by these patches. It has always been in upstream
and our driver. Broadcom is working on fixing
it and I will make a new bugzilla for that issue when it is fixed.

Broadcom has also tested this driver.

This is a new driver for 5.4, so there is at least no chance for
regressions with 5.3. Broadcom is also doing pretty much all
the QE on this for us (our QE is not doing any testing), so it wil
 not invalidate our testing. Dell is also testing and Broadcom and
Dell are coordinate in their testing so it will not hurt then either.

diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c
index d025274..03ffd27 100644
--- a/drivers/net/cnic.c
+++ b/drivers/net/cnic.c
@@ -227,7 +227,7 @@ static int cnic_send_nlmsg(struct cnic_local *cp, u32 type,
 	}
 
 	rcu_read_lock();
-	ulp_ops = rcu_dereference(cp->ulp_ops[CNIC_ULP_ISCSI]);
+	ulp_ops = rcu_dereference(cnic_ulp_tbl[CNIC_ULP_ISCSI]);
 	if (ulp_ops)
 		ulp_ops->iscsi_nl_send_msg(cp->dev, msg_type, buf, len);
 	rcu_read_unlock();
@@ -320,6 +320,20 @@ static int cnic_abort_prep(struct cnic_sock *csk)
 	return 0;
 }
 
+static void cnic_uio_stop(void)
+{
+	struct cnic_dev *dev;
+
+	read_lock(&cnic_dev_lock);
+	list_for_each_entry(dev, &cnic_dev_list, list) {
+		struct cnic_local *cp = dev->cnic_priv;
+
+		if (cp->cnic_uinfo)
+			cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL);
+	}
+	read_unlock(&cnic_dev_lock);
+}
+
 int cnic_register_driver(int ulp_type, struct cnic_ulp_ops *ulp_ops)
 {
 	struct cnic_dev *dev;
@@ -391,6 +405,9 @@ int cnic_unregister_driver(int ulp_type)
 	}
 	read_unlock(&cnic_dev_lock);
 
+	if (ulp_type == CNIC_ULP_ISCSI)
+		cnic_uio_stop();
+
 	rcu_assign_pointer(cnic_ulp_tbl[ulp_type], NULL);
 
 	mutex_unlock(&cnic_lock);
@@ -633,7 +650,6 @@ static void cnic_free_resc(struct cnic_dev *dev)
 	int i = 0;
 
 	if (cp->cnic_uinfo) {
-		cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL);
 		while (cp->uio_dev != -1 && i < 15) {
 			msleep(100);
 			i++;
@@ -1058,6 +1074,9 @@ static void cnic_ulp_stop(struct cnic_dev *dev)
 	struct cnic_local *cp = dev->cnic_priv;
 	int if_type;
 
+	if (cp->cnic_uinfo)
+		cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL);
+
 	rcu_read_lock();
 	for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) {
 		struct cnic_ulp_ops *ulp_ops;
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index 5e93aaa..57a6e49 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -387,6 +387,7 @@ static struct iscsi_endpoint *bnx2i_alloc_ep(struct bnx2i_hba *hba)
 	bnx2i_ep = ep->dd_data;
 	INIT_LIST_HEAD(&bnx2i_ep->link);
 	bnx2i_ep->state = EP_STATE_IDLE;
+	bnx2i_ep->ep_iscsi_cid = (u16) -1;
 	bnx2i_ep->hba = hba;
 	bnx2i_ep->hba_age = hba->age;
 	hba->ofld_conns_active++;
@@ -1160,9 +1161,6 @@ static int bnx2i_task_xmit(struct iscsi_task *task)
 	struct bnx2i_cmd *cmd = task->dd_data;
 	struct iscsi_cmd *hdr = (struct iscsi_cmd *) task->hdr;
 
-	if (test_bit(ADAPTER_STATE_LINK_DOWN, &hba->adapter_state))
-		return -ENOTCONN;
-
 	if (!bnx2i_conn->is_bound)
 		return -ENOTCONN;
 
@@ -1695,8 +1693,6 @@ static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost,
 		goto net_if_down;
 	}
 
-	bnx2i_ep->state = EP_STATE_IDLE;
-	bnx2i_ep->ep_iscsi_cid = (u16) -1;
 	bnx2i_ep->num_active_cmds = 0;
 	iscsi_cid = bnx2i_alloc_iscsi_cid(hba);
 	if (iscsi_cid == -1) {
diff --git a/drivers/scsi/scsi_transport_iscsi2.c b/drivers/scsi/scsi_transport_iscsi2.c
index f32d594..1bc3e17 100644
--- a/drivers/scsi/scsi_transport_iscsi2.c
+++ b/drivers/scsi/scsi_transport_iscsi2.c
@@ -958,7 +958,7 @@ int iscsi_offload_mesg(struct Scsi_Host *shost,
 	struct iscsi_uevent *ev;
 	int len = NLMSG_SPACE(sizeof(*ev) + data_size);
 
-	skb = alloc_skb(len, GFP_NOIO);
+	skb = alloc_skb(len, GFP_ATOMIC);
 	if (!skb) {
 		printk(KERN_ERR "can not deliver iscsi offload message:OOM\n");
 		return -ENOMEM;
@@ -980,7 +980,7 @@ int iscsi_offload_mesg(struct Scsi_Host *shost,
 
 	memcpy((char*)ev + sizeof(*ev), data, data_size);
 
-	return iscsi_multicast_skb(skb, ISCSI_NL_GRP_UIP, GFP_NOIO);
+	return iscsi_multicast_skb(skb, ISCSI_NL_GRP_UIP, GFP_ATOMIC);
 }
 EXPORT_SYMBOL_GPL(iscsi_offload_mesg);