Module Name:    src
Committed By:   jdolecek
Date:           Sat Oct  6 21:19:55 UTC 2018

Modified Files:
        src/sys/dev/ata [jdolecek-ncqfixes]: ata.c ata_subr.c atavar.h wd.c

Log Message:
actually, just make dump use the same queue skip as recovery, and remove the
no longer necessary ata_queue_reset() call from wd(4)

also for PR kern/47041


To generate a diff of this commit:
cvs rdiff -u -r1.141.6.14 -r1.141.6.15 src/sys/dev/ata/ata.c
cvs rdiff -u -r1.6.2.6 -r1.6.2.7 src/sys/dev/ata/ata_subr.c
cvs rdiff -u -r1.99.2.9 -r1.99.2.10 src/sys/dev/ata/atavar.h
cvs rdiff -u -r1.441.2.11 -r1.441.2.12 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.14 src/sys/dev/ata/ata.c:1.141.6.15
--- src/sys/dev/ata/ata.c:1.141.6.14	Sat Oct  6 20:27:36 2018
+++ src/sys/dev/ata/ata.c	Sat Oct  6 21:19:55 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata.c,v 1.141.6.14 2018/10/06 20:27:36 jdolecek Exp $	*/
+/*	$NetBSD: ata.c,v 1.141.6.15 2018/10/06 21:19:55 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.14 2018/10/06 20:27:36 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.141.6.15 2018/10/06 21:19:55 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -961,7 +961,7 @@ ata_read_log_ext_ncq(struct ata_drive_da
 	 * and to make this a little faster. Realistically, it
 	 * should not matter.
 	 */
-	xfer->c_flags |= C_RECOVERY;
+	xfer->c_flags |= C_SKIP_QUEUE;
 	xfer->c_ata_c.r_command = WDCC_READ_LOG_EXT;
 	xfer->c_ata_c.r_lba = page = WDCC_LOG_PAGE_NCQ;
 	xfer->c_ata_c.r_st_bmask = WDCS_DRDY;
@@ -1087,7 +1087,7 @@ ata_exec_xfer(struct ata_channel *chp, s
 	 * Standard commands are added to the end of command list, but
 	 * recovery commands must be run immediatelly.
 	 */
-	if ((xfer->c_flags & C_RECOVERY) == 0)
+	if ((xfer->c_flags & C_SKIP_QUEUE) == 0)
 		SIMPLEQ_INSERT_TAIL(&chp->ch_queue->queue_xfer, xfer,
 		    c_xferchain);
 	else
@@ -1137,7 +1137,7 @@ atastart(struct ata_channel *chp)
 	struct atac_softc *atac = chp->ch_atac;
 	struct ata_queue *chq = chp->ch_queue;
 	struct ata_xfer *xfer, *axfer;
-	bool recovery;
+	bool skipq;
 
 #ifdef ATA_DEBUG
 	int spl1, spl2;
@@ -1174,18 +1174,18 @@ again:
 		goto out;
 	}
 
-	recovery = ISSET(xfer->c_flags, C_RECOVERY);
+	skipq = ISSET(xfer->c_flags, C_SKIP_QUEUE);
 
 	/* is the queue frozen? */
-	if (__predict_false(!recovery && chq->queue_freeze > 0)) {
+	if (__predict_false(!skipq && chq->queue_freeze > 0)) {
 		if (chq->queue_flags & QF_IDLE_WAIT) {
 			chq->queue_flags &= ~QF_IDLE_WAIT;
 			cv_signal(&chp->ch_queue->queue_idle);
 		}
 		ATADEBUG_PRINT(("%s(chp=%p): channel %d drive %d "
-		    "queue frozen: %d (recovery: %d)\n",
+		    "queue frozen: %d\n",
 		    __func__, chp, chp->ch_channel, xfer->c_drive,
-		    chq->queue_freeze, recovery),
+		    chq->queue_freeze),
 		    DEBUG_XFERS);
 		goto out;
 	}
@@ -1201,7 +1201,7 @@ again:
 	 * Need only check first xfer.
 	 * XXX FIS-based switching - revisit
 	 */
