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>