Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 17 Mar 2001 18:51:14 -0800
From:      Mike Smith <msmith@freebsd.org>
To:        "Douglas K. Rand" <rand@meridian-enviro.com>
Cc:        freebsd-stable@FreeBSD.ORG, Mike Tancsa <mike@sentex.net>, bryanh@meridian-enviro.com
Subject:   Re: 3ware problems 
Message-ID:  <200103180251.f2I2pEU04264@mass.dis.org>
In-Reply-To: Your message of "Fri, 16 Mar 2001 15:00:21 CST." <3AB27EE5.7CCB1387@meridian-enviro.com> 

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multipart MIME message.

--==_Exmh_7072093770
Content-Type: text/plain; charset=us-ascii

> > So far the only way I can get the problem to show up is banging on
> > MySQL for 3-12 hours.
> 
> Here is a short perl script that along with MySQL 3.23.33 will hang our
> 3ware controller:

I had to change this to 'fortune -s' to prevent the server from aborting 
the client connection, but it's just passed 2.5M rows and still counting.

Do you have any other tuning in effect?  Is the filesystem mounted with 
softupdates enabled, for example?

Please find attached diffs to bring the driver up to my current working 
version.  There's a couple of small races closed in this code which might 
have an effect on your problem (not sure about that, though), so I'd love 
to know if they help you.

Regards,
Mike


--==_Exmh_7072093770
Content-Type: text/plain ; name="twe.diff"; charset=us-ascii
Content-Description: twe.diff
Content-Disposition: attachment; filename="twe.diff"

Index: twe.c
===================================================================
RCS file: /local0/cvs/src/sys/dev/twe/twe.c,v
retrieving revision 1.7
diff -u -r1.7 twe.c
--- twe.c	2001/01/23 22:21:14	1.7
+++ twe.c	2001/03/17 23:43:58
@@ -47,8 +47,10 @@
 static void	*twe_get_param(struct twe_softc *sc, int table_id, int parameter_id, size_t size, 
 					       void (* func)(struct twe_request *tr));
 static int	twe_set_param_1(struct twe_softc *sc, int table_id, int param_id, u_int8_t value);
+#if 0
 static int	twe_set_param_2(struct twe_softc *sc, int table_id, int param_id, u_int16_t value);
 static int	twe_set_param_4(struct twe_softc *sc, int table_id, int param_id, u_int32_t value);
+#endif
 static int	twe_set_param(struct twe_softc *sc, int table_id, int param_id, int param_size, 
 					      void *data);
 static int	twe_init_connection(struct twe_softc *sc, int mode);
@@ -373,7 +375,17 @@
 	    cmd->io.lba = TWE_BIO_LBA(bp);
 
 	    /* map the command so the controller can work with it */
-	    twe_map_request(tr);
+	    if (twe_map_request(tr) != 0) {
+		/*
+		 * We can't map the request, so put the bio back on the 
+		 * queue, release the request and return to give the
+		 * system time to recover.
+		 */
+		tr->tr_private = NULL;
+		twe_release_request(tr);
+		twe_enqueue_bio(sc, bp);
+		return;
+	    }
 	}
 	
 	/* did we find something to do? */
@@ -578,7 +590,6 @@
 {
     sc->twe_state |= TWE_STATE_INTEN;
     TWE_CONTROL(sc, 
-	       TWE_CONTROL_CLEAR_ATTENTION_INTERRUPT |
 	       TWE_CONTROL_UNMASK_RESPONSE_INTERRUPT |
 	       TWE_CONTROL_ENABLE_INTERRUPTS);
 }
@@ -720,6 +731,7 @@
     return(twe_set_param(sc, table_id, param_id, sizeof(value), &value));
 }
 
