Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/scsipi The atapibus detach path did hold the channel...



details:   https://anonhg.NetBSD.org/src/rev/18591fdb4aa6
branches:  trunk
changeset: 824780:18591fdb4aa6
user:      mlelstv <mlelstv%NetBSD.org@localhost>
date:      Sat Jun 17 22:35:50 2017 +0000

description:
The atapibus detach path did hold the channel mutex while calling into autoconf,
which would trigger a panic when unplugging a USB ATAPI CDROM.

Align detach code for scsibus and atapibus to fix this.

Also avoid races when detaching devices by replacing callout_stop with
callout_halt.

diffstat:

 sys/dev/scsipi/atapiconf.c   |  43 +++++++++++++++----------------------------
 sys/dev/scsipi/cd.c          |   6 +++---
 sys/dev/scsipi/scsi_base.c   |  14 ++++++++++++--
 sys/dev/scsipi/scsiconf.c    |  34 +++++-----------------------------
 sys/dev/scsipi/scsipi_base.c |  24 +++++++++++++++++++-----
 sys/dev/scsipi/sd.c          |   6 +++---
 sys/dev/scsipi/ss.c          |   6 +++---
 sys/dev/scsipi/st.c          |   6 +++---
 8 files changed, 63 insertions(+), 76 deletions(-)

diffs (truncated from 359 to 300 lines):

diff -r f3bd0156a4b2 -r 18591fdb4aa6 sys/dev/scsipi/atapiconf.c
--- a/sys/dev/scsipi/atapiconf.c        Sat Jun 17 22:06:54 2017 +0000
+++ b/sys/dev/scsipi/atapiconf.c        Sat Jun 17 22:35:50 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: atapiconf.c,v 1.90 2016/11/29 03:23:00 mlelstv Exp $   */
+/*     $NetBSD: atapiconf.c,v 1.91 2017/06/17 22:35:50 mlelstv Exp $   */
 
 /*
  * Copyright (c) 1996, 2001 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: atapiconf.c,v 1.90 2016/11/29 03:23:00 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: atapiconf.c,v 1.91 2017/06/17 22:35:50 mlelstv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -147,6 +147,7 @@
        sc->sc_dev = self;
 
        chan->chan_name = device_xname(sc->sc_dev);
+       chan->chan_id = -1;
 
        /* ATAPI has no LUNs. */
        chan->chan_nluns = 1;
@@ -192,39 +193,28 @@
        mutex_exit(chan_mtx(chan));
 }
 
+/* same as scsibusdetach */
 static int
 atapibusdetach(device_t self, int flags)
 {
        struct atapibus_softc *sc = device_private(self);
        struct scsipi_channel *chan = sc->sc_channel;
-       struct scsipi_periph *periph;
-       int target, error = 0;
+       int error = 0;
+
+       /*
+        * Detach all of the periphs.
+        */
+       error = scsipi_target_detach(chan, -1, -1, flags);
+       if (error)
+               return error;
+
+       pmf_device_deregister(self);
 
        /*
         * Shut down the channel.
         */
        scsipi_channel_shutdown(chan);
 
-       /* for config_detach() */
-       KERNEL_LOCK(1, curlwp);
-
-       /*
-        * Now detach all of the periphs.
-        */
-       mutex_enter(chan_mtx(chan));
-       for (target = 0; target < chan->chan_ntargets; target++) {
-               periph = scsipi_lookup_periph_locked(chan, target, 0);
-               if (periph == NULL)
-                       continue;
-               error = config_detach(periph->periph_dev, flags);
-               if (error) {
-                       mutex_exit(chan_mtx(chan));
-                       goto out;
-               }
-               KASSERT(scsipi_lookup_periph(chan, target, 0) == NULL);
-       }
-       mutex_exit(chan_mtx(chan));
-
        cv_destroy(&chan->chan_cv_xs);
        cv_destroy(&chan->chan_cv_comp);
        cv_destroy(&chan->chan_cv_thr);
@@ -232,10 +222,7 @@
        if (atomic_dec_uint_nv(&chan_running(chan)) == 0)
                mutex_destroy(chan_mtx(chan));
 
-out:
-       /* XXXSMP scsipi */
-       KERNEL_UNLOCK_ONE(curlwp);
-       return error;
+       return 0;
 }
 
 static int
