Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/ata The NCQ support added a private request queue to...



details:   https://anonhg.NetBSD.org/src/rev/b6ff8ebe5e52
branches:  trunk
changeset: 449751:b6ff8ebe5e52
user:      mlelstv <mlelstv%NetBSD.org@localhost>
date:      Tue Mar 19 16:56:29 2019 +0000

description:
The NCQ support added a private request queue to the wd driver. This
makes the regular buffer queue ineffective, it also allowed to queue
an unlimited number of requests.

Fix this by limiting the number of requests queued to the driver to
the possible number of concurrent NCQ transactions.

diffstat:

 sys/dev/ata/wd.c |  25 ++++++++++++++++++++++---
 1 files changed, 22 insertions(+), 3 deletions(-)

diffs (71 lines):

diff -r 53ba1d73b0e4 -r b6ff8ebe5e52 sys/dev/ata/wd.c
--- a/sys/dev/ata/wd.c  Tue Mar 19 16:45:28 2019 +0000
+++ b/sys/dev/ata/wd.c  Tue Mar 19 16:56:29 2019 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: wd.c,v 1.445 2019/03/19 06:51:05 mlelstv Exp $ */
+/*     $NetBSD: wd.c,v 1.446 2019/03/19 16:56:29 mlelstv 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.445 2019/03/19 06:51:05 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.446 2019/03/19 16:56:29 mlelstv Exp $");
 
 #include "opt_ata.h"
 #include "opt_wd.h"
@@ -321,6 +321,7 @@
        SLIST_INIT(&wd->sc_bslist);
 #endif
        wd->atabus = adev->adev_bustype;
+       wd->inflight = 0;
        wd->drvp = adev->adev_drv_data;
 
        wd->drvp->drv_openings = 1;
@@ -729,6 +730,7 @@
                xfer->c_bio.flags |= ATA_FUA;
        }
 
+       wd->inflight++;
        switch (wd->atabus->ata_bio(wd->drvp, xfer)) {
        case ATACMD_TRY_AGAIN:
                panic("wdstart1: try again");
@@ -749,10 +751,25 @@
        struct dk_softc *dksc = &wd->sc_dksc;
 #endif
        struct ata_xfer *xfer;
+       struct ata_channel *chp;
+       unsigned openings;
 
        mutex_enter(&wd->sc_lock);
 
-       xfer = ata_get_xfer(wd->drvp->chnl_softc, false);
+       chp = wd->drvp->chnl_softc;
+
+       ata_channel_lock(chp);
+       openings = ata_queue_openings(chp);
+       ata_channel_unlock(chp);
+
+       openings = uimin(openings, wd->drvp->drv_openings);
+
+       if (wd->inflight >= openings) {
+               mutex_exit(&wd->sc_lock);
+               return EAGAIN;
+       }
+
+       xfer = ata_get_xfer(chp, false);
        if (xfer == NULL) {
                ATADEBUG_PRINT(("wd_diskstart %s no xfer\n",
                    dksc->sc_xname), DEBUG_XFERS);
@@ -952,7 +969,9 @@
 
        ata_free_xfer(wd->drvp->chnl_softc, xfer);
 
+       wd->inflight--;
        dk_done(dksc, bp);
+       dk_start(dksc, NULL);
 }
 
 static void



Home | Main Index | Thread Index | Old Index