+#if 0 /* currently unused */
 static int
 twe_set_param_2(struct twe_softc *sc, int table_id, int param_id, u_int16_t value)
 {
@@ -731,6 +743,7 @@
 {
     return(twe_set_param(sc, table_id, param_id, sizeof(value), &value));
 }
+#endif
 
 /********************************************************************************
  * Perform a TWE_OP_SET_PARAM command, returns nonzero on error.
@@ -1225,11 +1238,8 @@
     debug_called(4);
 
     /* instigate a poll for AENs */
-    if (twe_fetch_aen(sc)) {
-	twe_printf(sc, "error polling for signalled AEN\n");
-    } else {
-	TWE_CONTROL(sc, TWE_CONTROL_CLEAR_ATTENTION_INTERRUPT);
-    }
+    TWE_CONTROL(sc, TWE_CONTROL_CLEAR_ATTENTION_INTERRUPT);
+    twe_fetch_aen(sc);
 }
 
 /********************************************************************************
@@ -1290,9 +1300,14 @@
 
     free(tr->tr_data, M_DEVBUF);
     twe_release_request(tr);
-    twe_enqueue_aen(sc, aen);
 
-    /* XXX poll for more AENs? */
+    /* if we've hit the end of the queue, stop */
+    if (aen == TWE_AEN_QUEUE_EMPTY)
+	return;
+
+    /* enqueue this AEN and poll for the next one */
+    twe_enqueue_aen(sc, aen);
+    twe_fetch_aen(sc);
 }
 
 /********************************************************************************
@@ -1619,6 +1634,11 @@
 		    msg, TWE_AEN_UNIT(aen));
 	}
 	return(buf);
+
+    case 'd':
+	sprintf(buf, "twe%d: port %d: %s ", device_get_unit(sc->twe_dev), 
+		TWE_AEN_UNIT(aen), msg);
+	return(buf);
 	
     case 'x':
     default:
@@ -1692,6 +1712,7 @@
 #ifdef TWE_DEBUG
     panic(reason);
 #else
+    twe_printf(sc, "twe_panic - %s\n", reason);
     twe_reset(sc);
 #endif
 }
Index: twe_compat.h
===================================================================
RCS file: /local0/cvs/src/sys/dev/twe/twe_compat.h,v
retrieving revision 1.2
diff -u -r1.2 twe_compat.h
--- twe_compat.h	2000/10/25 06:59:05	1.2
+++ twe_compat.h	2001/03/17 23:55:18
@@ -131,7 +131,9 @@
 #define twed_printf(twed, fmt, args...)	device_printf(twed->twed_dev, fmt , ##args)
 
 #if __FreeBSD_version < 500003		/* old buf style */
+# include <machine/clock.h>
 # include <sys/buf.h>
+# include <sys/syslog.h>
 typedef struct buf			twe_bio;
 typedef struct buf_queue_head		twe_bioq;
 # define TWE_BIO_QINIT(bq)		bufq_init(&bq);
@@ -150,6 +152,7 @@
 # define TWE_BIO_DONE(bp)		biodone(bp)
 # define TWE_BIO_STATS_START(bp)	devstat_start_transaction(&((struct twed_softc *)TWE_BIO_SOFTC(bp))->twed_stats)
 # define TWE_BIO_STATS_END(bp)		devstat_end_transaction_buf(&((struct twed_softc *)TWE_BIO_SOFTC(bp))->twed_stats, bp)
+# define TWE_DISKERR(bp, wh, bd, lp)	diskerr(bp, wh, LOG_PRINTF, bd, lp)
 #else
 # include <sys/bio.h>
 typedef struct bio			twe_bio;
@@ -170,6 +173,7 @@
 # define TWE_BIO_DONE(bp)		biodone(bp)
 # define TWE_BIO_STATS_START(bp)	devstat_start_transaction(&((struct twed_softc *)TWE_BIO_SOFTC(bp))->twed_stats)
 # define TWE_BIO_STATS_END(bp)		devstat_end_transaction_bio(&((struct twed_softc *)TWE_BIO_SOFTC(bp))->twed_stats, bp)
+# define TWE_DISKERR(bp, wh, bd, lp)	diskerr(bp, wh, bd, lp)
 #endif
 
 #endif /* FreeBSD */
Index: twe_freebsd.c
===================================================================
RCS file: /local0/cvs/src/sys/dev/twe/twe_freebsd.c,v
retrieving revision 1.3
diff -u -r1.3 twe_freebsd.c
--- twe_freebsd.c	2000/12/03 02:11:35	1.3
+++ twe_freebsd.c	2001/03/17 23:53:38
@@ -663,6 +663,7 @@
     if (sc == NULL) {
 	TWE_BIO_SET_ERROR(bp, EINVAL);
 	printf("twe: bio for invalid disk!\n");
+	TWE_BIO_RESID(bp) = TWE_BIO_LENGTH(bp);
 	TWE_BIO_DONE(bp);
 	TWED_BIO_OUT;
 	return;
@@ -753,11 +754,18 @@
 void
 twed_intr(twe_bio *bp)
 {
+    struct twed_softc	*twed_sc = TWE_BIO_SOFTC(bp);
+
     debug_called(4);
 
     /* if no error, transfer completed */
-    if (!TWE_BIO_HAS_ERROR(bp))
+    if (!TWE_BIO_HAS_ERROR(bp)) {
 	TWE_BIO_RESID(bp) = 0;
+    } else {
+	TWE_BIO_RESID(bp) = TWE_BIO_LENGTH(bp);
+	TWE_DISKERR(bp, TWE_BIO_IS_READ(bp) ? "read error" : "write error", 0, 
+		    &twed_sc->twed_label);
+    }
 
     TWE_BIO_STATS_END(bp);
     TWE_BIO_DONE(bp);
@@ -960,13 +968,24 @@
     tr->tr_cmdphys = segs[0].ds_addr;
 }
 
-void
+int
 twe_map_request(struct twe_request *tr)
 {
     struct twe_softc	*sc = tr->tr_sc;
 
     debug_called(4);
 
+    /* 
+     * Data must be 64-byte aligned; allocate a fixup buffer if it's not.
+     */
+    if ((tr->tr_data != NULL) && (((vm_offset_t)tr->tr_data % TWE_ALIGNMENT) != 0)) {
+	tr->tr_realdata = tr->tr_data;				/* save pointer to 'real' data */
+	if ((tr->tr_data = malloc(tr->tr_length, TWE_MALLOC_CLASS, M_NOWAIT)) == NULL) {
+	    tr->tr_data = tr->tr_realdata;
+	    return(ENOMEM);
+	}
+	tr->tr_flags |= TWE_CMD_ALIGNBUF;
+    }
 
     /*
      * Map the command into bus space.
@@ -980,15 +999,6 @@
      */
     if (tr->tr_data != NULL) {
 
-	/* 
-	 * Data must be 64-byte aligned; allocate a fixup buffer if it's not.
-	 */
-	if (((vm_offset_t)tr->tr_data % TWE_ALIGNMENT) != 0) {
-	    tr->tr_realdata = tr->tr_data;				/* save pointer to 'real' data */
-	    tr->tr_flags |= TWE_CMD_ALIGNBUF;
-	    tr->tr_data = malloc(tr->tr_length, TWE_MALLOC_CLASS, M_NOWAIT);	/* XXX check result here */
-	}
-	
 	/*
 	 * Map the data buffer into bus space and build the s/g list.
 	 */
@@ -1003,6 +1013,7 @@
 	    bus_dmamap_sync(sc->twe_buffer_dmat, tr->tr_dmamap, BUS_DMASYNC_PREWRITE);
 	}
     }
+    return(0);
 }
 
 void
