svn commit: r296913 - in releng/10.3/sys: kern sys

Konstantin Belousov kib at FreeBSD.org
Tue Mar 15 17:09:29 UTC 2016


Author: kib
Date: Tue Mar 15 17:09:27 2016
New Revision: 296913
URL: https://svnweb.freebsd.org/changeset/base/296913

Log:
  MFC r296320:
  Adjust _callout_stop_safe() return value for the subr_sleepqueue.c needs
  when migrating callout was blocked, but running one was not.
  
  PR:	200992
  Approved by:	re (marius)

Modified:
  releng/10.3/sys/kern/kern_timeout.c
  releng/10.3/sys/kern/subr_sleepqueue.c
  releng/10.3/sys/sys/callout.h
Directory Properties:
  releng/10.3/   (props changed)

Modified: releng/10.3/sys/kern/kern_timeout.c
==============================================================================
--- releng/10.3/sys/kern/kern_timeout.c	Tue Mar 15 17:06:40 2016	(r296912)
+++ releng/10.3/sys/kern/kern_timeout.c	Tue Mar 15 17:09:27 2016	(r296913)
@@ -1114,9 +1114,9 @@ callout_schedule(struct callout *c, int 
 }
 
 int
-_callout_stop_safe(c, safe)
+_callout_stop_safe(c, flags)
 	struct	callout *c;
-	int	safe;
+	int	flags;
 {
 	struct callout_cpu *cc, *old_cc;
 	struct lock_class *class;
@@ -1127,7 +1127,7 @@ _callout_stop_safe(c, safe)
 	 * Some old subsystems don't hold Giant while running a callout_stop(),
 	 * so just discard this check for the moment.
 	 */
-	if (!safe && c->c_lock != NULL) {
+	if ((flags & CS_DRAIN) == 0 && c->c_lock != NULL) {
 		if (c->c_lock == &Giant.lock_object)
 			use_lock = mtx_owned(&Giant);
 		else {
@@ -1207,7 +1207,7 @@ again:
 			return (0);
 		}
 
-		if (safe) {
+		if ((flags & CS_DRAIN) != 0) {
 			/*
 			 * The current callout is running (or just
 			 * about to run) and blocking is allowed, so
@@ -1319,7 +1319,7 @@ again:
 			CTR3(KTR_CALLOUT, "postponing stop %p func %p arg %p",
 			    c, c->c_func, c->c_arg);
 			CC_UNLOCK(cc);
-			return (0);
+			return ((flags & CS_MIGRBLOCK) != 0);
 		}
 		CTR3(KTR_CALLOUT, "failed to stop %p func %p arg %p",
 		    c, c->c_func, c->c_arg);

Modified: releng/10.3/sys/kern/subr_sleepqueue.c
==============================================================================
--- releng/10.3/sys/kern/subr_sleepqueue.c	Tue Mar 15 17:06:40 2016	(r296912)
+++ releng/10.3/sys/kern/subr_sleepqueue.c	Tue Mar 15 17:09:27 2016	(r296913)
@@ -572,7 +572,8 @@ sleepq_check_timeout(void)
 	 * another CPU, so synchronize with it to avoid having it
 	 * accidentally wake up a subsequent sleep.
 	 */
-	else if (callout_stop(&td->td_slpcallout) == 0) {
+	else if (_callout_stop_safe(&td->td_slpcallout, CS_MIGRBLOCK)
+	    == 0) {
 		td->td_flags |= TDF_TIMEOUT;
 		TD_SET_SLEEPING(td);
 		mi_switch(SW_INVOL | SWT_SLEEPQTIMO, NULL);

Modified: releng/10.3/sys/sys/callout.h
==============================================================================
--- releng/10.3/sys/sys/callout.h	Tue Mar 15 17:06:40 2016	(r296912)
+++ releng/10.3/sys/sys/callout.h	Tue Mar 15 17:09:27 2016	(r296913)
@@ -62,6 +62,12 @@ struct callout_handle {
 	struct callout *callout;
 };
 
+/* Flags for callout_stop_safe() */
+#define	CS_DRAIN		0x0001 /* callout_drain(), wait allowed */
+#define	CS_MIGRBLOCK		0x0002 /* Block migration, return value
+					  indicates that the callout was
+				          executing */
+
 #ifdef _KERNEL
 /* 
  * Note the flags field is actually *two* fields. The c_flags
@@ -81,7 +87,7 @@ struct callout_handle {
  */
 #define	callout_active(c)	((c)->c_flags & CALLOUT_ACTIVE)
 #define	callout_deactivate(c)	((c)->c_flags &= ~CALLOUT_ACTIVE)
-#define	callout_drain(c)	_callout_stop_safe(c, 1)
+#define	callout_drain(c)	_callout_stop_safe(c, CS_DRAIN)
 void	callout_init(struct callout *, int);
 void	_callout_init_lock(struct callout *, struct lock_object *, int);
 #define	callout_init_mtx(c, mtx, flags)					\


More information about the svn-src-all mailing list