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 convert to mutex, mark MPSAFE



details:   https://anonhg.NetBSD.org/src/rev/34a08e86f6a1
branches:  jdolecek-ncq
changeset: 822873:34a08e86f6a1
user:      jdolecek <jdolecek%NetBSD.org@localhost>
date:      Wed Apr 12 21:59:14 2017 +0000

description:
convert to mutex, mark MPSAFE

diffstat:

 sys/dev/ata/wd.c    |  110 ++++++++++++++++++++++++++-------------------------
 sys/dev/ata/wdvar.h |    6 ++-
 2 files changed, 61 insertions(+), 55 deletions(-)

diffs (truncated from 388 to 300 lines):

diff -r 5e8a53101afd -r 34a08e86f6a1 sys/dev/ata/wd.c
--- a/sys/dev/ata/wd.c  Tue Apr 11 18:15:03 2017 +0000
+++ b/sys/dev/ata/wd.c  Wed Apr 12 21:59:14 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: wd.c,v 1.428 2017/03/05 23:07:12 mlelstv Exp $ */
+/*     $NetBSD: wd.c,v 1.428.2.1 2017/04/12 21:59:14 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 2017/03/05 23:07:12 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.428.2.1 2017/04/12 21:59:14 jdolecek Exp $");
 
 #include "opt_ata.h"
 
@@ -150,7 +150,7 @@
        .d_dump = wddump,
        .d_psize = wdsize,
        .d_discard = wddiscard,
-       .d_flag = D_DISK
+       .d_flag = D_DISK | D_MPSAFE
 };
 
 const struct cdevsw wd_cdevsw = {
@@ -165,7 +165,7 @@
        .d_mmap = nommap,
        .d_kqfilter = nokqfilter,
        .d_discard = wddiscard,
-       .d_flag = D_DISK
+       .d_flag = D_DISK | D_MPSAFE
 };
 
 /*
@@ -181,11 +181,9 @@
        struct wd_softc *wi_softc;
 };
 
-LIST_HEAD(, wd_ioctl) wi_head;
-
 struct wd_ioctl *wi_find(struct buf *);
 void   wi_free(struct wd_ioctl *);
-struct wd_ioctl *wi_get(void);
+struct wd_ioctl *wi_get(struct wd_softc *);
 void   wdioctlstrategy(struct buf *);
 
 void  wdgetdefaultlabel(struct wd_softc *, struct disklabel *);
@@ -297,10 +295,12 @@
 
        ATADEBUG_PRINT(("wdattach\n"), DEBUG_FUNCS | DEBUG_PROBE);
        callout_init(&wd->sc_restart_ch, 0);
+       mutex_init(&wd->sc_lock, MUTEX_DEFAULT, IPL_BIO);
        bufq_alloc(&wd->sc_q, BUFQ_DISK_DEFAULT_STRAT, BUFQ_SORT_RAWBLOCK);
 #ifdef WD_SOFTBADSECT
        SLIST_INIT(&wd->sc_bslist);
 #endif
+       LIST_INIT(&wd->wi_head);
        wd->atabus = adev->adev_bustype;
        wd->openings = adev->adev_openings;
        wd->drvp = adev->adev_drv_data;
@@ -458,7 +458,7 @@
 wddetach(device_t self, int flags)
 {
        struct wd_softc *sc = device_private(self);
-       int bmaj, cmaj, i, mn, rc, s;
+       int bmaj, cmaj, i, mn, rc;
 
        if ((rc = disk_begindetach(&sc->sc_dk, wdlastclose, self, flags)) != 0)
                return rc;
@@ -477,7 +477,7 @@
        /* Delete all of our wedges. */
        dkwedge_delall(&sc->sc_dk);
 
-       s = splbio();
+       mutex_enter(&sc->sc_lock);
 
        /* Kill off any queued buffers. */
        bufq_drain(sc->sc_q);
@@ -486,7 +486,7 @@
        if (flags & DETACH_POWEROFF)
                wd_standby(sc, AT_POLL);
 
