diff options
author | rrs <rrs@FreeBSD.org> | 2015-03-28 12:50:24 +0000 |
---|---|---|
committer | rrs <rrs@FreeBSD.org> | 2015-03-28 12:50:24 +0000 |
commit | 8e2d411633cbbb1a3ae9a9513be3a6d6d9a1ae77 (patch) | |
tree | f549ad26e7b3f0719ad8ebb38c56b86cfbeb39dd /sys/sys/callout.h | |
parent | f9990b7dcc91119bc54bb1064c8fb13c6fe71de7 (diff) | |
download | FreeBSD-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.h | 25 |
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); |