svn commit: r236358 - in projects/calloutng/sys: kern sys
Davide Italiano
davide at FreeBSD.org
Thu May 31 14:47:03 UTC 2012
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;
More information about the svn-src-projects
mailing list