Module Name:    src
Committed By:   mlelstv
Date:           Sun Dec 18 13:59:14 UTC 2016

Modified Files:
        src/sys/dev/scsipi: scsipi_base.c

Log Message:
The mutex passed to cv_wait must also be held when calling cv_broadcast.
Also optimizing mutex handling in completion thread.

>From nick@.


To generate a diff of this commit:
cvs rdiff -u -r1.170 -r1.171 src/sys/dev/scsipi/scsipi_base.c

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/scsipi_base.c
diff -u src/sys/dev/scsipi/scsipi_base.c:1.170 src/sys/dev/scsipi/scsipi_base.c:1.171
--- src/sys/dev/scsipi/scsipi_base.c:1.170	Fri Dec 16 15:00:52 2016
+++ src/sys/dev/scsipi/scsipi_base.c	Sun Dec 18 13:59:14 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: scsipi_base.c,v 1.170 2016/12/16 15:00:52 mlelstv Exp $	*/
+/*	$NetBSD: scsipi_base.c,v 1.171 2016/12/18 13:59:14 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.170 2016/12/16 15:00:52 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: scsipi_base.c,v 1.171 2016/12/18 13:59:14 mlelstv Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_scsi.h"
@@ -1462,8 +1462,8 @@ scsipi_done(struct scsipi_xfer *xs)
 	 * completion queue, and wake up the completion thread.
 	 */
 	TAILQ_INSERT_TAIL(&chan->chan_complete, xs, channel_q);
-	mutex_exit(chan_mtx(chan));
 	cv_broadcast(chan_cv_complete(chan));
+	mutex_exit(chan_mtx(chan));
 
  out:
 	/*
@@ -2138,21 +2138,17 @@ scsipi_completion_thread(void *arg)
 
 	mutex_enter(chan_mtx(chan));
 	chan->chan_flags |= SCSIPI_CHAN_TACTIVE;
-	mutex_exit(chan_mtx(chan));
 	for (;;) {
-		mutex_enter(chan_mtx(chan));
 		xs = TAILQ_FIRST(&chan->chan_complete);
 		if (xs == NULL && chan->chan_tflags  == 0) {
 			/* nothing to do; wait */
 			cv_wait(chan_cv_complete(chan), chan_mtx(chan));
-			mutex_exit(chan_mtx(chan));
 			continue;
 		}
 		if (chan->chan_tflags & SCSIPI_CHANT_CALLBACK) {
 			/* call chan_callback from thread context */
 			chan->chan_tflags &= ~SCSIPI_CHANT_CALLBACK;
 			chan->chan_callback(chan, chan->chan_callback_arg);
-			mutex_exit(chan_mtx(chan));
 			continue;
 		}
 		if (chan->chan_tflags & SCSIPI_CHANT_GROWRES) {
@@ -2164,6 +2160,7 @@ scsipi_completion_thread(void *arg)
 			scsipi_channel_thaw(chan, 1);
 			if (chan->chan_tflags & SCSIPI_CHANT_GROWRES)
 				kpause("scsizzz", FALSE, hz/10, NULL);
+			mutex_enter(chan_mtx(chan));
 			continue;
 		}
 		if (chan->chan_tflags & SCSIPI_CHANT_KICK) {
@@ -2171,10 +2168,10 @@ scsipi_completion_thread(void *arg)
 			chan->chan_tflags &= ~SCSIPI_CHANT_KICK;
 			mutex_exit(chan_mtx(chan));
 			scsipi_run_queue(chan);
+			mutex_enter(chan_mtx(chan));
 			continue;
 		}
 		if (chan->chan_tflags & SCSIPI_CHANT_SHUTDOWN) {
-			mutex_exit(chan_mtx(chan));
 			break;
 		}
 		if (xs) {
@@ -2191,8 +2188,6 @@ scsipi_completion_thread(void *arg)
 			 * for some reason.
 			 */
 			scsipi_run_queue(chan);
-		} else {
-			mutex_exit(chan_mtx(chan));
 		}
 	}
 
@@ -2200,6 +2195,7 @@ scsipi_completion_thread(void *arg)
 
 	/* In case parent is waiting for us to exit. */
 	cv_broadcast(chan_cv_thread(chan));
+	mutex_exit(chan_mtx(chan));
 
 	kthread_exit(0);
 }

Reply via email to