Skip to contentSkip to conversation

aic94xx: fix TMF ascb handling to prevent sequencer panic

PATCH In review James Bottomley 1 participant 1 message Feb 24, 2008 SCSI

lore
Share & tools
lore

James Bottomley

author maintainer
#0 lore raw

PATCH 5/5 aic94xx: fix TMF ascb handling to prevent sequencer panic

This is a particularly nasty bug. The problem is that if any internal ascb times out, currently we free it even though it's pending at the sequencer. This results in the sequencer getting terminally confused and the error message:

BUG:sequencer:dl:no ascb

Being returned when it comes back. The way to fix this is to manage freeing the ascb from the tasklet completion routine, so that we only free it when the sequencer actually returns it. The code is also altered to use on stack completions and transfer variables.

---
 drivers/scsi/aic94xx/aic94xx_hwi.h  |    3 +-
 drivers/scsi/aic94xx/aic94xx_task.c |    4 +-
 drivers/scsi/aic94xx/aic94xx_tmf.c  |  246 +++++++++++++++++++----------------
 3 files changed, 139 insertions(+), 114 deletions(-)
drivers/scsi/aic94xx/aic94xx_hwi.h +1 -2
index 150f670..abc7575 100644
@@ -140,7 +140,7 @@ struct asd_ascb {
 
 	/* internally generated command */
 	struct timer_list timer;
-	struct completion completion;
+	struct completion *completion;
 	u8        tag_valid:1;
 	__be16    tag;		  /* error recovery only */
 
@@ -294,7 +294,6 @@ static inline void asd_init_ascb(struct asd_ha_struct *asd_ha,
 	ascb->timer.function = NULL;
 	init_timer(&ascb->timer);
 	ascb->tc_index = -1;
-	init_completion(&ascb->completion);
 }
 
 /* Must be called with the tc_index_lock held!
drivers/scsi/aic94xx/aic94xx_task.c +3 -1
index 965d4bb..008df9a 100644
@@ -343,11 +343,13 @@ Again:
 	task->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
 	task->task_state_flags |= SAS_TASK_STATE_DONE;
 	if (unlikely((task->task_state_flags & SAS_TASK_STATE_ABORTED))) {
+		struct completion *completion = ascb->completion;
 		spin_unlock_irqrestore(&task->task_state_lock, flags);
 		ASD_DPRINTK("task 0x%p done with opcode 0x%x resp 0x%x "
 			    "stat 0x%x but aborted by upper layer!\n",
 			    task, opcode, ts->resp, ts->stat);
-		complete(&ascb->completion);
+		if (completion)
+			complete(completion);
 	} else {
 		spin_unlock_irqrestore(&task->task_state_lock, flags);
 		task->lldd_task = NULL;
drivers/scsi/aic94xx/aic94xx_tmf.c +135 -111

426 lines not on this page · raw message

Signature · 1 line
1.5.4.1