Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/jdolecek-ncqfixes]: src/sys/dev/ata remove explicit ata_channel_start() ...
details: https://anonhg.NetBSD.org/src/rev/74875c16264a
branches: jdolecek-ncqfixes
changeset: 1025081:74875c16264a
user: jdolecek <jdolecek%NetBSD.org@localhost>
date: Sat Sep 22 17:50:09 2018 +0000
description:
remove explicit ata_channel_start() calls, it's no longer necessary
now that ata_xfer's are allocated via pool and not really limited;
replace by just a callout to restart the processing for rare cases
where system runs out of memory
diffstat:
sys/dev/ata/TODO.ncq | 2 -
sys/dev/ata/ata_subr.c | 52 +------------------------------------------------
sys/dev/ata/atavar.h | 4 +--
sys/dev/ata/wd.c | 40 ++++++++++++++++++--------------------
sys/dev/ata/wdvar.h | 3 +-
5 files changed, 24 insertions(+), 77 deletions(-)
diffs (264 lines):
diff -r e123de37688a -r 74875c16264a sys/dev/ata/TODO.ncq
--- a/sys/dev/ata/TODO.ncq Sat Sep 22 16:14:25 2018 +0000
+++ b/sys/dev/ata/TODO.ncq Sat Sep 22 17:50:09 2018 +0000
@@ -1,6 +1,4 @@
jdolecek-ncqfixes goals:
-- add to wd(4) a callout to restart buf queue processing when ata_get_xfer()
- call fails and remove ata_channel_start()
- re-fix QEMU ahci(4) bug workaround (no READ LOG EXT support) - now it
triggers KASSERT()
- fix ahci(4) error handling under paralles - invalid bio via WD_CHAOS_MONKEY
diff -r e123de37688a -r 74875c16264a sys/dev/ata/ata_subr.c
--- a/sys/dev/ata/ata_subr.c Sat Sep 22 16:14:25 2018 +0000
+++ b/sys/dev/ata/ata_subr.c Sat Sep 22 17:50:09 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ata_subr.c,v 1.6.2.5 2018/09/22 09:22:59 jdolecek Exp $ */
+/* $NetBSD: ata_subr.c,v 1.6.2.6 2018/09/22 17:50:09 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.5 2018/09/22 09:22:59 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata_subr.c,v 1.6.2.6 2018/09/22 17:50:09 jdolecek Exp $");
#include "opt_ata.h"
@@ -257,54 +257,6 @@
splx(s);
}
-/*
- * Must be called without any locks, i.e. with both drive and channel locks
- * released.
- */
-void
-ata_channel_start(struct ata_channel *chp, int drive, bool start_self)
-{
- int i, s;
- struct ata_drive_datas *drvp;
-
- s = splbio();
-
- KASSERT(chp->ch_ndrives > 0);
-
-#define ATA_DRIVE_START(chp, drive) \
- do { \
- KASSERT(drive < chp->ch_ndrives); \
- drvp = &chp->ch_drive[drive]; \
- \
- if (drvp->drive_type != ATA_DRIVET_ATA && \
- drvp->drive_type != ATA_DRIVET_ATAPI && \
- drvp->drive_type != ATA_DRIVET_OLD) \
- continue; \
- \
- if (drvp->drv_start != NULL) \
- (*drvp->drv_start)(drvp->drv_softc); \
- } while (0)
-
- /*
- * Process drives in round robin fashion starting with next one after
- * the one which finished transfer. Thus no single drive would
- * completely starve other drives on same channel.
- * This loop processes all but the current drive, so won't do anything
- * if there is only one drive in channel.
- */
- for (i = (drive + 1) % chp->ch_ndrives; i != drive;
- i = (i + 1) % chp->ch_ndrives) {
- ATA_DRIVE_START(chp, i);
- }
-
- /* Now try to kick off xfers on the current drive */
- if (start_self)
- ATA_DRIVE_START(chp, drive);
-
- splx(s);
-#undef ATA_DRIVE_START
-}
-
void
ata_channel_lock(struct ata_channel *chp)
{
diff -r e123de37688a -r 74875c16264a sys/dev/ata/atavar.h
--- a/sys/dev/ata/atavar.h Sat Sep 22 16:14:25 2018 +0000
+++ b/sys/dev/ata/atavar.h Sat Sep 22 17:50:09 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: atavar.h,v 1.99.2.6 2018/09/22 16:14:25 jdolecek Exp $ */
+/* $NetBSD: atavar.h,v 1.99.2.7 2018/09/22 17:50:09 jdolecek Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -327,7 +327,6 @@
/* Callbacks into the drive's driver. */
void (*drv_done)(device_t, struct ata_xfer *); /* xfer is done */
- void (*drv_start)(device_t); /* start queue */
device_t drv_softc; /* ATA drives softc, if any */
struct ata_channel *chnl_softc; /* channel softc */
@@ -547,7 +546,6 @@
void ata_reset_channel(struct ata_channel *, int);
void ata_channel_freeze(struct ata_channel *);
void ata_channel_thaw(struct ata_channel *);
-void ata_channel_start(struct ata_channel *, int, bool);
void ata_channel_lock(struct ata_channel *);
void ata_channel_unlock(struct ata_channel *);
void ata_channel_lock_owned(struct ata_channel *);
diff -r e123de37688a -r 74875c16264a sys/dev/ata/wd.c
--- a/sys/dev/ata/wd.c Sat Sep 22 16:14:25 2018 +0000
+++ b/sys/dev/ata/wd.c Sat Sep 22 17:50:09 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: wd.c,v 1.441.2.5 2018/09/22 16:14:25 jdolecek Exp $ */
+/* $NetBSD: wd.c,v 1.441.2.6 2018/09/22 17:50:09 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.5 2018/09/22 16:14:25 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.441.2.6 2018/09/22 17:50:09 jdolecek Exp $");
#include "opt_ata.h"
#include "opt_wd.h"
@@ -192,7 +192,7 @@
static struct wd_ioctl *wi_get(struct wd_softc *);
static void wdioctlstrategy(struct buf *);
-static void wdstart(device_t);
+static void wdrestart(void *);
static void wdstart1(struct wd_softc *, struct buf *, struct ata_xfer *);
static int wd_diskstart(device_t, struct buf *);
static int wd_dumpblocks(device_t, void *, daddr_t, int);
@@ -324,7 +324,6 @@
wd->drvp = adev->adev_drv_data;
wd->drvp->drv_openings = 1;
- wd->drvp->drv_start = wdstart;
wd->drvp->drv_done = wddone;
wd->drvp->drv_softc = dksc->sc_dev; /* done in atabusconfig_thread()
but too late */
@@ -333,6 +332,7 @@
SLIST_INIT(&wd->sc_requeue_list);
callout_init(&wd->sc_retry_callout, 0); /* XXX MPSAFE */
callout_init(&wd->sc_requeue_callout, 0); /* XXX MPSAFE */
+ callout_init(&wd->sc_restart_diskqueue, 0); /* XXX MPSAFE */
aprint_naive("\n");
aprint_normal("\n");
@@ -527,6 +527,8 @@
callout_destroy(&wd->sc_retry_callout);
callout_halt(&wd->sc_requeue_callout, &wd->sc_lock);
callout_destroy(&wd->sc_requeue_callout);
+ callout_halt(&wd->sc_restart_diskqueue, &wd->sc_lock);
+ callout_destroy(&wd->sc_restart_diskqueue);
mutex_exit(&wd->sc_lock);
@@ -749,6 +751,17 @@
if (xfer == NULL) {
ATADEBUG_PRINT(("wd_diskstart %s no xfer\n",
dksc->sc_xname), DEBUG_XFERS);
+
+ /*
+ * No available memory, retry later. This happens very rarely
+ * and only under memory pressure, so wait relatively long
+ * before retry.
+ */
+ if (!callout_pending(&wd->sc_restart_diskqueue)) {
+ callout_reset(&wd->sc_restart_diskqueue, hz / 2,
+ wdrestart, dev);
+ }
+
mutex_exit(&wd->sc_lock);
return EAGAIN;
}
@@ -764,8 +777,9 @@
* Queue a drive for I/O.
*/
static void
-wdstart(device_t self)
+wdrestart(void *x)
{
+ device_t self = x;
struct wd_softc *wd = device_private(self);
struct dk_softc *dksc = &wd->sc_dksc;
@@ -919,7 +933,6 @@
ata_free_xfer(wd->drvp->chnl_softc, xfer);
dk_done(dksc, bp);
- ata_channel_start(wd->drvp->chnl_softc, wd->drvp->drive, true);
}
static void
@@ -1687,7 +1700,6 @@
out:
ata_free_xfer(wd->drvp->chnl_softc, xfer);
- ata_channel_start(wd->drvp->chnl_softc, wd->drvp->drive, true);
return error;
}
@@ -1729,13 +1741,6 @@
out:
ata_free_xfer(wd->drvp->chnl_softc, xfer);
-
- /*
- * Drive is supposed to go idle, start only other drives.
- * bufq might be actually already freed at this moment.
- */
- ata_channel_start(wd->drvp->chnl_softc, wd->drvp->drive, false);
-
return error;
}
@@ -1792,10 +1797,6 @@
out_xfer:
ata_free_xfer(wd->drvp->chnl_softc, xfer);
-
- /* start again I/O processing possibly stopped due to no xfer */
- ata_channel_start(wd->drvp->chnl_softc, wd->drvp->drive, start_self);
-
return error;
}
@@ -1855,7 +1856,6 @@
out:
ata_free_xfer(wd->drvp->chnl_softc, xfer);
- ata_channel_start(wd->drvp->chnl_softc, wd->drvp->drive, true);
return error;
}
@@ -2062,8 +2062,6 @@
out:
ata_free_xfer(wi->wi_softc->drvp->chnl_softc, xfer);
- ata_channel_start(wi->wi_softc->drvp->chnl_softc,
- wi->wi_softc->drvp->drive, true);
out2:
bp->b_error = error;
if (error)
diff -r e123de37688a -r 74875c16264a sys/dev/ata/wdvar.h
--- a/sys/dev/ata/wdvar.h Sat Sep 22 16:14:25 2018 +0000
+++ b/sys/dev/ata/wdvar.h Sat Sep 22 17:50:09 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: wdvar.h,v 1.46.6.3 2018/09/22 16:14:25 jdolecek Exp $ */
+/* $NetBSD: wdvar.h,v 1.46.6.4 2018/09/22 17:50:09 jdolecek Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -67,6 +67,7 @@
/* Retry/requeue failed transfers */
SLIST_HEAD(, ata_xfer) sc_retry_list;
struct callout sc_retry_callout; /* retry callout handle */
+ struct callout sc_restart_diskqueue; /* restart queue processing */
SLIST_HEAD(, ata_xfer) sc_requeue_list;
struct callout sc_requeue_callout; /* requeue callout handle */
Home |
Main Index |
Thread Index |
Old Index