Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 31 May 2012 14:47:02 +0000 (UTC)
From:      Davide Italiano <davide@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r236358 - in projects/calloutng/sys: kern sys
Message-ID:  <201205311447.q4VEl2kl048185@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: davide
Date: Thu May 31 14:47:02 2012
New Revision: 236358
URL: http://svn.freebsd.org/changeset/base/236358

Log:
  We need to figure out if the element we're trying to remove actually belongs
  to the tail queue of one of the buckets of the callwheel or to the tail queue
  introduced with r236315, to avoid random memory corruption and so some
  unpredictable behaviour.
  To avoid the entire scan of the two queues, a flag is added. This flags is
  set or cleared depending to the queues to which the element actually belongs.
  
  Discussed with:		mav

Modified:
  projects/calloutng/sys/kern/kern_timeout.c
  projects/calloutng/sys/sys/callout.h

Modified: projects/calloutng/sys/kern/kern_timeout.c
==============================================================================
--- projects/calloutng/sys/kern/kern_timeout.c	Thu May 31 14:46:02 2012	(r236357)
+++ projects/calloutng/sys/kern/kern_timeout.c	Thu May 31 14:47:02 2012	(r236358)
@@ -376,6 +376,7 @@ callout_tick(void)
 			if (bintime_cmp(&tmp->c_time,&now, <=)) {
 				TAILQ_INSERT_TAIL(cc->cc_localexp,tmp,c_staiter);
 				TAILQ_REMOVE(sc, tmp, c_links.tqe);
+				tmp->c_flags |= CALLOUT_PROCESSED;
 				need_softclock = 1;
 			}	
 		}
@@ -470,6 +471,7 @@ callout_cc_add(struct callout *c, struct
 	}
 	c->c_arg = arg;
 	c->c_flags |= (CALLOUT_ACTIVE | CALLOUT_PENDING);
+	c->c_flags &= ~CALLOUT_PROCESSED;
 	c->c_func = func;
 	c->c_time = to_bintime; 
 	bucket = get_bucket(&c->c_time);	
@@ -855,13 +857,19 @@ callout_reset_on(struct callout *c, int 
 		}
 	}
 	if (c->c_flags & CALLOUT_PENDING) {
-		if (cc->cc_next == c) {
-			cc->cc_next = TAILQ_NEXT(c, c_links.tqe);
+		if ((c->c_flags & CALLOUT_PROCESSED) == 0) {	
+			if (cc->cc_next == c)
+				cc->cc_next = TAILQ_NEXT(c, c_links.tqe);
+			bucket = get_bucket(&c->c_time);
+			TAILQ_REMOVE(&cc->cc_callwheel[bucket], c,
+			    c_links.tqe);
+		}
+		else {
+			if (cc->cc_next == c)
+				cc->cc_next = TAILQ_NEXT(c, c_staiter);
+			TAILQ_REMOVE(cc->cc_localexp, c, 
+			    c_staiter);
 		}
-		bucket = get_bucket(&c->c_time);	
-		TAILQ_REMOVE(&cc->cc_callwheel[bucket], c,
-		    c_links.tqe);
-
 		cancelled = 1;
 		c->c_flags &= ~(CALLOUT_ACTIVE | CALLOUT_PENDING);
 	}
@@ -1069,9 +1077,14 @@ again:
 
 	CTR3(KTR_CALLOUT, "cancelled %p func %p arg %p",
 	    c, c->c_func, c->c_arg);
-	bucket = get_bucket(&c->c_time);
-	TAILQ_REMOVE(&cc->cc_callwheel[bucket], c,
-	    c_links.tqe);
+	if ((c->c_flags & CALLOUT_PROCESSED) == 0) {
+		bucket = get_bucket(&c->c_time);
+		TAILQ_REMOVE(&cc->cc_callwheel[bucket], c,
+		    c_links.tqe);
+	}
+	else 
+		TAILQ_REMOVE(cc->cc_localexp, c, 
+		    c_staiter);
 	callout_cc_del(c, cc);
 
 	CC_UNLOCK(cc);

Modified: projects/calloutng/sys/sys/callout.h
==============================================================================
--- projects/calloutng/sys/sys/callout.h	Thu May 31 14:46:02 2012	(r236357)
+++ projects/calloutng/sys/sys/callout.h	Thu May 31 14:47:02 2012	(r236358)
@@ -47,6 +47,7 @@
 #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 */
+#define	CALLOUT_PROCESSED	0x0080 /* callout in wheel or processing list? */
 
 struct callout_handle {
 	struct callout *callout;



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