Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev Allow for draining/adjusting the queue.



details:   https://anonhg.NetBSD.org/src/rev/b209f62a2d8b
branches:  trunk
changeset: 503279:b209f62a2d8b
user:      ad <ad%NetBSD.org@localhost>
date:      Sun Feb 04 17:15:37 2001 +0000

description:
Allow for draining/adjusting the queue.

diffstat:

 sys/dev/ld.c    |  68 +++++++++++++++++++++++++++++++++++++++++---------------
 sys/dev/ldvar.h |  12 +++++----
 2 files changed, 56 insertions(+), 24 deletions(-)

diffs (167 lines):

diff -r c7b57076332d -r b209f62a2d8b sys/dev/ld.c
--- a/sys/dev/ld.c      Sun Feb 04 17:05:11 2001 +0000
+++ b/sys/dev/ld.c      Sun Feb 04 17:15:37 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ld.c,v 1.6 2001/01/08 06:57:21 itojun Exp $    */
+/*     $NetBSD: ld.c,v 1.7 2001/02/04 17:15:37 ad Exp $        */
 
 /*-
  * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@@ -83,15 +83,16 @@
 {
        char buf[9];
 
+       if ((sc->sc_flags & LDF_ENABLED) == 0) {
+               printf("%s: disabled\n", sc->sc_dv.dv_xname);
+               return;
+       }
+
        /* Initialise and attach the disk structure. */
        sc->sc_dk.dk_driver = &lddkdriver;
        sc->sc_dk.dk_name = sc->sc_dv.dv_xname;
        disk_attach(&sc->sc_dk);
 
-       if ((sc->sc_flags & LDF_ENABLED) == 0) {
-               printf("%s: disabled\n", sc->sc_dv.dv_xname);
-               return;
-       }
        if (sc->sc_maxxfer > MAXPHYS)
                sc->sc_maxxfer = MAXPHYS;
 
@@ -114,28 +115,55 @@
 }
 
 int
-lddrain(struct ld_softc *sc, int flags)
+ldadjqparam(struct ld_softc *sc, int max)
 {
-       int s;
+       int s, rv;
+
+       s = splbio();
+       sc->sc_maxqueuecnt = max;
+       if (sc->sc_queuecnt > max) {
+               sc->sc_flags |= LDF_DRAIN;
+               rv = tsleep(&sc->sc_queuecnt, PRIBIO, "lddrn", 30 * hz);
+               sc->sc_flags &= ~LDF_DRAIN;
+       } else
+               rv = 0;
+       splx(s);
+
+       return (rv);
+}
+
+int
+ldbegindetach(struct ld_softc *sc, int flags)
+{
+       int s, rv;
+
+       if ((sc->sc_flags & LDF_ENABLED) == 0)
+               return (0);
 
        if ((flags & DETACH_FORCE) == 0 && sc->sc_dk.dk_openmask != 0)
                return (EBUSY);
 
        s = splbio();
-       sc->sc_flags |= LDF_DRAIN;
+       sc->sc_flags |= LDF_DETACH;
+       rv = ldadjqparam(sc, 0);
        splx(s);
-       return (0);
+
+       return (rv);
 }
 
 void
-lddetach(struct ld_softc *sc)
+ldenddetach(struct ld_softc *sc)
 {
        struct buf *bp;
        int s, bmaj, cmaj, mn;
 
+       if ((sc->sc_flags & LDF_ENABLED) == 0)
+               return;
+
        /* Wait for commands queued with the hardware to complete. */
        if (sc->sc_queuecnt != 0)
-               tsleep(&sc->sc_queuecnt, PRIBIO, "lddrn", 30 * hz);
+               if (tsleep(&sc->sc_queuecnt, PRIBIO, "lddtch", 30 * hz))
+                       printf("%s: not drained\n", sc->sc_dv.dv_xname);
 
        /* Locate the major numbers. */
        for (bmaj = 0; bmaj <= nblkdev; bmaj++)
@@ -388,7 +416,7 @@
        sc = device_lookup(&ld_cd, DISKUNIT(bp->b_dev));
 
        s = splbio();
-       if (sc->sc_queuecnt == sc->sc_maxqueuecnt) {
+       if (sc->sc_queuecnt >= sc->sc_maxqueuecnt) {
                BUFQ_INSERT_TAIL(&sc->sc_bufq, bp);
                splx(s);
                return;
@@ -403,7 +431,7 @@
        struct disklabel *lp;
        int part, s, rv;
 
-       if ((sc->sc_flags & LDF_DRAIN) != 0) {
+       if ((sc->sc_flags & LDF_DETACH) != 0) {
                bp->b_error = EIO;
                bp->b_flags |= B_ERROR;
                bp->b_resid = bp->b_bcount;
@@ -488,13 +516,15 @@
        rnd_add_uint32(&sc->sc_rnd_source, bp->b_rawblkno);
 #endif
        biodone(bp);
-       if (--sc->sc_queuecnt == 0 && (sc->sc_flags & LDF_DRAIN) != 0)
-               wakeup(&sc->sc_queuecnt);
 
-       while ((bp = BUFQ_FIRST(&sc->sc_bufq)) != NULL) {
-               BUFQ_REMOVE(&sc->sc_bufq, bp);
-               if (!ldstart(sc, bp))
-                       break;
+       if (--sc->sc_queuecnt <= sc->sc_maxqueuecnt) {
+               if ((sc->sc_flags & LDF_DRAIN) != 0)
+                       wakeup(&sc->sc_queuecnt);
+               while ((bp = BUFQ_FIRST(&sc->sc_bufq)) != NULL) {
+                       BUFQ_REMOVE(&sc->sc_bufq, bp);
+                       if (!ldstart(sc, bp))
+                               break;
+               }
        }
 }
 
diff -r c7b57076332d -r b209f62a2d8b sys/dev/ldvar.h
--- a/sys/dev/ldvar.h   Sun Feb 04 17:05:11 2001 +0000
+++ b/sys/dev/ldvar.h   Sun Feb 04 17:15:37 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ldvar.h,v 1.3 2001/01/03 21:01:28 ad Exp $     */
+/*     $NetBSD: ldvar.h,v 1.4 2001/02/04 17:15:37 ad Exp $     */
 
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -58,7 +58,7 @@
        int     sc_nsectors;                    /* # sectors per track */
        int     sc_secsize;                     /* sector size in bytes */
        int     sc_maxxfer;                     /* max xfer size in bytes */
-       int     sc_maxqueuecnt;                 /* maximum h/w queue count */
+       int     sc_maxqueuecnt;         /* maximum h/w queue count */
 
        int     (*sc_dump)(struct ld_softc *, void *, int, int);
        int     (*sc_flush)(struct ld_softc *);
@@ -70,11 +70,13 @@
 #define        LDF_LKWANTED    0x04            /* lock wanted */
 #define        LDF_WLABEL      0x08            /* label is writable */
 #define        LDF_LABELLING   0x10            /* writing label */
-#define        LDF_DRAIN       0x20            /* detach pending */
+#define        LDF_DRAIN       0x20            /* maxqueuecnt has changed; drain */
+#define        LDF_DETACH      0x40            /* detach pending */
 
+int    ldadjqparam(struct ld_softc *, int);
 void   ldattach(struct ld_softc *);
-void   lddetach(struct ld_softc *);
+int    ldbegindetach(struct ld_softc *, int);
+void   ldenddetach(struct ld_softc *);
 void   lddone(struct ld_softc *, struct buf *);
-int    lddrain(struct ld_softc *, int);
 
 #endif /* !_DEV_LDVAR_H_ */



Home | Main Index | Thread Index | Old Index