Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 10 May 2012 10:02:57 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r235220 - in stable/9/sys: kern sys
Message-ID:  <201205101002.q4AA2v4u027767@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Thu May 10 10:02:56 2012
New Revision: 235220
URL: http://svn.freebsd.org/changeset/base/235220

Log:
  MFC r234952:
  Mark the migrating callouts with CALLOUT_DFRMIGRATION flag. The flag is
  cleared by callout_stop_safe() when the function detects a migration,
  besides returning the success. The softclock() rechecks the flag for
  migrating callout and cancels its execution if the flag was cleared
  meantime.
  
  PR:	misc/166340

Modified:
  stable/9/sys/kern/kern_timeout.c
  stable/9/sys/sys/callout.h
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/kern/kern_timeout.c
==============================================================================
--- stable/9/sys/kern/kern_timeout.c	Thu May 10 09:47:04 2012	(r235219)
+++ stable/9/sys/kern/kern_timeout.c	Thu May 10 10:02:56 2012	(r235220)
@@ -645,6 +645,32 @@ softclock(void *arg)
 					cc_cme_cleanup(cc);
 
 					/*
+					 * Handle deferred callout stops
+					 */
+					if ((c->c_flags & CALLOUT_DFRMIGRATION)
+					    == 0) {
+						CTR3(KTR_CALLOUT,
+					"deferred cancelled %p func %p arg %p",
+						    c, new_func, new_arg);
+						if (cc->cc_next == c) {
+							cc->cc_next =
+							    TAILQ_NEXT(c,
+							    c_links.tqe);
+						}
+						if (c->c_flags &
+						    CALLOUT_LOCAL_ALLOC) {
+							c->c_func = NULL;
+							SLIST_INSERT_HEAD(
+							    &cc->cc_callfree, c,
+							    c_links.sle);
+						}
+						goto nextc;
+					} else {
+						c->c_flags &= ~
+						    CALLOUT_DFRMIGRATION;
+					}
+
+					/*
 					 * It should be assert here that the
 					 * callout is not destroyed but that
 					 * is not easy.
@@ -659,6 +685,9 @@ softclock(void *arg)
 					panic("migration should not happen");
 #endif
 				}
+#ifdef SMP
+nextc:
+#endif
 				steps = 0;
 				c = cc->cc_next;
 			}
@@ -814,6 +843,7 @@ callout_reset_on(struct callout *c, int 
 			cc->cc_migration_ticks = to_ticks;
 			cc->cc_migration_func = ftn;
 			cc->cc_migration_arg = arg;
+			c->c_flags |= CALLOUT_DFRMIGRATION;
 			CTR5(KTR_CALLOUT,
 		    "migration of %p func %p arg %p in %d to %u deferred",
 			    c, c->c_func, c->c_arg, to_ticks, cpu);
@@ -984,6 +1014,12 @@ again:
 			CC_UNLOCK(cc);
 			KASSERT(!sq_locked, ("sleepqueue chain locked"));
 			return (1);
+		} else if ((c->c_flags & CALLOUT_DFRMIGRATION) != 0) {
+			c->c_flags &= ~CALLOUT_DFRMIGRATION;
+			CTR3(KTR_CALLOUT, "postponing stop %p func %p arg %p",
+			    c, c->c_func, c->c_arg);
+			CC_UNLOCK(cc);
+			return (1);
 		}
 		CTR3(KTR_CALLOUT, "failed to stop %p func %p arg %p",
 		    c, c->c_func, c->c_arg);

Modified: stable/9/sys/sys/callout.h
==============================================================================
--- stable/9/sys/sys/callout.h	Thu May 10 09:47:04 2012	(r235219)
+++ stable/9/sys/sys/callout.h	Thu May 10 10:02:56 2012	(r235220)
@@ -46,6 +46,7 @@
 #define	CALLOUT_MPSAFE		0x0008 /* callout handler is mp safe */
 #define	CALLOUT_RETURNUNLOCKED	0x0010 /* handler returns with mtx unlocked */
 #define	CALLOUT_SHAREDLOCK	0x0020 /* callout lock held in shared mode */
+#define	CALLOUT_DFRMIGRATION	0x0040 /* callout in deferred migration mode */
 
 struct callout_handle {
 	struct callout *callout;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201205101002.q4AA2v4u027767>