@@ -1039,6 +1050,7 @@
     if (tr->tr_flags & TWE_CMD_ALIGNBUF) {
 	free(tr->tr_data, TWE_MALLOC_CLASS);
 	tr->tr_data = tr->tr_realdata;		/* restore 'real' data pointer */
+	tr->tr_flags &= ~TWE_CMD_ALIGNBUF;
     }
 }
 
Index: twe_tables.h
===================================================================
RCS file: /local0/cvs/src/sys/dev/twe/twe_tables.h,v
retrieving revision 1.1
diff -u -r1.1 twe_tables.h
--- twe_tables.h	2000/10/25 06:59:05	1.1
+++ twe_tables.h	2001/03/17 23:43:28
@@ -127,6 +127,12 @@
     {"c drive timeout",			0x09},
     {"c drive error",			0x0a},
     {"c rebuild started",		0x0b},
+    {"c init started",			0x0c},
+    {"c logical unit deleted",		0x0d},
+    /* 0x0e unused */
+    {"d SMART exceeded threshold",	0x0f},
+    /* 0x10-0x20 reserved */
+    
     {"p aen queue full",		0xff},
     {NULL, 0},
     {"x unknown AEN",		0}
Index: twevar.h
===================================================================
RCS file: /local0/cvs/src/sys/dev/twe/twevar.h,v
retrieving revision 1.3
diff -u -r1.3 twevar.h
--- twevar.h	2000/12/03 02:11:35	1.3
+++ twevar.h	2001/03/17 23:43:28
@@ -148,7 +148,7 @@
 extern void	twed_intr(twe_bio *bp);				/* return bio from core */
 extern struct twe_request *twe_allocate_request(struct twe_softc *sc);	/* allocate request structure */
 extern void	twe_free_request(struct twe_request *tr);	/* free request structure */
-extern void	twe_map_request(struct twe_request *tr);	/* make request visible to controller, do s/g */
+extern int	twe_map_request(struct twe_request *tr);	/* make request visible to controller, do s/g */
 extern void	twe_unmap_request(struct twe_request *tr);	/* cleanup after transfer, unmap */
 
 /********************************************************************************
@@ -240,7 +240,7 @@
 }
 
 static __inline void
-twe_enqueue_bio(struct twe_softc *sc, struct bio *bp)
+twe_enqueue_bio(struct twe_softc *sc, twe_bio *bp)
 {
     int		s;
 
@@ -250,11 +250,11 @@
     splx(s);
 }
 
-static __inline struct bio *
+static __inline twe_bio *
 twe_dequeue_bio(struct twe_softc *sc)
 {
     int		s;
-    struct bio	*bp;
+    twe_bio	*bp;
 
     s = splbio();
     if ((bp = TWE_BIO_QFIRST(sc->twe_bioq)) != NULL) {

--==_Exmh_7072093770
Content-Type: text/plain; charset=us-ascii

... every activity meets with opposition, everyone who acts has his
rivals and unfortunately opponents also.  But not because people want
to be opponents, rather because the tasks and relationships force
people to take different points of view.  [Dr. Fritz Todt]
           V I C T O R Y   N O T   V E N G E A N C E

--==_Exmh_7072093770--



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-stable" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200103180251.f2I2pEU04264>