diff options
| author | Alfred Perlstein <alfred@FreeBSD.org> | 2008-03-22 07:29:45 +0000 |
|---|---|---|
| committer | Alfred Perlstein <alfred@FreeBSD.org> | 2008-03-22 07:29:45 +0000 |
| commit | 435cdf88ea76245289e15e9b1d3136a835685c23 (patch) | |
| tree | b3443ae24c0f902b2465c50508b739835c6d3931 | |
| parent | 20b94d8035dc461dab17c4a27382fce7ac3cea58 (diff) | |
Notes
| -rw-r--r-- | sys/kern/kern_timeout.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/sys/kern/kern_timeout.c b/sys/kern/kern_timeout.c index 70d558c69cd5..679430ff79ba 100644 --- a/sys/kern/kern_timeout.c +++ b/sys/kern/kern_timeout.c @@ -230,11 +230,8 @@ softclock(void *dummy) c_arg = c->c_arg; c_flags = c->c_flags; if (c->c_flags & CALLOUT_LOCAL_ALLOC) { - c->c_func = NULL; c->c_flags = CALLOUT_LOCAL_ALLOC; - SLIST_INSERT_HEAD(&callfree, c, - c_links.sle); - curr_callout = NULL; + curr_callout = c; } else { c->c_flags = (c->c_flags & ~CALLOUT_PENDING); @@ -299,6 +296,24 @@ softclock(void *dummy) class->lc_unlock(c_lock); skip: mtx_lock_spin(&callout_lock); + /* + * If the current callout is locally + * allocated (from timeout(9)) + * then put it on the freelist. + * + * Note: we need to check the cached + * copy of c_flags because if it was not + * local, then it's not safe to deref the + * callout pointer. + */ + if (c_flags & CALLOUT_LOCAL_ALLOC) { + KASSERT(c->c_flags == + CALLOUT_LOCAL_ALLOC, + ("corrupted callout")); + c->c_func = NULL; + SLIST_INSERT_HEAD(&callfree, c, + c_links.sle); + } curr_callout = NULL; if (callout_wait) { /* |
