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>