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 add sysctls to control if NCQ is being us...
details: https://anonhg.NetBSD.org/src/rev/08aa2ccb38f9
branches: jdolecek-ncq
changeset: 352791:08aa2ccb38f9
user: jdolecek <jdolecek%NetBSD.org@localhost>
date: Thu Sep 28 20:34:23 2017 +0000
description:
add sysctls to control if NCQ is being used, and how many max tags;
I have a drive which is significantly slower with NCQ than non-NCQ,
and it's generally useful to have this easily overridable
while here, also move the frequency settings for WD_CHAOS_MONKEY
to a sysctl and make it per-drive
diffstat:
sys/dev/ata/TODO.ncq | 2 -
sys/dev/ata/wd.c | 109 ++++++++++++++++++++++++++++++++++++++++++++------
sys/dev/ata/wdvar.h | 16 +++++++-
3 files changed, 110 insertions(+), 17 deletions(-)
diffs (232 lines):
diff -r 98860e038f2f -r 08aa2ccb38f9 sys/dev/ata/TODO.ncq
--- a/sys/dev/ata/TODO.ncq Thu Sep 28 20:25:45 2017 +0000
+++ b/sys/dev/ata/TODO.ncq Thu Sep 28 20:34:23 2017 +0000
@@ -32,8 +32,6 @@
is too much for emergency crash dump code path
- old bug - kern/16789
-add nibble to control number of tags (1==disable NCQ)?
-
add support for the NCQ TRIM if supported by device?
implement DIOCGCACHE/DIOCCACHESYNC for ld@ataraid? just passthrough, like ccd
diff -r 98860e038f2f -r 08aa2ccb38f9 sys/dev/ata/wd.c
--- a/sys/dev/ata/wd.c Thu Sep 28 20:25:45 2017 +0000
+++ b/sys/dev/ata/wd.c Thu Sep 28 20:34:23 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: wd.c,v 1.428.2.34 2017/08/13 15:12:04 jdolecek Exp $ */
+/* $NetBSD: wd.c,v 1.428.2.35 2017/09/28 20:34:23 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.34 2017/08/13 15:12:04 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.35 2017/09/28 20:34:23 jdolecek Exp $");
#include "opt_ata.h"
#include "opt_wd.h"
@@ -116,11 +116,6 @@
#define ATADEBUG_PRINT(args, level)
#endif
-#ifdef WD_CHAOS_MONKEY
-int wdcdebug_wd_cnt = 0;
-int wdcdebug_wd_chaos = 0;
-#endif
-
int wdprobe(device_t, cfdata_t, void *);
void wdattach(device_t, device_t, void *);
int wddetach(device_t, int);
@@ -211,6 +206,9 @@
int wd_getcache(struct wd_softc *, int *);
int wd_setcache(struct wd_softc *, int);
+static void wd_sysctl_attach(struct wd_softc *);
+static void wd_sysctl_detach(struct wd_softc *);
+
struct dkdriver wddkdriver = {
.d_strategy = wdstrategy,
.d_minphys = wdminphys
@@ -450,6 +448,8 @@
if (!pmf_device_register1(self, wd_suspend, NULL, wd_shutdown))
aprint_error_dev(self, "couldn't establish power handler\n");
+
+ wd_sysctl_attach(wd);
}
static bool
@@ -520,6 +520,8 @@
pmf_device_deregister(self);
+ wd_sysctl_detach(sc);
+
/* Unhook the entropy source. */
rnd_detach_source(&sc->rnd_source);
@@ -663,8 +665,7 @@
while (bufq_peek(wd->sc_q) != NULL) {
/* First try to get xfer. Limit to drive openings iff NCQ. */
xfer = ata_get_xfer_ext(wd->drvp->chnl_softc, 0,
- ISSET(wd->drvp->drive_flags, ATA_DRIVE_NCQ)
- ? wd->drvp->drv_openings : 0);
+ WD_USE_NCQ(wd) ? WD_MAX_OPENINGS(wd) : 0);
if (xfer == NULL)
break;
@@ -708,8 +709,8 @@
* the command be clipped, or otherwise misinterpreted, by the
* driver or controller.
*/
- if (BUF_ISREAD(bp) && xfer->c_retries == 0 && wdcdebug_wd_cnt > 0 &&
- (++wdcdebug_wd_chaos % wdcdebug_wd_cnt) == 0) {
+ if (BUF_ISREAD(bp) && xfer->c_retries == 0 && wd->drv_chaos_freq > 0 &&
+ (++wd->drv_chaos_cnt % wd->drv_chaos_freq) == 0) {
aprint_normal_dev(wd->sc_dev, "%s: chaos xfer %d\n",
__func__, xfer->c_slot);
xfer->c_bio.blkno = 7777777 + wd->sc_capacity;
@@ -745,8 +746,7 @@
* the semantics - FUA would not be honored. In that case, continue
* retrying with NCQ.
*/
- if (wd->drvp->drive_flags & ATA_DRIVE_NCQ &&
- (xfer->c_retries < WDIORETRIES_SINGLE ||
+ if (WD_USE_NCQ(wd) && (xfer->c_retries < WDIORETRIES_SINGLE ||
(bp->b_flags & B_MEDIA_FUA) != 0)) {
xfer->c_bio.flags |= ATA_LBA48;
xfer->c_flags |= C_NCQ;
@@ -1856,7 +1856,7 @@
if (params.atap_cmd1_en & WDC_CMD1_CACHE)
*bitsp |= DKCACHE_WRITE;
- if (wd->drvp->drive_flags & (ATA_DRIVE_NCQ|ATA_DRIVE_WFUA))
+ if (WD_USE_NCQ(wd) || (wd->drvp->drive_flags & ATA_DRIVE_WFUA))
*bitsp |= DKCACHE_FUA;
return 0;
@@ -2315,3 +2315,84 @@
bp->b_resid = bp->b_bcount;
biodone(bp);
}
+
+static void
+wd_sysctl_attach(struct wd_softc *wd)
+{
+ const struct sysctlnode *node;
+ int error;
+
+ /* sysctl set-up */
+ if (sysctl_createv(&wd->nodelog, 0, NULL, &node,
+ 0, CTLTYPE_NODE, device_xname(wd->sc_dev),
+ SYSCTL_DESCR("wd driver settings"),
+ NULL, 0, NULL, 0,
+ CTL_HW, CTL_CREATE, CTL_EOL) != 0) {
+ aprint_error_dev(wd->sc_dev,
+ "could not create %s.%s sysctl node\n",
+ "hw", device_xname(wd->sc_dev));
+ return;
+ }
+
+ wd->drv_max_tags = ATA_MAX_OPENINGS;
+ if ((error = sysctl_createv(&wd->nodelog, 0, NULL, NULL,
+ CTLFLAG_READWRITE, CTLTYPE_INT, "max_tags",
+ SYSCTL_DESCR("max number of NCQ tags to use"),
+ NULL, 0, &wd->drv_max_tags, 0,
+ CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL))
+ != 0) {
+ aprint_error_dev(wd->sc_dev,
+ "could not create %s.%s.max_tags sysctl - error %d\n",
+ "hw", device_xname(wd->sc_dev), error);
+ return;
+ }
+
+ wd->drv_ncq = true;
+ if ((error = sysctl_createv(&wd->nodelog, 0, NULL, NULL,
+ CTLFLAG_READWRITE, CTLTYPE_BOOL, "use_ncq",
+ SYSCTL_DESCR("use NCQ if supported"),
+ NULL, 0, &wd->drv_ncq, 0,
+ CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL))
+ != 0) {
+ aprint_error_dev(wd->sc_dev,
+ "could not create %s.%s.use_ncq sysctl - error %d\n",
+ "hw", device_xname(wd->sc_dev), error);
+ return;
+ }
+
+#ifdef WD_CHAOS_MONKEY
+ wd->drv_chaos_freq = 0;
+ if ((error = sysctl_createv(&wd->nodelog, 0, NULL, NULL,
+ CTLFLAG_READWRITE, CTLTYPE_INT, "chaos_freq",
+ SYSCTL_DESCR("simulated bio read error rate"),
+ NULL, 0, &wd->drv_chaos_freq, 0,
+ CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL))
+ != 0) {
+ aprint_error_dev(wd->sc_dev,
+ "could not create %s.%s.chaos_freq sysctl - error %d\n",
+ "hw", device_xname(wd->sc_dev), error);
+ return;
+ }
+
+ wd->drv_chaos_cnt = 0;
+ if ((error = sysctl_createv(&wd->nodelog, 0, NULL, NULL,
+ CTLFLAG_READONLY, CTLTYPE_INT, "chaos_cnt",
+ SYSCTL_DESCR("number of processed bio reads"),
+ NULL, 0, &wd->drv_chaos_cnt, 0,
+ CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL))
+ != 0) {
+ aprint_error_dev(wd->sc_dev,
+ "could not create %s.%s.chaos_cnt sysctl - error %d\n",
+ "hw", device_xname(wd->sc_dev), error);
+ return;
+ }
+#endif
+
+}
+
+static void
+wd_sysctl_detach(struct wd_softc *wd)
+{
+ sysctl_teardown(&wd->nodelog);
+}
+
diff -r 98860e038f2f -r 08aa2ccb38f9 sys/dev/ata/wdvar.h
--- a/sys/dev/ata/wdvar.h Thu Sep 28 20:25:45 2017 +0000
+++ b/sys/dev/ata/wdvar.h Thu Sep 28 20:34:23 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: wdvar.h,v 1.43.4.8 2017/09/02 12:01:25 jdolecek Exp $ */
+/* $NetBSD: wdvar.h,v 1.43.4.9 2017/09/28 20:34:23 jdolecek Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -32,6 +32,7 @@
#endif
#include <sys/rndsource.h>
+#include <sys/sysctl.h>
struct wd_softc {
/* General disk infos */
@@ -68,6 +69,19 @@
u_int sc_bscount;
#endif
krndsource_t rnd_source;
+
+ /* Sysctl nodes specific for the disk */
+ struct sysctllog *nodelog;
+ int drv_max_tags;
+#define WD_MAX_OPENINGS(wd) \
+ (MAX(1, MIN((wd)->drvp->drv_openings, (wd)->drv_max_tags)))
+ bool drv_ncq;
+#define WD_USE_NCQ(wd) \
+ ((wd)->drv_ncq && ((wd)->drvp->drive_flags & ATA_DRIVE_NCQ))
+#ifdef WD_CHAOS_MONKEY
+ int drv_chaos_freq; /* frequency of simulated bio errors */
+ int drv_chaos_cnt; /* count of processed bio read xfers */
+#endif
};
#endif /* _DEV_ATA_WDVAR_H_ */
Home |
Main Index |
Thread Index |
Old Index