-       splx(s);
+       mutex_exit(&sc->sc_lock);
        bufq_free(sc->sc_q);
 
        /* Detach disk. */
@@ -502,6 +502,7 @@
        }
        sc->sc_bscount = 0;
 #endif
+       KASSERT(LIST_EMPTY(&sc->wi_head));
 
        pmf_device_deregister(self);
 
@@ -527,7 +528,6 @@
            device_lookup_private(&wd_cd, WDUNIT(bp->b_dev));
        struct disklabel *lp = wd->sc_dk.dk_label;
        daddr_t blkno;
-       int s;
 
        ATADEBUG_PRINT(("wdstrategy (%s)\n", device_xname(wd->sc_dev)),
            DEBUG_XFERS);
@@ -604,11 +604,11 @@
 #endif
 
        /* Queue transfer on drive, activate drive and controller if idle. */
-       s = splbio();
+       mutex_enter(&wd->sc_lock);
        disk_wait(&wd->sc_dk);
        bufq_put(wd->sc_q, bp);
        wdstart(wd);
-       splx(s);
+       mutex_exit(&wd->sc_lock);
        return;
 done:
        /* Toss transfer; we're done early. */
@@ -651,9 +651,8 @@
 wd_split_mod15_write(struct buf *bp)
 {
        struct buf *obp = bp->b_private;
-       struct wd_softc *sc =
+       struct wd_softc *wd =
            device_lookup_private(&wd_cd, DISKUNIT(obp->b_dev));
-       int s;
 
        if (__predict_false(bp->b_error != 0)) {
                /*
@@ -681,26 +680,28 @@
        bp->b_cflags = obp->b_cflags;
        bp->b_data = (char *)bp->b_data + bp->b_bcount;
        bp->b_blkno += (bp->b_bcount / DEV_BSIZE);
-       bp->b_rawblkno += (bp->b_bcount / sc->sc_blksize);
-       s = splbio();
-       wdstart1(sc, bp);
-       splx(s);
+       bp->b_rawblkno += (bp->b_bcount / wd->sc_blksize);
+       mutex_enter(&wd->sc_lock);
+       wdstart1(wd, bp);
+       mutex_exit(&wd->sc_lock);
        return;
 
  done:
        obp->b_error = bp->b_error;
        obp->b_resid = bp->b_resid;
-       s = splbio();
+       mutex_enter(&wd->sc_lock);
        putiobuf(bp);
        biodone(obp);
-       sc->openings++;
-       splx(s);
+       wd->openings++;
+       mutex_exit(&wd->sc_lock);
        /* wddone() will call wdstart() */
 }
 
 void
 wdstart1(struct wd_softc *wd, struct buf *bp)
 {
+       /* already locked */
+       KASSERT(mutex_owned(&wd->sc_lock));
 
        /*
         * Deal with the "split mod15 write" quirk.  We just divide the
@@ -716,7 +717,6 @@
                            ((bp->b_bcount / 512) % 15) == 1)) {
                struct buf *nbp;
 
-               /* already at splbio */
                nbp = getiobuf(NULL, false);
                if (__predict_false(nbp == NULL)) {
                        /* No memory -- fail the iop. */
@@ -757,6 +757,7 @@
        wd->sc_wdc_bio.blkdone =0;
        KASSERT(bp == wd->sc_bp || wd->sc_bp == NULL);
        wd->sc_bp = bp;
+
        /*
         * If we're retrying, retry in single-sector mode. This will give us
         * the sector number of the problem, and will eventually allow the
@@ -899,13 +900,12 @@
 {
        struct wd_softc *wd = v;
        struct buf *bp = wd->sc_bp;
-       int s;
 
        ATADEBUG_PRINT(("wdrestart %s\n", device_xname(wd->sc_dev)),
            DEBUG_XFERS);
-       s = splbio();
+       mutex_enter(&wd->sc_lock);
        wdstart1(v, bp);
-       splx(s);
+       mutex_exit(&wd->sc_lock);
 }
 
 static void
@@ -1125,7 +1125,6 @@
 {
        struct disklabel *lp = wd->sc_dk.dk_label;
        const char *errstring;
-       int s;
 
        ATADEBUG_PRINT(("wdgetdisklabel\n"), DEBUG_FUNCS);
 
@@ -1136,9 +1135,9 @@
        wd->sc_badsect[0] = -1;
 
        if (wd->drvp->state > RESET) {
-               s = splbio();
+               mutex_enter(&wd->sc_lock);
                wd->drvp->drive_flags |= ATA_DRIVE_RESET;
-               splx(s);
+               mutex_exit(&wd->sc_lock);
        }
        errstring = readdisklabel(MAKEWDDEV(0, device_unit(wd->sc_dev),
                                  RAW_PART), wdstrategy, lp,
@@ -1151,9 +1150,9 @@
                 * again.  XXX This is a kluge.
                 */
                if (wd->drvp->state > RESET) {
-                       s = splbio();
+                       mutex_enter(&wd->sc_lock);
                        wd->drvp->drive_flags |= ATA_DRIVE_RESET;
-                       splx(s);
+                       mutex_exit(&wd->sc_lock);
                }
                errstring = readdisklabel(MAKEWDDEV(0, device_unit(wd->sc_dev),
                    RAW_PART), wdstrategy, lp, wd->sc_dk.dk_cpulabel);
@@ -1164,9 +1163,9 @@
        }
 
        if (wd->drvp->state > RESET) {
-               s = splbio();
+               mutex_enter(&wd->sc_lock);
                wd->drvp->drive_flags |= ATA_DRIVE_RESET;
-               splx(s);
+               mutex_exit(&wd->sc_lock);
        }
 #ifdef HAS_BAD144_HANDLING
        if ((lp->d_flags & D_BADSECT) != 0)
@@ -1218,7 +1217,7 @@
 {
        struct wd_softc *wd =
            device_lookup_private(&wd_cd, WDUNIT(dev));
-       int error, s;
+       int error;
 #ifdef __HAVE_OLD_DISKLABEL
        struct disklabel *newlabel = NULL;
 #endif
@@ -1331,9 +1330,9 @@
                    wd->sc_dk.dk_cpulabel);
                if (error == 0) {
                        if (wd->drvp->state > RESET) {
-                               s = splbio();
+                               mutex_enter(&wd->sc_lock);
                                wd->drvp->drive_flags |= ATA_DRIVE_RESET;
-                               splx(s);
+                               mutex_exit(&wd->sc_lock);
                        }
                        if (xfer == DIOCWDINFO
 #ifdef __HAVE_OLD_DISKLABEL
@@ -1434,8 +1433,7 @@
                atareq_t *atareq = (atareq_t *) addr;
                int error1;
 
-               wi = wi_get();
-               wi->wi_softc = wd;
+               wi = wi_get(wd);
                wi->wi_atareq = *atareq;
 
                if (atareq->datalen && atareq->flags &
@@ -1487,10 +1485,10 @@
            {
                struct disk_strategy *dks = (void *)addr;
 
-               s = splbio();
+               mutex_enter(&wd->sc_lock);
                strlcpy(dks->dks_name, bufq_getstrategyname(wd->sc_q),
                    sizeof(dks->dks_name));
-               splx(s);
+               mutex_exit(&wd->sc_lock);
                dks->dks_paramlen = 0;
 
                return 0;
@@ -1514,11 +1512,11 @@
                if (error) {
                        return error;
                }
-               s = splbio();
+               mutex_enter(&wd->sc_lock);
                old = wd->sc_q;
                bufq_move(new, old);
                wd->sc_q = new;
-               splx(s);
+               mutex_exit(&wd->sc_lock);
                bufq_free(old);
 
                return 0;



Home | Main Index | Thread Index | Old Index