diff -r f3bd0156a4b2 -r 18591fdb4aa6 sys/dev/scsipi/cd.c
--- a/sys/dev/scsipi/cd.c       Sat Jun 17 22:06:54 2017 +0000
+++ b/sys/dev/scsipi/cd.c       Sat Jun 17 22:35:50 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cd.c,v 1.340 2017/04/08 13:50:23 mlelstv Exp $ */
+/*     $NetBSD: cd.c,v 1.341 2017/06/17 22:35:50 mlelstv Exp $ */
 
 /*-
  * Copyright (c) 1998, 2001, 2003, 2004, 2005, 2008 The NetBSD Foundation,
@@ -50,7 +50,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cd.c,v 1.340 2017/04/08 13:50:23 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cd.c,v 1.341 2017/06/17 22:35:50 mlelstv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -354,7 +354,7 @@
        }
 
        /* kill any pending restart */
-       callout_stop(&cd->sc_callout);
+       callout_halt(&cd->sc_callout, NULL);
 
        dk_drain(dksc);
 
diff -r f3bd0156a4b2 -r 18591fdb4aa6 sys/dev/scsipi/scsi_base.c
--- a/sys/dev/scsipi/scsi_base.c        Sat Jun 17 22:06:54 2017 +0000
+++ b/sys/dev/scsipi/scsi_base.c        Sat Jun 17 22:35:50 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: scsi_base.c,v 1.91 2016/11/20 15:37:19 mlelstv Exp $   */
+/*     $NetBSD: scsi_base.c,v 1.92 2017/06/17 22:35:50 mlelstv Exp $   */
 
 /*-
  * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: scsi_base.c,v 1.91 2016/11/20 15:37:19 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: scsi_base.c,v 1.92 2017/06/17 22:35:50 mlelstv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -116,6 +116,16 @@
 void
 scsi_kill_pending(struct scsipi_periph *periph)
 {
+       struct scsipi_xfer *xs;
+
+       TAILQ_FOREACH(xs, &periph->periph_xferq, device_q) {
+               callout_stop(&xs->xs_callout);
+               scsi_print_addr(periph);
+               printf("killed ");
+               scsipi_print_cdb(xs->cmd);
+               xs->error = XS_DRIVER_STUFFUP;
+               scsipi_done(xs);
+       }
 }
 
 /*
diff -r f3bd0156a4b2 -r 18591fdb4aa6 sys/dev/scsipi/scsiconf.c
--- a/sys/dev/scsipi/scsiconf.c Sat Jun 17 22:06:54 2017 +0000
+++ b/sys/dev/scsipi/scsiconf.c Sat Jun 17 22:35:50 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: scsiconf.c,v 1.279 2017/03/18 08:05:40 tsutsui Exp $   */
+/*     $NetBSD: scsiconf.c,v 1.280 2017/06/17 22:35:50 mlelstv Exp $   */
 
 /*-
  * Copyright (c) 1998, 1999, 2004 The NetBSD Foundation, Inc.
@@ -48,7 +48,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: scsiconf.c,v 1.279 2017/03/18 08:05:40 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: scsiconf.c,v 1.280 2017/06/17 22:35:50 mlelstv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -333,43 +333,19 @@
 {
        struct scsibus_softc *sc = device_private(self);
        struct scsipi_channel *chan = sc->sc_channel;
-       struct scsipi_periph *periph;
-       int ctarget, clun;
-       struct scsipi_xfer *xs;
        int error;
 
        /*
         * Detach all of the periphs.
         */
