public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
From: Ravi Anand <ravi.anand@qlogic.com>
To: James Bottomley <james.bottomley@suse.de>
Cc: Linux-SCSI Mailing List <linux-scsi@vger.kernel.org>,
	Mike Christie <michaelc@cs.wisc.edu>,
	Karen Higgins <karen.higgins@qlogic.com>,
	Vikas Chaudhary <vikas.chaudhary@qlogic.com>
Subject: [PATCH 06/11] qla4xxx: added srb referance counter
Date: Fri, 29 Jan 2010 22:28:56 -0800	[thread overview]
Message-ID: <20100130062856.GG10274@linux-qf4p> (raw)

From: Vikas Chaudhary <vikas.chaudhary@qlogic.com>

Serialization between the error handler and recovery code.

Signed-off-by: Karen Higgins <karen.higgins@qlogic.com>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
Signed-off-by: Ravi Anand <ravi.anand@qlogic.com>
---
 drivers/scsi/qla4xxx/ql4_glbl.h |    2 +
 drivers/scsi/qla4xxx/ql4_isr.c  |    6 ++--
 drivers/scsi/qla4xxx/ql4_os.c   |   58 +++++++++++++++++++++++++++++++++++----
 3 files changed, 57 insertions(+), 9 deletions(-)

diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h
index 96ebfb0..6400714 100644
--- a/drivers/scsi/qla4xxx/ql4_glbl.h
+++ b/drivers/scsi/qla4xxx/ql4_glbl.h
@@ -73,6 +73,8 @@ void qla4xxx_dump_buffer(void *b, uint32_t size);
 int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha,
 	struct ddb_entry *ddb_entry, int lun, uint16_t mrkr_mod);
 
+void sp_put(struct scsi_qla_host *ha, struct srb *sp);
+
 extern int ql4xextended_error_logging;
 extern int ql4xdiscoverywait;
 extern int ql4xdontresethba;
diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c
index 36e6e85..21c4d02 100644
--- a/drivers/scsi/qla4xxx/ql4_isr.c
+++ b/drivers/scsi/qla4xxx/ql4_isr.c
@@ -97,7 +97,7 @@ qla4xxx_status_cont_entry(struct scsi_qla_host *ha,
 
 	/* Place command on done queue. */
 	if (srb->req_sense_len == 0) {
-		qla4xxx_srb_compl(ha, srb);
+		sp_put(ha, srb);
 		ha->status_srb = NULL;
 	}
 }
@@ -329,7 +329,7 @@ status_entry_exit:
 	/* complete the request, if not waiting for status_continuation pkt */
 	srb->cc_stat = sts_entry->completionStatus;
 	if (ha->status_srb == NULL)
-		qla4xxx_srb_compl(ha, srb);
+		sp_put(ha, srb);
 }
 
 /**
@@ -393,7 +393,7 @@ static void qla4xxx_process_response_queue(struct scsi_qla_host * ha)
 			/* ETRY normally by sending it back with
 			 * DID_BUS_BUSY */
 			srb->cmd->result = DID_BUS_BUSY << 16;
-			qla4xxx_srb_compl(ha, srb);
+			sp_put(ha, srb);
 			break;
 
 		case ET_CONTINUE:
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 97d35fd..9057860 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -372,6 +372,16 @@ void qla4xxx_mark_device_missing(struct scsi_qla_host *ha,
 	iscsi_conn_error_event(ddb_entry->conn, ISCSI_ERR_CONN_FAILED);
 }
 
