Date: Wed, 20 Jul 2016 16:44:22 +0000 (UTC) From: Gleb Smirnoff <glebius@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r303096 - head/sys/kern Message-ID: <201607201644.u6KGiM3e007023@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: glebius Date: Wed Jul 20 16:44:22 2016 New Revision: 303096 URL: https://svnweb.freebsd.org/changeset/base/303096 Log: Revert r303037. It re-introduces the panic with TCP timers. Agreed by: rrs, re (gjb) Modified: head/sys/kern/kern_timeout.c Modified: head/sys/kern/kern_timeout.c ============================================================================== --- head/sys/kern/kern_timeout.c Wed Jul 20 16:36:17 2016 (r303095) +++ head/sys/kern/kern_timeout.c Wed Jul 20 16:44:22 2016 (r303096) @@ -1050,7 +1050,7 @@ callout_reset_sbt_on(struct callout *c, */ if (c->c_lock != NULL && !cc_exec_cancel(cc, direct)) cancelled = cc_exec_cancel(cc, direct) = true; - if (cc_exec_waiting(cc, direct) || cc_exec_drain(cc, direct)) { + if (cc_exec_waiting(cc, direct)) { /* * Someone has called callout_drain to kill this * callout. Don't reschedule. @@ -1166,7 +1166,7 @@ _callout_stop_safe(struct callout *c, in struct callout_cpu *cc, *old_cc; struct lock_class *class; int direct, sq_locked, use_lock; - int not_on_a_list; + int cancelled, not_on_a_list; if ((flags & CS_DRAIN) != 0) WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, c->c_lock, @@ -1234,47 +1234,17 @@ again: panic("migration should not happen"); #endif } - if ((drain != NULL) && (c->c_iflags & CALLOUT_PENDING) && - (cc_exec_curr(cc, direct) != c)) { - /* - * This callout is executing and we are draining. - * The only way this can happen is if its also - * been rescheduled to run on one thread *and* asked to drain - * on this thread (at the same time it is waiting to execute). - */ - if ((c->c_iflags & CALLOUT_PROCESSED) == 0) { - if (cc_exec_next(cc) == c) - cc_exec_next(cc) = LIST_NEXT(c, c_links.le); - LIST_REMOVE(c, c_links.le); - } else { - TAILQ_REMOVE(&cc->cc_expireq, c, c_links.tqe); - } - c->c_iflags &= ~CALLOUT_PENDING; - c->c_flags &= ~CALLOUT_ACTIVE; - } + /* - * If the callout isn't pending, it's not on the queue, so - * don't attempt to remove it from the queue. We can try to - * stop it by other means however. + * If the callout is running, try to stop it or drain it. */ - if (!(c->c_iflags & CALLOUT_PENDING)) { + if (cc_exec_curr(cc, direct) == c) { /* - * If it wasn't on the queue and it isn't the current - * callout, then we can't stop it, so just bail. - * It probably has already been run (if locking - * is properly done). You could get here if the caller - * calls stop twice in a row for example. The second - * call would fall here without CALLOUT_ACTIVE set. + * Succeed we to stop it or not, we must clear the + * active flag - this is what API users expect. */ c->c_flags &= ~CALLOUT_ACTIVE; - if (cc_exec_curr(cc, direct) != c) { - CTR3(KTR_CALLOUT, "failed to stop %p func %p arg %p", - c, c->c_func, c->c_arg); - CC_UNLOCK(cc); - if (sq_locked) - sleepq_release(&cc_exec_waiting(cc, direct)); - return (-1); - } + if ((flags & CS_DRAIN) != 0) { /* * The current callout is running (or just @@ -1308,6 +1278,7 @@ again: old_cc = cc; goto again; } + /* * Migration could be cancelled here, but * as long as it is still not sure when it @@ -1391,8 +1362,6 @@ again: cc_exec_drain(cc, direct) = drain; } CC_UNLOCK(cc); - if (drain) - return(0); return ((flags & CS_EXECUTING) != 0); } CTR3(KTR_CALLOUT, "failed to stop %p func %p arg %p", @@ -1400,13 +1369,21 @@ again: if (drain) { cc_exec_drain(cc, direct) = drain; } - CC_UNLOCK(cc); KASSERT(!sq_locked, ("sleepqueue chain still locked")); - return (0); - } + cancelled = ((flags & CS_EXECUTING) != 0); + } else + cancelled = 1; + if (sq_locked) sleepq_release(&cc_exec_waiting(cc, direct)); + if ((c->c_iflags & CALLOUT_PENDING) == 0) { + CTR3(KTR_CALLOUT, "failed to stop %p func %p arg %p", + c, c->c_func, c->c_arg); + CC_UNLOCK(cc); + return (0); + } + c->c_iflags &= ~CALLOUT_PENDING; c->c_flags &= ~CALLOUT_ACTIVE; @@ -1423,7 +1400,7 @@ again: } callout_cc_del(c, cc); CC_UNLOCK(cc); - return (1); + return (cancelled); } void @@ -1638,6 +1615,7 @@ SYSCTL_PROC(_kern, OID_AUTO, callout_sta CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 0, sysctl_kern_callout_stat, "I", "Dump immediate statistic snapshot of the scheduled callouts"); + #ifdef DDB static void _show_callout(struct callout *c)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201607201644.u6KGiM3e007023>