Module Name:    src
Committed By:   mlelstv
Date:           Sat Sep  1 07:20:29 UTC 2018

Modified Files:
        src/sys/dev/scsipi: scsiconf.c scsipiconf.h

Log Message:
Wait in detach if the discovery thread is still running. Avoids crashes
when a device is attached/detached rapidly.


To generate a diff of this commit:
cvs rdiff -u -r1.280 -r1.281 src/sys/dev/scsipi/scsiconf.c
cvs rdiff -u -r1.127 -r1.128 src/sys/dev/scsipi/scsipiconf.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/scsipi/scsiconf.c
diff -u src/sys/dev/scsipi/scsiconf.c:1.280 src/sys/dev/scsipi/scsiconf.c:1.281
--- src/sys/dev/scsipi/scsiconf.c:1.280	Sat Jun 17 22:35:50 2017
+++ src/sys/dev/scsipi/scsiconf.c	Sat Sep  1 07:20:29 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: scsiconf.c,v 1.280 2017/06/17 22:35:50 mlelstv Exp $	*/
+/*	$NetBSD: scsiconf.c,v 1.281 2018/09/01 07:20:29 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.280 2017/06/17 22:35:50 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: scsiconf.c,v 1.281 2018/09/01 07:20:29 mlelstv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -270,7 +270,7 @@ scsibusattach(device_t parent, device_t 
          * Create the discover thread
          */
         if (kthread_create(PRI_NONE, 0, NULL, scsibus_discover_thread, sc,
-            NULL, "%s-d", chan->chan_name)) {
+            &chan->chan_dthread, "%s-d", chan->chan_name)) {
                 aprint_error_dev(sc->sc_dev, "unable to create discovery "
 		    "thread for channel %d\n", chan->chan_channel);
                 return;
@@ -283,6 +283,7 @@ scsibus_discover_thread(void *arg)
 	struct scsibus_softc *sc = arg;
 
 	scsibus_config(sc);
+	sc->sc_channel->chan_dthread = NULL;
 	kthread_exit(0);
 }
 
@@ -336,6 +337,12 @@ scsibusdetach(device_t self, int flags)
 	int error;
 
 	/*
+	 * Defer while discovery thread is running
+	 */
+	while (chan->chan_dthread != NULL)
+		kpause("scsibusdet", false, hz, NULL);
+
+	/*
 	 * Detach all of the periphs.
 	 */
 	error = scsipi_target_detach(chan, -1, -1, flags);
@@ -415,6 +422,7 @@ scsi_probe_bus(struct scsibus_softc *sc,
 		 */
 		scsipi_set_xfer_mode(chan, target, 1);
 	}
+
 	scsipi_adapter_delref(chan->chan_adapter);
 ret:
 	return (error);

Index: src/sys/dev/scsipi/scsipiconf.h
diff -u src/sys/dev/scsipi/scsipiconf.h:1.127 src/sys/dev/scsipi/scsipiconf.h:1.128
--- src/sys/dev/scsipi/scsipiconf.h:1.127	Wed Jul  4 03:17:01 2018
+++ src/sys/dev/scsipi/scsipiconf.h	Sat Sep  1 07:20:29 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: scsipiconf.h,v 1.127 2018/07/04 03:17:01 kamil Exp $	*/
+/*	$NetBSD: scsipiconf.h,v 1.128 2018/09/01 07:20:29 mlelstv Exp $	*/
 
 /*-
  * Copyright (c) 1998, 1999, 2000, 2004 The NetBSD Foundation, Inc.
@@ -289,6 +289,7 @@ struct scsipi_channel {
 
 	int	chan_defquirks;		/* default device's quirks */
 
+	struct lwp *chan_dthread;	/* discovery thread */
 	struct lwp *chan_thread;	/* completion thread */
 	int	chan_tflags;		/* flags for the completion thread */
 

Reply via email to