From: Mike Christie <[EMAIL PROTECTED]>
I guess the list is not allowing attachments, so here is a resend
inline.
If an abort thread and a normal thread decided to call
exch_done then we end up doing a dec on the refcount too many times.
This patch checks for ESB_ST_COMPLETE before completing it.
Signed-off-by: Mike Christie <[EMAIL PROTECTED]>
---
drivers/scsi/libfc/fc_exch.c | 13 +++++++++++--
1 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index 7d7a3ef..a4d3901 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -390,7 +390,7 @@ static void fc_exch_timeout(unsigned long ep_arg)
spin_lock_bh(&ep->ex_lock);
e_stat = ep->esb_stat;
if (e_stat & ESB_ST_COMPLETE) {
- ep->esb_stat = e_stat & ~ESB_ST_REC_QUAL;
+ ep->esb_stat = e_stat & ~(ESB_ST_REC_QUAL | ESB_ST_COMPLETE);
spin_unlock_bh(&ep->ex_lock);
if (e_stat & ESB_ST_REC_QUAL)
fc_exch_rrq(ep);
@@ -559,8 +559,17 @@ static int fc_exch_done_locked(struct fc_exch *ep)
{
int rc = 1;
- ep->esb_stat |= ESB_ST_COMPLETE;
+ /*
+ * We must check for completion in case there are two threads
+ * tyring to complete this. But the rrq code will reuse the
+ * ep, and in that case we only clear the resp and set it as
+ * complete, so it can be reused by the timer to send the rrq.
+ */
ep->resp = NULL;
+ if (ep->esb_stat & ESB_ST_COMPLETE)
+ return rc;
+ ep->esb_stat |= ESB_ST_COMPLETE;
+
if (!(ep->esb_stat & ESB_ST_REC_QUAL)) {
if (del_timer(&ep->ex_timer))
atomic_dec(&ep->ex_refcnt); /* drop hold for timer */
--
1.5.4.1
_______________________________________________
devel mailing list
[email protected]
http://www.open-fcoe.org/mailman/listinfo/devel