Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/jdolecek-ncq]: src/sys/dev/ata restore the fallback to non-NCQ on retrie...
details: https://anonhg.NetBSD.org/src/rev/977723c76fff
branches: jdolecek-ncq
changeset: 352752:977723c76fff
user: jdolecek <jdolecek%NetBSD.org@localhost>
date: Sun Aug 13 11:40:25 2017 +0000
description:
restore the fallback to non-NCQ on retries, do this after WDIORETRIES_SINGLE
retries, but only for non-FUA I/O; also only do the ATA_SINGLE fallback
when non-FUA
this makes sure that bio with ATA_SINGLE is not attempted as NCQ -
the ATA_SINGLE I/O is usually done using PIO by drivers which
actually support it, and thus are not compatible with DMA-only NCQ
diffstat:
sys/dev/ata/wd.c | 24 +++++++++++++++++-------
1 files changed, 17 insertions(+), 7 deletions(-)
diffs (54 lines):
diff -r 6116bf6437f5 -r 977723c76fff sys/dev/ata/wd.c
--- a/sys/dev/ata/wd.c Sat Aug 12 22:43:22 2017 +0000
+++ b/sys/dev/ata/wd.c Sun Aug 13 11:40:25 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: wd.c,v 1.428.2.32 2017/08/12 22:12:04 jdolecek Exp $ */
+/* $NetBSD: wd.c,v 1.428.2.33 2017/08/13 11:40:25 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.428.2.32 2017/08/12 22:12:04 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.33 2017/08/13 11:40:25 jdolecek Exp $");
#include "opt_ata.h"
#include "opt_wd.h"
@@ -720,9 +720,12 @@
/*
* If we're retrying, retry in single-sector mode. This will give us
* the sector number of the problem, and will eventually allow the
- * transfer to succeed.
+ * transfer to succeed. If FUA is requested, we can't actually
+ * do this, as ATA_SINGLE is usually executed as PIO transfer by drivers
+ * which support it, and that isn't compatible with NCQ/FUA.
*/
- if (xfer->c_retries >= WDIORETRIES_SINGLE)
+ if (xfer->c_retries >= WDIORETRIES_SINGLE &&
+ (bp->b_flags & B_MEDIA_FUA) == 0)
xfer->c_bio.flags = ATA_SINGLE;
else
xfer->c_bio.flags = 0;
@@ -734,10 +737,17 @@
xfer->c_bio.flags |= ATA_LBA48;
/*
- * If NCQ was negotiated, always use it. Some drives return random
- * errors when switching between NCQ and non-NCQ I/O too often.
+ * If NCQ was negotiated, always use it for the first several attempts.
+ * Since device cancels all outstanding requests on error, downgrade
+ * to non-NCQ on retry, so that the retried transfer would not cause
+ * cascade failure for the other transfers if it fails again.
+ * If FUA was requested, we can't downgrade, as that would violate
+ * the semantics - FUA would not be honored. In that case, continue
+ * retrying with NCQ.
*/
- if (wd->drvp->drive_flags & ATA_DRIVE_NCQ) {
+ if (wd->drvp->drive_flags & ATA_DRIVE_NCQ &&
+ (xfer->c_retries < WDIORETRIES_SINGLE ||
+ (bp->b_flags & B_MEDIA_FUA) != 0)) {
xfer->c_bio.flags |= ATA_LBA48;
xfer->c_flags |= C_NCQ;
Home |
Main Index |
Thread Index |
Old Index