Date: Mon, 03 May 2004 08:09:22 -0600 From: Scott Long <scottl@freebsd.org> To: freebsd-stable@freebsd.org Cc: Paul Saab <ps@freebsd.org> Subject: [PATCH] Fix for 3ware driver Message-ID: <40965292.2040608@freebsd.org>
next in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
All,
Release testing has shown several recent problems with the 3ware (twe)
driver. Attached is a patch that appears to fix these problems. I
would appreciate as much testing as possible before I commit so that I
can be sure that all of the problems are caught and fixed correctly.
The patch applies to both RELENG_4_10 and RELENG_4 branches. Symptoms
of the problems included i/o hangs under heavy load and filesystem
corruption.
Thanks,
Scott
[-- Attachment #2 --]
Index: twe.c
===================================================================
RCS file: /mnt/ncvs/src/sys/dev/twe/twe.c,v
retrieving revision 1.1.2.8
diff -u -r1.1.2.8 twe.c
--- twe.c 7 Apr 2004 22:18:00 -0000 1.1.2.8
+++ twe.c 3 May 2004 01:03:37 -0000
@@ -393,14 +393,14 @@
/* build a command from an outstanding bio */
if (tr == NULL) {
-
- /* see if there's work to be done */
- if ((bp = twe_dequeue_bio(sc)) == NULL)
- break;
/* get a command to handle the bio with */
- if (twe_get_request(sc, &tr)) {
- twe_enqueue_bio(sc, bp); /* failed, put the bio back */
+ if (twe_get_request(sc, &tr))
+ break;
+
+ /* see if there's work to be done */
+ if ((bp = twe_dequeue_bio(sc)) == NULL) {
+ twe_release_request(tr);
break;
}
@@ -1093,20 +1093,18 @@
{
TWE_Response_Queue rq;
struct twe_request *tr;
- int s, found;
+ int s;
u_int32_t status_reg;
debug_called(5);
/* loop collecting completed commands */
- found = 0;
s = splbio();
for (;;) {
status_reg = TWE_STATUS(sc);
twe_check_bits(sc, status_reg); /* XXX should this fail? */
if (!(status_reg & TWE_STATUS_RESPONSE_QUEUE_EMPTY)) {
- found = 1;
rq = TWE_RESPONSE_QUEUE(sc);
tr = sc->twe_lookup[rq.u.response_id]; /* find command */
if (tr->tr_status != TWE_CMD_BUSY)
@@ -1117,6 +1115,7 @@
/* move to completed queue */
twe_remove_busy(tr);
twe_enqueue_complete(tr);
+ sc->twe_state &= ~TWE_STATE_FRZN;
} else {
break; /* no response ready */
}
@@ -1124,8 +1123,7 @@
splx(s);
/* if we've completed any commands, try posting some more */
- if (found)
- twe_startio(sc);
+ twe_startio(sc);
/* handle completion and timeouts */
twe_complete(sc); /* XXX use deferred completion? */
Index: twe_freebsd.c
===================================================================
RCS file: /mnt/ncvs/src/sys/dev/twe/twe_freebsd.c,v
retrieving revision 1.2.2.8
diff -u -r1.2.2.8 twe_freebsd.c
--- twe_freebsd.c 7 Apr 2004 22:18:00 -0000 1.2.2.8
+++ twe_freebsd.c 3 May 2004 01:00:32 -0000
@@ -944,8 +944,6 @@
tr->tr_flags |= TWE_CMD_MAPPED;
- if (tr->tr_flags & TWE_CMD_IN_PROGRESS)
- tr->tr_sc->twe_state &= ~TWE_STATE_FRZN;
/* save base of first segment in command (applicable if there only one segment) */
tr->tr_dataphys = segs[0].ds_addr;
@@ -1055,7 +1053,6 @@
if ((error = bus_dmamap_load(sc->twe_buffer_dmat, tr->tr_dmamap, tr->tr_data,
tr->tr_length, twe_setup_data_dmamap, tr, 0)
== EINPROGRESS)) {
- tr->tr_flags |= TWE_CMD_IN_PROGRESS;
sc->twe_state |= TWE_STATE_FRZN;
error = 0;
}
@@ -1102,6 +1099,8 @@
free(tr->tr_data, TWE_MALLOC_CLASS);
tr->tr_data = tr->tr_realdata; /* restore 'real' data pointer */
}
+
+ tr->tr_flags &= ~TWE_CMD_MAPPED;
}
#ifdef TWE_DEBUG
Index: twevar.h
===================================================================
RCS file: /mnt/ncvs/src/sys/dev/twe/twevar.h,v
retrieving revision 1.1.2.6
diff -u -r1.1.2.6 twevar.h
--- twevar.h 7 Apr 2004 22:18:01 -0000 1.1.2.6
+++ twevar.h 3 May 2004 00:49:34 -0000
@@ -121,7 +121,6 @@
#define TWE_CMD_ALIGNBUF (1<<2) /* data in bio is misaligned, have to copy to/from private buffer */
#define TWE_CMD_SLEEPER (1<<3) /* owner is sleeping on this command */
#define TWE_CMD_MAPPED (1<<4) /* cmd has been mapped */
-#define TWE_CMD_IN_PROGRESS (1<<5) /* bus_dmamap_load returned EINPROGRESS */
void (* tr_complete)(struct twe_request *tr); /* completion handler */
void *tr_private; /* submitter-private data or wait channel */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?40965292.2040608>
