From owner-freebsd-stable@FreeBSD.ORG Mon May 3 07:09:42 2004 Return-Path: Delivered-To: freebsd-stable@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 9E98C16A4CE; Mon, 3 May 2004 07:09:42 -0700 (PDT) Received: from pooker.samsco.org (pooker.samsco.org [168.103.85.57]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2573A43D2F; Mon, 3 May 2004 07:09:42 -0700 (PDT) (envelope-from scottl@freebsd.org) Received: from freebsd.org (junior-wifi.samsco.home [192.168.0.11]) by pooker.samsco.org (8.12.10/8.12.10) with ESMTP id i43EDeu6012302; Mon, 3 May 2004 08:13:40 -0600 (MDT) (envelope-from scottl@freebsd.org) Message-ID: <40965292.2040608@freebsd.org> Date: Mon, 03 May 2004 08:09:22 -0600 From: Scott Long User-Agent: Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.6) Gecko/20040304 X-Accept-Language: en-us, en MIME-Version: 1.0 To: freebsd-stable@freebsd.org Content-Type: multipart/mixed; boundary="------------030007050308030708030905" X-Spam-Status: No, hits=0.0 required=3.8 tests=none autolearn=no version=2.63 X-Spam-Checker-Version: SpamAssassin 2.63 (2004-01-11) on pooker.samsco.org cc: Vinod Kashyap cc: Paul Saab Subject: [PATCH] Fix for 3ware driver X-BeenThere: freebsd-stable@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Production branch of FreeBSD source code List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 03 May 2004 14:09:42 -0000 This is a multi-part message in MIME format. --------------030007050308030708030905 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit 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 --------------030007050308030708030905 Content-Type: text/plain; name="twe.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="twe.diff" 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 */ --------------030007050308030708030905--