svn commit: r192322 - in user/kmacy/releng_7_2_fcs/sys: kern sys

Kip Macy kmacy at FreeBSD.org
Mon May 18 18:34:03 UTC 2009


Author: kmacy
Date: Mon May 18 18:34:03 2009
New Revision: 192322
URL: http://svn.freebsd.org/changeset/base/192322

Log:
  Merge dependent callout changes
  
  171053
  172025
  172184
  173760
  173842
  176013

Modified:
  user/kmacy/releng_7_2_fcs/sys/kern/kern_timeout.c
  user/kmacy/releng_7_2_fcs/sys/sys/callout.h

Modified: user/kmacy/releng_7_2_fcs/sys/kern/kern_timeout.c
==============================================================================
--- user/kmacy/releng_7_2_fcs/sys/kern/kern_timeout.c	Mon May 18 18:12:45 2009	(r192321)
+++ user/kmacy/releng_7_2_fcs/sys/kern/kern_timeout.c	Mon May 18 18:34:03 2009	(r192322)
@@ -55,9 +55,9 @@ SYSCTL_INT(_debug, OID_AUTO, to_avg_dept
 static int avg_gcalls;
 SYSCTL_INT(_debug, OID_AUTO, to_avg_gcalls, CTLFLAG_RD, &avg_gcalls, 0,
     "Average number of Giant callouts made per softclock call. Units = 1/1000");
-static int avg_mtxcalls;
-SYSCTL_INT(_debug, OID_AUTO, to_avg_mtxcalls, CTLFLAG_RD, &avg_mtxcalls, 0,
-    "Average number of mtx callouts made per softclock call. Units = 1/1000");
+static int avg_lockcalls;
+SYSCTL_INT(_debug, OID_AUTO, to_avg_lockcalls, CTLFLAG_RD, &avg_lockcalls, 0,
+    "Average number of lock callouts made per softclock call. Units = 1/1000");
 static int avg_mpcalls;
 SYSCTL_INT(_debug, OID_AUTO, to_avg_mpcalls, CTLFLAG_RD, &avg_mpcalls, 0,
     "Average number of MP callouts made per softclock call. Units = 1/1000");
@@ -82,12 +82,12 @@ static struct callout *nextsoftcheck;	/*
  *                     If curr_callout is non-NULL, threads waiting in
  *                     callout_drain() will be woken up as soon as the 
  *                     relevant callout completes.
- *   curr_cancelled  - Changing to 1 with both callout_lock and c_mtx held
+ *   curr_cancelled  - Changing to 1 with both callout_lock and c_lock held
  *                     guarantees that the current callout will not run.
  *                     The softclock() function sets this to 0 before it
- *                     drops callout_lock to acquire c_mtx, and it calls
+ *                     drops callout_lock to acquire c_lock, and it calls
  *                     the handler only if curr_cancelled is still 0 after
- *                     c_mtx is successfully acquired.
+ *                     c_lock is successfully acquired.
  *   callout_wait    - If a thread is waiting in callout_drain(), then
  *                     callout_wait is nonzero.  Set only when
  *                     curr_callout is non-NULL.
@@ -170,7 +170,7 @@ softclock(void *dummy)
 	int steps;	/* #steps since we last allowed interrupts */
 	int depth;
 	int mpcalls;
-	int mtxcalls;
+	int lockcalls;
 	int gcalls;
 #ifdef DIAGNOSTIC
 	struct bintime bt1, bt2;
@@ -184,7 +184,7 @@ softclock(void *dummy)
 #endif /* MAX_SOFTCLOCK_STEPS */
 
 	mpcalls = 0;
-	mtxcalls = 0;
+	lockcalls = 0;
 	gcalls = 0;
 	depth = 0;
 	steps = 0;
@@ -215,14 +215,19 @@ softclock(void *dummy)
 			} else {
 				void (*c_func)(void *);
 				void *c_arg;
-				struct mtx *c_mtx;
-				int c_flags;
+				struct lock_class *class;
+				struct lock_object *c_lock;
+				int c_flags, sharedlock;
 
 				nextsoftcheck = TAILQ_NEXT(c, c_links.tqe);
 				TAILQ_REMOVE(bucket, c, c_links.tqe);
+				class = (c->c_lock != NULL) ?
+				    LOCK_CLASS(c->c_lock) : NULL;
+				sharedlock = (c->c_flags & CALLOUT_SHAREDLOCK) ?
+				    0 : 1;
+				c_lock = c->c_lock;
 				c_func = c->c_func;
 				c_arg = c->c_arg;
-				c_mtx = c->c_mtx;
 				c_flags = c->c_flags;
 				if (c->c_flags & CALLOUT_LOCAL_ALLOC) {
 					c->c_func = NULL;
@@ -237,27 +242,27 @@ softclock(void *dummy)
 				}
 				curr_cancelled = 0;
 				mtx_unlock_spin(&callout_lock);
-				if (c_mtx != NULL) {
-					mtx_lock(c_mtx);
+				if (c_lock != NULL) {
+					class->lc_lock(c_lock, sharedlock);
 					/*
 					 * The callout may have been cancelled
 					 * while we switched locks.
 					 */
 					if (curr_cancelled) {
-						mtx_unlock(c_mtx);
+						class->lc_unlock(c_lock);
 						goto skip;
 					}
 					/* The callout cannot be stopped now. */
 					curr_cancelled = 1;
 
-					if (c_mtx == &Giant) {
+					if (c_lock == &Giant.lock_object) {
 						gcalls++;
 						CTR3(KTR_CALLOUT,
 						    "callout %p func %p arg %p",
 						    c, c_func, c_arg);
 					} else {
-						mtxcalls++;
-						CTR3(KTR_CALLOUT, "callout mtx"
+						lockcalls++;
+						CTR3(KTR_CALLOUT, "callout lock"
 						    " %p func %p arg %p",
 						    c, c_func, c_arg);
 					}
@@ -292,7 +297,7 @@ softclock(void *dummy)
 #endif
 				CTR1(KTR_CALLOUT, "callout %p finished", c);
 				if ((c_flags & CALLOUT_RETURNUNLOCKED) == 0)
-					mtx_unlock(c_mtx);
+					class->lc_unlock(c_lock);
 			skip:
 				mtx_lock_spin(&callout_lock);
 				curr_callout = NULL;
@@ -313,7 +318,7 @@ softclock(void *dummy)
 	}
 	avg_depth += (depth * 1000 - avg_depth) >> 8;
 	avg_mpcalls += (mpcalls * 1000 - avg_mpcalls) >> 8;
-	avg_mtxcalls += (mtxcalls * 1000 - avg_mtxcalls) >> 8;
+	avg_lockcalls += (lockcalls * 1000 - avg_lockcalls) >> 8;
 	avg_gcalls += (gcalls * 1000 - avg_gcalls) >> 8;
 	nextsoftcheck = NULL;
 	mtx_unlock_spin(&callout_lock);
@@ -412,19 +417,14 @@ callout_reset(c, to_ticks, ftn, arg)
 {
 	int cancelled = 0;
 
-#ifdef notyet /* Some callers of timeout() do not hold Giant. */
-	if (c->c_mtx != NULL)
-		mtx_assert(c->c_mtx, MA_OWNED);
-#endif
-
 	mtx_lock_spin(&callout_lock);
 	if (c == curr_callout) {
 		/*
 		 * We're being asked to reschedule a callout which is
-		 * currently in progress.  If there is a mutex then we
+		 * currently in progress.  If there is a lock then we
 		 * can cancel the callout if it has not really started.
 		 */
-		if (c->c_mtx != NULL && !curr_cancelled)
+		if (c->c_lock != NULL && !curr_cancelled)
 			cancelled = curr_cancelled = 1;
 		if (callout_wait) {
 			/*
@@ -483,18 +483,23 @@ _callout_stop_safe(c, safe)
 	struct	callout *c;
 	int	safe;
 {
-	int use_mtx, sq_locked;
+	struct lock_class *class;
+	int use_lock, sq_locked;
 
-	if (!safe && c->c_mtx != NULL) {
-#ifdef notyet /* Some callers do not hold Giant for Giant-locked callouts. */
-		mtx_assert(c->c_mtx, MA_OWNED);
-		use_mtx = 1;
-#else
-		use_mtx = mtx_owned(c->c_mtx);
-#endif
-	} else {
-		use_mtx = 0;
-	}
+	/*
+	 * 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 (c->c_lock == &Giant.lock_object)
+			use_lock = mtx_owned(&Giant);
+		else {
+			use_lock = 1;
+			class = LOCK_CLASS(c->c_lock);
+			class->lc_assert(c->c_lock, LA_XLOCKED);
+		}
+	} else
+		use_lock = 0;
 
 	sq_locked = 0;
 again:
@@ -566,12 +571,12 @@ again:
 				PICKUP_GIANT();
 				mtx_lock_spin(&callout_lock);
 			}
-		} else if (use_mtx && !curr_cancelled) {
+		} else if (use_lock && !curr_cancelled) {
 			/*
-			 * The current callout is waiting for it's
-			 * mutex which we hold.  Cancel the callout
+			 * The current callout is waiting for its
+			 * lock which we hold.  Cancel the callout
 			 * and return.  After our caller drops the
-			 * mutex, the callout will be skipped in
+			 * lock, the callout will be skipped in
 			 * softclock().
 			 */
 			curr_cancelled = 1;
@@ -615,28 +620,30 @@ callout_init(c, mpsafe)
 {
 	bzero(c, sizeof *c);
 	if (mpsafe) {
-		c->c_mtx = NULL;
+		c->c_lock = NULL;
 		c->c_flags = CALLOUT_RETURNUNLOCKED;
 	} else {
-		c->c_mtx = &Giant;
+		c->c_lock = &Giant.lock_object;
 		c->c_flags = 0;
 	}
 }
 
 void
-callout_init_mtx(c, mtx, flags)
+_callout_init_lock(c, lock, flags)
 	struct	callout *c;
-	struct	mtx *mtx;
+	struct	lock_object *lock;
 	int flags;
 {
 	bzero(c, sizeof *c);
-	c->c_mtx = mtx;
-	KASSERT((flags & ~(CALLOUT_RETURNUNLOCKED)) == 0,
-	    ("callout_init_mtx: bad flags %d", flags));
-	/* CALLOUT_RETURNUNLOCKED makes no sense without a mutex. */
-	KASSERT(mtx != NULL || (flags & CALLOUT_RETURNUNLOCKED) == 0,
-	    ("callout_init_mtx: CALLOUT_RETURNUNLOCKED with no mutex"));
-	c->c_flags = flags & (CALLOUT_RETURNUNLOCKED);
+	c->c_lock = lock;
+	KASSERT((flags & ~(CALLOUT_RETURNUNLOCKED | CALLOUT_SHAREDLOCK)) == 0,
+	    ("callout_init_lock: bad flags %d", flags));
+	KASSERT(lock != NULL || (flags & CALLOUT_RETURNUNLOCKED) == 0,
+	    ("callout_init_lock: CALLOUT_RETURNUNLOCKED with no lock"));
+	KASSERT(lock == NULL || !(LOCK_CLASS(lock)->lc_flags &
+	    (LC_SPINLOCK | LC_SLEEPABLE)), ("%s: invalid lock class",
+	    __func__));
+	c->c_flags = flags & (CALLOUT_RETURNUNLOCKED | CALLOUT_SHAREDLOCK);
 }
 
 #ifdef APM_FIXUP_CALLTODO

Modified: user/kmacy/releng_7_2_fcs/sys/sys/callout.h
==============================================================================
--- user/kmacy/releng_7_2_fcs/sys/sys/callout.h	Mon May 18 18:12:45 2009	(r192321)
+++ user/kmacy/releng_7_2_fcs/sys/sys/callout.h	Mon May 18 18:34:03 2009	(r192322)
@@ -40,7 +40,7 @@
 
 #include <sys/queue.h>
 
-struct mtx;
+struct lock_object;
 
 SLIST_HEAD(callout_list, callout);
 TAILQ_HEAD(callout_tailq, callout);
@@ -53,7 +53,7 @@ struct callout {
 	int	c_time;				/* ticks to the event */
 	void	*c_arg;				/* function argument */
 	void	(*c_func)(void *);	/* function to call */
-	struct mtx *c_mtx;			/* mutex to lock */
+	struct lock_object *c_lock;		/* lock to handle */
 	int	c_flags;			/* state of this entry */
 };
 
@@ -62,6 +62,7 @@ struct callout {
 #define	CALLOUT_PENDING		0x0004 /* callout is waiting for timeout */
 #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 */
 
 struct callout_handle {
 	struct callout *callout;
@@ -79,7 +80,13 @@ extern struct mtx callout_lock;
 #define	callout_deactivate(c)	((c)->c_flags &= ~CALLOUT_ACTIVE)
 #define	callout_drain(c)	_callout_stop_safe(c, 1)
 void	callout_init(struct callout *, int);
-void	callout_init_mtx(struct callout *, struct mtx *, int);
+void	_callout_init_lock(struct callout *, struct lock_object *, int);
+#define	callout_init_mtx(c, mtx, flags)					\
+	_callout_init_lock((c), ((mtx) != NULL) ? &(mtx)->lock_object :	\
+	    NULL, (flags))
+#define	callout_init_rw(c, rw, flags)					\
+	_callout_init_lock((c), ((rw) != NULL) ? &(rw)->lock_object :	\
+	   NULL, (flags))
 #define	callout_pending(c)	((c)->c_flags & CALLOUT_PENDING)
 int	callout_reset(struct callout *, int, void (*)(void *), void *);
 #define	callout_stop(c)		_callout_stop_safe(c, 0)


More information about the svn-src-user mailing list