Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 20 Sep 2013 23:16:15 +0000 (UTC)
From:      Davide Italiano <davide@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r255747 - head/sys/kern
Message-ID:  <201309202316.r8KNGFeZ007194@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: davide
Date: Fri Sep 20 23:16:15 2013
New Revision: 255747
URL: http://svnweb.freebsd.org/changeset/base/255747

Log:
  Fix callout_init_rm() in the shared case, allocating storage for 'struct
  rm_priotracker' directly in the softclock thread. Now consumers can
  pass CALLOUT_SHAREDLOCK flag to callout initialization routine safely.
  The choice of the already existing flags  instead of special casing
  shared rmlocks is done to prevent consumer footshooting.
  
  Suggested by:	jhb
  Reviewed by:	jhb
  Approved by:	re (delphij)

Modified:
  head/sys/kern/kern_timeout.c

Modified: head/sys/kern/kern_timeout.c
==============================================================================
--- head/sys/kern/kern_timeout.c	Fri Sep 20 23:10:52 2013	(r255746)
+++ head/sys/kern/kern_timeout.c	Fri Sep 20 23:16:15 2013	(r255747)
@@ -597,11 +597,13 @@ softclock_call_cc(struct callout *c, str
 #endif
     int direct)
 {
+	struct rm_priotracker tracker;
 	void (*c_func)(void *);
 	void *c_arg;
 	struct lock_class *class;
 	struct lock_object *c_lock;
-	int c_flags, sharedlock;
+	uintptr_t lock_status;
+	int c_flags;
 #ifdef SMP
 	struct callout_cpu *new_cc;
 	void (*new_func)(void *);
@@ -620,7 +622,13 @@ softclock_call_cc(struct callout *c, str
 	    (CALLOUT_PENDING | CALLOUT_ACTIVE),
 	    ("softclock_call_cc: pend|act %p %x", c, c->c_flags));
 	class = (c->c_lock != NULL) ? LOCK_CLASS(c->c_lock) : NULL;
-	sharedlock = (c->c_flags & CALLOUT_SHAREDLOCK) ? 0 : 1;
+	lock_status = 0;
+	if (c->c_flags & CALLOUT_SHAREDLOCK) {
+		if (class == &lock_class_rm)
+			lock_status = (uintptr_t)&tracker;
+		else
+			lock_status = 1;
+	}
 	c_lock = c->c_lock;
 	c_func = c->c_func;
 	c_arg = c->c_arg;
@@ -633,7 +641,7 @@ softclock_call_cc(struct callout *c, str
 	cc->cc_exec_entity[direct].cc_cancel = false;
 	CC_UNLOCK(cc);
 	if (c_lock != NULL) {
-		class->lc_lock(c_lock, sharedlock);
+		class->lc_lock(c_lock, lock_status);
 		/*
 		 * The callout may have been cancelled
 		 * while we switched locks.



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