-	if (!recovery && (axfer = TAILQ_FIRST(&chp->ch_queue->active_xfers))) {
+	if (!skipq && (axfer = TAILQ_FIRST(&chp->ch_queue->active_xfers))) {
 		if (!ISSET(xfer->c_flags, C_NCQ) ||
 		    !ISSET(axfer->c_flags, C_NCQ) ||
 		    xfer->c_drive != axfer->c_drive)
@@ -1211,17 +1211,17 @@ again:
 	struct ata_drive_datas * const drvp = &chp->ch_drive[xfer->c_drive];
 
 	/*
-	 * Are we on limit of active xfers ?
-	 * For recovery, we must leave one slot available at all times.
+	 * Are we on limit of active xfers ? If the queue has more
+	 * than 1 openings, we keep one slot reserved for recovery or dump.
 	 */
 	KASSERT(chq->queue_active <= chq->queue_openings);
-	const uint8_t chq_openings = (!recovery && chq->queue_openings > 1)
+	const uint8_t chq_openings = (!skipq && chq->queue_openings > 1)
 	    ? (chq->queue_openings - 1) : chq->queue_openings;
 	const uint8_t drv_openings = ISSET(xfer->c_flags, C_NCQ)
 	    ? drvp->drv_openings : ATA_MAX_OPENINGS;
 	if (chq->queue_active >= MIN(chq_openings, drv_openings)) {
-		if (recovery) {
-			panic("%s: channel %d busy, recovery not possible",
+		if (skipq) {
+			panic("%s: channel %d busy, xfer not possible",
 			    __func__, chp->ch_channel);
 		}
 
@@ -1272,8 +1272,8 @@ again:
 		break;
 	}
 
-	/* Queue more commands if possible, but not during recovery */
-	if (!recovery && chq->queue_active < chq->queue_openings)
+	/* Queue more commands if possible, but not during recovery or dump */
+	if (!skipq && chq->queue_active < chq->queue_openings)
 		goto again;
 
 out:
@@ -1321,17 +1321,9 @@ ata_activate_xfer_locked(struct ata_chan
 	struct ata_queue * const chq = chp->ch_queue;
 
 	KASSERT(mutex_owned(&chp->ch_lock));
-
-	/*
-	 * When openings is just 1, can't reserve anything for
-	 * recovery. KASSERT() here is to catch code which naively
-	 * relies on C_RECOVERY to work under this condition.
-	 */
-	KASSERT((xfer->c_flags & C_RECOVERY) == 0 || chq->queue_openings > 1);
-
 	KASSERT((chq->active_xfers_used & __BIT(xfer->c_slot)) == 0);
 
-	if ((xfer->c_flags & C_RECOVERY) == 0)
+	if ((xfer->c_flags & C_SKIP_QUEUE) == 0)
 		TAILQ_INSERT_TAIL(&chq->active_xfers, xfer, c_activechain);
 	else {
 		/*

Index: src/sys/dev/ata/ata_subr.c
diff -u src/sys/dev/ata/ata_subr.c:1.6.2.6 src/sys/dev/ata/ata_subr.c:1.6.2.7
--- src/sys/dev/ata/ata_subr.c:1.6.2.6	Sat Sep 22 17:50:09 2018
+++ src/sys/dev/ata/ata_subr.c	Sat Oct  6 21:19:55 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata_subr.c,v 1.6.2.6 2018/09/22 17:50:09 jdolecek Exp $	*/
+/*	$NetBSD: ata_subr.c,v 1.6.2.7 2018/10/06 21:19:55 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ata_subr.c,v 1.6.2.6 2018/09/22 17:50:09 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata_subr.c,v 1.6.2.7 2018/10/06 21:19:55 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -65,7 +65,7 @@ extern int atadebug_mask;
 #define ATADEBUG_PRINT(args, level)
 #endif
 
-void
+static void
 ata_queue_reset(struct ata_queue *chq)
 {
 	/* make sure that we can use polled commands */

Index: src/sys/dev/ata/atavar.h
diff -u src/sys/dev/ata/atavar.h:1.99.2.9 src/sys/dev/ata/atavar.h:1.99.2.10
--- src/sys/dev/ata/atavar.h:1.99.2.9	Sat Oct  6 20:27:36 2018
+++ src/sys/dev/ata/atavar.h	Sat Oct  6 21:19:55 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: atavar.h,v 1.99.2.9 2018/10/06 20:27:36 jdolecek Exp $	*/
+/*	$NetBSD: atavar.h,v 1.99.2.10 2018/10/06 21:19:55 jdolecek Exp $	*/
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -194,7 +194,7 @@ struct ata_xfer_ops {
 #define C_FREE		0x0040		/* call ata_free_xfer() asap */
 #define C_PIOBM		0x0080		/* command uses busmastering PIO */
 #define	C_NCQ		0x0100		/* command is queued  */
-#define C_RECOVERY	0x0200		/* executed as part of recovery */
+#define C_SKIP_QUEUE	0x0200		/* skip xfer queue */
 #define C_WAITTIMO	0x0400		/* race vs. timeout */
 #define C_CHAOS		0x0800		/* forced error xfer */
 #define C_RECOVERED	0x1000		/* error recovered, no need for reset */
@@ -563,7 +563,6 @@ void	ata_dmaerr(struct ata_drive_datas *
 struct ata_queue *
 	ata_queue_alloc(uint8_t openings);
 void	ata_queue_free(struct ata_queue *);
-void	ata_queue_reset(struct ata_queue *);
 struct ata_xfer *
 	ata_queue_hwslot_to_xfer(struct ata_channel *, int);
 struct ata_xfer *

Index: src/sys/dev/ata/wd.c
diff -u src/sys/dev/ata/wd.c:1.441.2.11 src/sys/dev/ata/wd.c:1.441.2.12
--- src/sys/dev/ata/wd.c:1.441.2.11	Sat Oct  6 20:27:36 2018
+++ src/sys/dev/ata/wd.c	Sat Oct  6 21:19:55 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: wd.c,v 1.441.2.11 2018/10/06 20:27:36 jdolecek Exp $ */
+/*	$NetBSD: wd.c,v 1.441.2.12 2018/10/06 21:19:55 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.11 2018/10/06 20:27:36 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.441.2.12 2018/10/06 21:19:55 jdolecek Exp $");
 
 #include "opt_ata.h"
 #include "opt_wd.h"
@@ -1497,15 +1497,12 @@ wd_dumpblocks(device_t dev, void *va, da
 		ata_thread_run(wd->drvp->chnl_softc, AT_POLL,
 		    ATACH_TH_DRIVE_RESET, wd->drvp->drive);
 
-		/* 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));
-	xfer->c_flags |= C_PRIVATE_ALLOC;
+	xfer->c_flags |= C_PRIVATE_ALLOC | C_SKIP_QUEUE;
 
 	xfer->c_bio.blkno = blkno;
 	xfer->c_bio.flags = ATA_POLL;

Reply via email to