summaryrefslogtreecommitdiffstats
path: root/sys/sys/callout.h
diff options
context:
space:
mode:
authorrrs <rrs@FreeBSD.org>2015-03-28 12:50:24 +0000
committerrrs <rrs@FreeBSD.org>2015-03-28 12:50:24 +0000
commit8e2d411633cbbb1a3ae9a9513be3a6d6d9a1ae77 (patch)
treef549ad26e7b3f0719ad8ebb38c56b86cfbeb39dd /sys/sys/callout.h
parentf9990b7dcc91119bc54bb1064c8fb13c6fe71de7 (diff)
downloadFreeBSD-src-8e2d411633cbbb1a3ae9a9513be3a6d6d9a1ae77.zip
FreeBSD-src-8e2d411633cbbb1a3ae9a9513be3a6d6d9a1ae77.tar.gz
Change the callout to supply -1 to indicate we are not changing
CPU, also add protection against invalid CPU's as well as split c_flags and c_iflags so that if a user plays with the active flag (the one expected to be played with by callers in MPSAFE) without a lock, it won't adversely affect the callout system by causing a corrupt list. This also means that all callers need to use the macros and *not* play with the falgs directly (like netgraph used to). Differential Revision: htts://reviews.freebsd.org/D1894 Reviewed by: .. timed out but looked at by jhb, imp, adrian hselasky tested by hiren and netflix. Sponsored by: Netflix Inc.
Diffstat (limited to 'sys/sys/callout.h')
-rw-r--r--sys/sys/callout.h25
1 files changed, 20 insertions, 5 deletions
diff --git a/sys/sys/callout.h b/sys/sys/callout.h
index 910d652..ba1c52f 100644
--- a/sys/sys/callout.h
+++ b/sys/sys/callout.h
@@ -63,8 +63,23 @@ struct callout_handle {
};
#ifdef _KERNEL
+/*
+ * Note the flags field is actually *two* fields. The c_flags
+ * field is the one that caller operations that may, or may not have
+ * a lock touches i.e. callout_deactivate(). The other, the c_iflags,
+ * is the internal flags that *must* be kept correct on which the
+ * callout system depend on i.e. callout_migrating() & callout_pending(),
+ * these are used internally by the callout system to determine which
+ * list and other critical internal state. Callers *should not* use the
+ * c_flags field directly but should use the macros!
+ *
+ * If the caller wants to keep the c_flags field sane they
+ * should init with a mutex *or* if using the older
+ * mpsafe option, they *must* lock there own lock
+ * before calling callout_deactivate().
+ */
#define callout_active(c) ((c)->c_flags & CALLOUT_ACTIVE)
-#define callout_migrating(c) ((c)->c_flags & CALLOUT_DFRMIGRATION)
+#define callout_migrating(c) ((c)->c_iflags & CALLOUT_DFRMIGRATION)
#define callout_deactivate(c) ((c)->c_flags &= ~CALLOUT_ACTIVE)
#define callout_drain(c) _callout_stop_safe(c, 1)
void callout_init(struct callout *, int);
@@ -78,11 +93,11 @@ void _callout_init_lock(struct callout *, struct lock_object *, int);
#define callout_init_rw(c, rw, flags) \
_callout_init_lock((c), ((rw) != NULL) ? &(rw)->lock_object : \
NULL, (flags))
-#define callout_pending(c) ((c)->c_flags & CALLOUT_PENDING)
+#define callout_pending(c) ((c)->c_iflags & CALLOUT_PENDING)
int callout_reset_sbt_on(struct callout *, sbintime_t, sbintime_t,
void (*)(void *), void *, int, int);
#define callout_reset_sbt(c, sbt, pr, fn, arg, flags) \
- callout_reset_sbt_on((c), (sbt), (pr), (fn), (arg), (c)->c_cpu, (flags))
+ callout_reset_sbt_on((c), (sbt), (pr), (fn), (arg), -1, (flags))
#define callout_reset_sbt_curcpu(c, sbt, pr, fn, arg, flags) \
callout_reset_sbt_on((c), (sbt), (pr), (fn), (arg), PCPU_GET(cpuid),\
(flags))
@@ -90,14 +105,14 @@ int callout_reset_sbt_on(struct callout *, sbintime_t, sbintime_t,
callout_reset_sbt_on((c), tick_sbt * (to_ticks), 0, (fn), (arg), \
(cpu), C_HARDCLOCK)
#define callout_reset(c, on_tick, fn, arg) \
- callout_reset_on((c), (on_tick), (fn), (arg), (c)->c_cpu)
+ callout_reset_on((c), (on_tick), (fn), (arg), -1)
#define callout_reset_curcpu(c, on_tick, fn, arg) \
callout_reset_on((c), (on_tick), (fn), (arg), PCPU_GET(cpuid))
#define callout_schedule_sbt_on(c, sbt, pr, cpu, flags) \
callout_reset_sbt_on((c), (sbt), (pr), (c)->c_func, (c)->c_arg, \
(cpu), (flags))
#define callout_schedule_sbt(c, sbt, pr, flags) \
- callout_schedule_sbt_on((c), (sbt), (pr), (c)->c_cpu, (flags))
+ callout_schedule_sbt_on((c), (sbt), (pr), -1, (flags))
#define callout_schedule_sbt_curcpu(c, sbt, pr, flags) \
callout_schedule_sbt_on((c), (sbt), (pr), PCPU_GET(cpuid), (flags))
int callout_schedule(struct callout *, int);
OpenPOWER on IntegriCloud