Module Name: src Committed By: jdolecek Date: Sat Oct 6 20:27:36 UTC 2018
Modified Files: src/sys/dev/ata [jdolecek-ncqfixes]: ata.c atavar.h wd.c Log Message: remove AT_RST_EMERG, do the queue reset explicitly in wd(4) this should explicitly fix PR kern/47041 with sync during heavy disk activity, even thought it was actually already implicitly fixed by calling ata_thread_run() for drive reset in previous commit already, since the function already called ata_queue_reset() drop now unused ch_reset_flags and drive_reset_flags To generate a diff of this commit: cvs rdiff -u -r1.141.6.13 -r1.141.6.14 src/sys/dev/ata/ata.c cvs rdiff -u -r1.99.2.8 -r1.99.2.9 src/sys/dev/ata/atavar.h cvs rdiff -u -r1.441.2.10 -r1.441.2.11 src/sys/dev/ata/wd.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/ata/ata.c diff -u src/sys/dev/ata/ata.c:1.141.6.13 src/sys/dev/ata/ata.c:1.141.6.14 --- src/sys/dev/ata/ata.c:1.141.6.13 Sat Oct 6 20:13:12 2018 +++ src/sys/dev/ata/ata.c Sat Oct 6 20:27:36 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.141.6.13 2018/10/06 20:13:12 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.141.6.14 2018/10/06 20:27:36 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.13 2018/10/06 20:13:12 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.14 2018/10/06 20:27:36 jdolecek Exp $"); #include "opt_ata.h" @@ -480,20 +480,17 @@ atabus_thread(void *arg) } if (chp->ch_flags & ATACH_TH_RESET) { /* this will unfreeze the channel */ - ata_thread_run(chp, AT_WAIT | chp->ch_reset_flags, + ata_thread_run(chp, AT_WAIT, ATACH_TH_RESET, ATACH_NODRIVE); } else if (chp->ch_flags & ATACH_TH_DRIVE_RESET) { for (i = 0; i < chp->ch_ndrives; i++) { struct ata_drive_datas *drvp; - int drv_reset_flags; drvp = &chp->ch_drive[i]; - drv_reset_flags = drvp->drive_reset_flags; if (drvp->drive_flags & ATA_DRIVE_TH_RESET) { ata_thread_run(chp, - AT_WAIT | drv_reset_flags, - ATACH_TH_DRIVE_RESET, i); + AT_WAIT, ATACH_TH_DRIVE_RESET, i); } } chp->ch_flags &= ~ATACH_TH_DRIVE_RESET; @@ -1527,9 +1524,6 @@ ata_kill_active(struct ata_channel *chp, TAILQ_FOREACH_SAFE(xfer, &chq->active_xfers, c_activechain, xfernext) { xfer->ops->c_kill_xfer(xfer->c_chp, xfer, reason); } - - if (flags & AT_RST_EMERG) - ata_queue_reset(chq); } /* @@ -1651,7 +1645,6 @@ ata_thread_run(struct ata_channel *chp, /* No need to schedule another reset */ return; } - chp->ch_reset_flags = flags & AT_RST_EMERG; break; case ATACH_TH_DRIVE_RESET: KASSERT(drive <= chp->ch_ndrives); @@ -1662,7 +1655,6 @@ ata_thread_run(struct ata_channel *chp, return; } drvp->drive_flags |= ATA_DRIVE_TH_RESET; - drvp->drive_reset_flags = flags; break; default: panic("%s: unknown type: %x", __func__, type); @@ -1726,11 +1718,6 @@ ata_thread_run(struct ata_channel *chp, /* Signal the thread in case there is an xfer to run */ cv_signal(&chp->ch_thr_idle); - - if (flags & AT_RST_EMERG) { - /* make sure that we can use polled commands */ - ata_queue_reset(chp->ch_queue); - } } int Index: src/sys/dev/ata/atavar.h diff -u src/sys/dev/ata/atavar.h:1.99.2.8 src/sys/dev/ata/atavar.h:1.99.2.9 --- src/sys/dev/ata/atavar.h:1.99.2.8 Wed Oct 3 19:20:48 2018 +++ src/sys/dev/ata/atavar.h Sat Oct 6 20:27:36 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: atavar.h,v 1.99.2.8 2018/10/03 19:20:48 jdolecek Exp $ */ +/* $NetBSD: atavar.h,v 1.99.2.9 2018/10/06 20:27:36 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. @@ -275,7 +275,6 @@ struct ata_drive_datas { #define ATA_DRIVE_NCQ 0x0200 /* drive supports NCQ feature set */ #define ATA_DRIVE_NCQ_PRIO 0x0400 /* drive supports NCQ PRIO field */ #define ATA_DRIVE_TH_RESET 0x0800 /* drive waits for thread drive reset */ - int drive_reset_flags; /* flags for drive reset via thread */ uint8_t drive_type; #define ATA_DRIVET_NONE 0 @@ -365,9 +364,6 @@ struct ata_bustype { int (*ata_bio)(struct ata_drive_datas *, struct ata_xfer *); void (*ata_reset_drive)(struct ata_drive_datas *, int, uint32_t *); void (*ata_reset_channel)(struct ata_channel *, int); -/* extra flags for ata_reset_*(), in addition to AT_* */ -#define AT_RST_EMERG 0x10000 /* emergency - e.g. for a dump */ - int (*ata_exec_command)(struct ata_drive_datas *, struct ata_xfer *); @@ -421,9 +417,6 @@ struct ata_channel { #define ATACH_NODRIVE 0xff /* no drive selected for reset */ - /* for the reset callback */ - int ch_reset_flags; - /* for the timeout callout */ struct callout c_timo_callout; /* timeout callout handle */ Index: src/sys/dev/ata/wd.c diff -u src/sys/dev/ata/wd.c:1.441.2.10 src/sys/dev/ata/wd.c:1.441.2.11 --- src/sys/dev/ata/wd.c:1.441.2.10 Sat Oct 6 19:25:43 2018 +++ src/sys/dev/ata/wd.c Sat Oct 6 20:27:36 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: wd.c,v 1.441.2.10 2018/10/06 19:25:43 jdolecek Exp $ */ +/* $NetBSD: wd.c,v 1.441.2.11 2018/10/06 20:27:36 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -54,7 +54,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.441.2.10 2018/10/06 19:25:43 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.441.2.11 2018/10/06 20:27:36 jdolecek Exp $"); #include "opt_ata.h" #include "opt_wd.h" @@ -1494,10 +1494,14 @@ wd_dumpblocks(device_t dev, void *va, da wddumprecalibrated = 1; ata_channel_lock(wd->drvp->chnl_softc); /* This will directly execute the reset due to AT_POLL */ - ata_thread_run(wd->drvp->chnl_softc, AT_POLL | AT_RST_EMERG, + ata_thread_run(wd->drvp->chnl_softc, AT_POLL, ATACH_TH_DRIVE_RESET, wd->drvp->drive); - ata_channel_unlock(wd->drvp->chnl_softc); + + /* make sure that we can use polled commands */ + ata_queue_reset(wd->drvp->chnl_softc->ch_queue); + wd->drvp->state = RESET; + ata_channel_unlock(wd->drvp->chnl_softc); } memset(xfer, 0, sizeof(*xfer));