-       if ((error = scsipi_target_detach(chan, -1, -1, flags)) != 0)
+       error = scsipi_target_detach(chan, -1, -1, flags);
+       if (error)
                return error;
 
        pmf_device_deregister(self);
 
        /*
-        * Process outstanding commands (which will never complete as the
-        * controller is gone).
-        *
-        * XXX Surely this is redundant?  If we get this far, the
-        * XXX peripherals have all been detached.
-        */
-       for (ctarget = 0; ctarget < chan->chan_ntargets; ctarget++) {
-               if (ctarget == chan->chan_id)
-                       continue;
-               for (clun = 0; clun < chan->chan_nluns; clun++) {
-                       periph = scsipi_lookup_periph(chan, ctarget, clun);
-                       if (periph == NULL)
-                               continue;
-                       TAILQ_FOREACH(xs, &periph->periph_xferq, device_q) {
-                               callout_stop(&xs->xs_callout);
-                               xs->error = XS_DRIVER_STUFFUP;
-                               scsipi_done(xs);
-                       }
-               }
-       }
-
-       /*
-        * Now shut down the channel.
+        * Shut down the channel.
         */
        scsipi_channel_shutdown(chan);
 
diff -r f3bd0156a4b2 -r 18591fdb4aa6 sys/dev/scsipi/scsipi_base.c
--- a/sys/dev/scsipi/scsipi_base.c      Sat Jun 17 22:06:54 2017 +0000
+++ b/sys/dev/scsipi/scsipi_base.c      Sat Jun 17 22:35:50 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: scsipi_base.c,v 1.175 2016/12/22 11:19:21 mlelstv Exp $        */
+/*     $NetBSD: scsipi_base.c,v 1.176 2017/06/17 22:35:50 mlelstv Exp $        */
 
 /*-
  * Copyright (c) 1998, 1999, 2000, 2002, 2003, 2004 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: scsipi_base.c,v 1.175 2016/12/22 11:19:21 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: scsipi_base.c,v 1.176 2017/06/17 22:35:50 mlelstv Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_scsi.h"
@@ -2400,6 +2400,7 @@
     int flags)
 {
        struct scsipi_periph *periph;
+       device_t tdev;
        int ctarget, mintarget, maxtarget;
        int clun, minlun, maxlun;
        int error;
@@ -2426,19 +2427,32 @@
                maxlun = lun + 1;
        }
 
+       /* for config_detach */
+       KERNEL_LOCK(1, curlwp);
+
+       mutex_enter(chan_mtx(chan));
        for (ctarget = mintarget; ctarget < maxtarget; ctarget++) {
                if (ctarget == chan->chan_id)
                        continue;
 
                for (clun = minlun; clun < maxlun; clun++) {
-                       periph = scsipi_lookup_periph(chan, ctarget, clun);
+                       periph = scsipi_lookup_periph_locked(chan, ctarget, clun);
                        if (periph == NULL)
                                continue;
-                       error = config_detach(periph->periph_dev, flags);
+                       tdev = periph->periph_dev;
+                       mutex_exit(chan_mtx(chan));
+                       error = config_detach(tdev, flags);
                        if (error)
-                               return error;
+                               goto out;
+                       mutex_enter(chan_mtx(chan));
+                       KASSERT(scsipi_lookup_periph_locked(chan, ctarget, clun) == NULL);
                }
        }
+       mutex_exit(chan_mtx(chan));
+
+out:
+       KERNEL_UNLOCK_ONE(curlwp);
+
        return 0;
 }
 
diff -r f3bd0156a4b2 -r 18591fdb4aa6 sys/dev/scsipi/sd.c
--- a/sys/dev/scsipi/sd.c       Sat Jun 17 22:06:54 2017 +0000
+++ b/sys/dev/scsipi/sd.c       Sat Jun 17 22:35:50 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sd.c,v 1.324 2017/04/10 18:20:43 jdolecek Exp $        */
+/*     $NetBSD: sd.c,v 1.325 2017/06/17 22:35:50 mlelstv Exp $ */
 
 /*-
  * Copyright (c) 1998, 2003, 2004 The NetBSD Foundation, Inc.
@@ -47,7 +47,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sd.c,v 1.324 2017/04/10 18:20:43 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sd.c,v 1.325 2017/06/17 22:35:50 mlelstv Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_scsi.h"
@@ -385,7 +385,7 @@
        }
 
        /* kill any pending restart */



Home | Main Index | Thread Index | Old Index