+/***
+ * qla4xxx_get_new_srb - Allocate memory for a local srb.
+ * @ha: Pointer to host adapter structure.
+ * @ddb_entry: Pointer to device database entry
+ * @cmd: Pointer to Linux's SCSI command structure
+ * @done: Pointer to Linux's SCSI mid-layer done function
+ *
+ * NOTE: Sets te ref_count for non-NULL srb to one,
+ *       and initializes some fields.
+ **/
 static struct srb* qla4xxx_get_new_srb(struct scsi_qla_host *ha,
 				       struct ddb_entry *ddb_entry,
 				       struct scsi_cmnd *cmd,
@@ -417,6 +427,33 @@ void qla4xxx_srb_compl(struct scsi_qla_host *ha, struct srb *srb)
 }
 
 /**
+ * sp_put - Decrement reference count and call callback.
+ * @ha: Pointer to host adapter structure.
+ * @sp: Pointer to srb structure
+ **/
+void sp_put(struct scsi_qla_host *ha, struct srb *sp)
+{
+	if (atomic_read(&sp->ref_count) == 0) {
+		DEBUG2(printk("%s: SP->ref_count ZERO\n", __func__));
+		DEBUG2(BUG());
+		return;
+	}
+	if (!atomic_dec_and_test(&sp->ref_count)) {
+		return;
+	}
+	qla4xxx_srb_compl(ha, sp);
+}
+
+/**
+ * sp_get - Increment reference count of the specified sp.
+ * @sp: Pointer to srb structure
+ **/
+void sp_get(struct srb *sp)
+{
+	atomic_inc(&sp->ref_count);
+}
+
+/**
  * qla4xxx_queuecommand - scsi layer issues scsi command to driver.
  * @cmd: Pointer to Linux's SCSI command structure
  * @done_fn: Function that the driver calls to notify the SCSI mid-layer
@@ -886,7 +923,7 @@ static void qla4xxx_flush_active_srbs(struct scsi_qla_host *ha)
 		srb = qla4xxx_del_from_active_array(ha, i);
 		if (srb != NULL) {
 			srb->cmd->result = DID_RESET << 16;
-			qla4xxx_srb_compl(ha, srb);
+			sp_put(ha, srb);
 		}
 	}
 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
@@ -1462,16 +1499,20 @@ struct srb * qla4xxx_del_from_active_array(struct scsi_qla_host *ha, uint32_t in
  * qla4xxx_eh_wait_on_command - waits for command to be returned by firmware
  * @ha: actual ha whose done queue will contain the comd returned by firmware.
  * @cmd: Scsi Command to wait on.
+ * @got_ref: Additional reference retrieved by caller.
  *
  * This routine waits for the command to be returned by the Firmware
  * for some max time.
  **/
 static int qla4xxx_eh_wait_on_command(struct scsi_qla_host *ha,
-				      struct scsi_cmnd *cmd)
+				      struct scsi_cmnd *cmd, int got_ref)
 {
+#define ABORT_POLLING_PERIOD	1000
+#define ABORT_WAIT_ITER		1
+
 	int done = 0;
 	struct srb *rp;
-	uint32_t max_wait_time = EH_WAIT_CMD_TOV;
+	unsigned long wait_iter = ABORT_WAIT_ITER;
 
 	do {
 		/* Checking to see if its returned to OS */
@@ -1481,8 +1522,13 @@ static int qla4xxx_eh_wait_on_command(struct scsi_qla_host *ha,
 			break;
 		}
 
-		msleep(2000);
-	} while (max_wait_time--);
+		if (got_ref && (atomic_read(&rp->ref_count) == 1)) {
+			done++;
+			break;
+		}
+
+		msleep(ABORT_POLLING_PERIOD);
+	} while (!(--wait_iter));
 
 	return done;
 }
@@ -1534,7 +1580,7 @@ static int qla4xxx_eh_wait_for_commands(struct scsi_qla_host *ha,
 		cmd = scsi_host_find_tag(ha->host, cnt);
 		if (cmd && stgt == scsi_target(cmd->device) &&
 		    (!sdev || sdev == cmd->device)) {
-			if (!qla4xxx_eh_wait_on_command(ha, cmd)) {
+			if (!qla4xxx_eh_wait_on_command(ha, cmd, 0)) {
 				status++;
 				break;
 			}
-- 
1.6.0.2


             reply	other threads:[~2010-01-30  6:27 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-01-30  6:28 Ravi Anand [this message]
2010-02-01 18:22 ` [PATCH 06/11] qla4xxx: added srb referance counter Mike Christie
2010-02-11 11:08   ` Ravi Anand
2010-02-11 22:57     ` Mike Christie
2010-02-11 23:02       ` Mike Christie
     [not found]         ` <0CB616B0-0903-41A0-9ADD-5DD64989FFD1@qlogic.com>
2010-02-11 23:54           ` Mike Christie
2010-02-12  0:06             ` Mike Christie
2010-02-12  0:48             ` Mike Christie
2010-02-12 17:29     ` Mike Christie
2010-02-12 18:19       ` James Bottomley

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=20100130062856.GG10274@linux-qf4p \
    --to=ravi.anand@qlogic.com \
    --cc=james.bottomley@suse.de \
    --cc=karen.higgins@qlogic.com \
    --cc=linux-scsi@vger.kernel.org \
    --cc=michaelc@cs.wisc.edu \
    --cc=vikas.chaudhary@qlogic.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