浏览代码

[SCSI] bnx2i: Modified the bnx2i stop path to compensate for in progress ops

The stop path has been augmented to wait a max of 10s for all in
progress offload and destroy activities to complete before proceeding
to terminate all active connections (via iscsid or forcefully).

Note that any new offload and destroy requests are now blocked and
return to the caller immediately.

Signed-off-by: Eddie Wai <eddie.wai@broadcom.com>
Acked-by: Anil Veerabhadrappa <anilgv@broadcom.com>
Reviewed-by: Benjamin Li <benli@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
Reviewed-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Eddie Wai 14 年之前
父节点
当前提交
842158d7b7
共有 2 个文件被更改,包括 23 次插入5 次删除
  1. 17 4
      drivers/scsi/bnx2i/bnx2i_init.c
  2. 6 1
      drivers/scsi/bnx2i/bnx2i_iscsi.c

+ 17 - 4
drivers/scsi/bnx2i/bnx2i_init.c

@@ -209,13 +209,24 @@ void bnx2i_stop(void *handle)
 {
 {
 	struct bnx2i_hba *hba = handle;
 	struct bnx2i_hba *hba = handle;
 	int conns_active;
 	int conns_active;
+	int wait_delay = 1 * HZ;
 
 
 	/* check if cleanup happened in GOING_DOWN context */
 	/* check if cleanup happened in GOING_DOWN context */
-	if (!test_and_clear_bit(ADAPTER_STATE_GOING_DOWN,
-				&hba->adapter_state))
+	if (!test_and_set_bit(ADAPTER_STATE_GOING_DOWN,
+			      &hba->adapter_state)) {
 		iscsi_host_for_each_session(hba->shost,
 		iscsi_host_for_each_session(hba->shost,
 					    bnx2i_drop_session);
 					    bnx2i_drop_session);
-
+		wait_delay = hba->hba_shutdown_tmo;
+	}
+	/* Wait for inflight offload connection tasks to complete before
+	 * proceeding. Forcefully terminate all connection recovery in
+	 * progress at the earliest, either in bind(), send_pdu(LOGIN),
+	 * or conn_start()
+	 */
+	wait_event_interruptible_timeout(hba->eh_wait,
+					 (list_empty(&hba->ep_ofld_list) &&
+					 list_empty(&hba->ep_destroy_list)),
+					 10 * HZ);
 	/* Wait for all endpoints to be torn down, Chip will be reset once
 	/* Wait for all endpoints to be torn down, Chip will be reset once
 	 *  control returns to network driver. So it is required to cleanup and
 	 *  control returns to network driver. So it is required to cleanup and
 	 * release all connection resources before returning from this routine.
 	 * release all connection resources before returning from this routine.
@@ -224,7 +235,7 @@ void bnx2i_stop(void *handle)
 		conns_active = hba->ofld_conns_active;
 		conns_active = hba->ofld_conns_active;
 		wait_event_interruptible_timeout(hba->eh_wait,
 		wait_event_interruptible_timeout(hba->eh_wait,
 				(hba->ofld_conns_active != conns_active),
 				(hba->ofld_conns_active != conns_active),
-				hba->hba_shutdown_tmo);
+				wait_delay);
 		if (hba->ofld_conns_active == conns_active)
 		if (hba->ofld_conns_active == conns_active)
 			break;
 			break;
 	}
 	}
@@ -233,9 +244,11 @@ void bnx2i_stop(void *handle)
 	/* This flag should be cleared last so that ep_disconnect() gracefully
 	/* This flag should be cleared last so that ep_disconnect() gracefully
 	 * cleans up connection context
 	 * cleans up connection context
 	 */
 	 */
+	clear_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state);
 	clear_bit(ADAPTER_STATE_UP, &hba->adapter_state);
 	clear_bit(ADAPTER_STATE_UP, &hba->adapter_state);
 }
 }
 
 
+
 /**
 /**
  * bnx2i_init_one - initialize an adapter instance and allocate memory resources
  * bnx2i_init_one - initialize an adapter instance and allocate memory resources
  * @hba:	bnx2i adapter instance
  * @hba:	bnx2i adapter instance

+ 6 - 1
drivers/scsi/bnx2i/bnx2i_iscsi.c

@@ -1383,6 +1383,12 @@ static int bnx2i_conn_bind(struct iscsi_cls_session *cls_session,
 	ep = iscsi_lookup_endpoint(transport_fd);
 	ep = iscsi_lookup_endpoint(transport_fd);
 	if (!ep)
 	if (!ep)
 		return -EINVAL;
 		return -EINVAL;
+	/*
+	 * Forcefully terminate all in progress connection recovery at the
+	 * earliest, either in bind(), send_pdu(LOGIN), or conn_start()
+	 */
+	if (bnx2i_adapter_ready(hba))
+		return -EIO;
 
 
 	bnx2i_ep = ep->dd_data;
 	bnx2i_ep = ep->dd_data;
 	if ((bnx2i_ep->state == EP_STATE_TCP_FIN_RCVD) ||
 	if ((bnx2i_ep->state == EP_STATE_TCP_FIN_RCVD) ||
@@ -1404,7 +1410,6 @@ static int bnx2i_conn_bind(struct iscsi_cls_session *cls_session,
 				  hba->netdev->name);
 				  hba->netdev->name);
 		return -EEXIST;
 		return -EEXIST;
 	}
 	}
-
 	bnx2i_ep->conn = bnx2i_conn;
 	bnx2i_ep->conn = bnx2i_conn;
 	bnx2i_conn->ep = bnx2i_ep;
 	bnx2i_conn->ep = bnx2i_ep;
 	bnx2i_conn->iscsi_conn_cid = bnx2i_ep->ep_iscsi_cid;
 	bnx2i_conn->iscsi_conn_cid = bnx2i_ep->ep_iscsi_cid;