source: rtems-libbsd/freebsd/sys/sys/callout.h @ 6d9d7b1

5-freebsd-12
Last change on this file since 6d9d7b1 was 6d9d7b1, checked in by Sebastian Huber <sebastian.huber@…>, on Jul 26, 2018 at 12:12:46 PM

Critical bug fix for callouts

FreeBSD has two callout executors, one in software and one in hardware
interrupt context. In libbsd, all callouts are executed by the timer
server. Entirely remove the different execution contexts for libbsd.
Previously, this was not properly done which could result an invalid
callout_drain() sequence leading to system memory corruption.

  • Property mode set to 100644
File size: 6.6 KB
Line 
1/*-
2 * Copyright (c) 1990, 1993
3 *      The Regents of the University of California.  All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 *    may be used to endorse or promote products derived from this software
20 *    without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 *      @(#)callout.h   8.2 (Berkeley) 1/21/94
35 * $FreeBSD$
36 */
37
38#ifndef _SYS_CALLOUT_H_
39#define _SYS_CALLOUT_H_
40
41#include <sys/_callout.h>
42
43#define CALLOUT_LOCAL_ALLOC     0x0001 /* was allocated from callfree */
44#define CALLOUT_ACTIVE          0x0002 /* callout is currently active */
45#define CALLOUT_PENDING         0x0004 /* callout is waiting for timeout */
46#define CALLOUT_MPSAFE          0x0008 /* deprecated */
47#define CALLOUT_RETURNUNLOCKED  0x0010 /* handler returns with mtx unlocked */
48#define CALLOUT_SHAREDLOCK      0x0020 /* callout lock held in shared mode */
49#define CALLOUT_DFRMIGRATION    0x0040 /* callout in deferred migration mode */
50#define CALLOUT_PROCESSED       0x0080 /* callout in wheel or processing list? */
51#ifndef __rtems__
52#define CALLOUT_DIRECT          0x0100 /* allow exec from hw int context */
53#endif /* __rtems__ */
54
55#define C_DIRECT_EXEC           0x0001 /* direct execution of callout */
56#define C_PRELBITS              7
57#define C_PRELRANGE             ((1 << C_PRELBITS) - 1)
58#define C_PREL(x)               (((x) + 1) << 1)
59#define C_PRELGET(x)            (int)((((x) >> 1) & C_PRELRANGE) - 1)
60#define C_HARDCLOCK             0x0100 /* align to hardclock() calls */
61#define C_ABSOLUTE              0x0200 /* event time is absolute. */
62#define C_PRECALC               0x0400 /* event time is pre-calculated. */
63
64struct callout_handle {
65        struct callout *callout;
66};
67
68/* Flags for callout_stop_safe() */
69#define CS_DRAIN                0x0001 /* callout_drain(), wait allowed */
70#define CS_EXECUTING            0x0002 /* Positive return value indicates that
71                                          the callout was executing */
72
73#ifdef _KERNEL
74/*
75 * Note the flags field is actually *two* fields. The c_flags
76 * field is the one that caller operations that may, or may not have
77 * a lock touches i.e. callout_deactivate(). The other, the c_iflags,
78 * is the internal flags that *must* be kept correct on which the
79 * callout system depend on e.g. callout_pending().
80 * The c_iflag is used internally by the callout system to determine which
81 * list the callout is on and track internal state. Callers *should not*
82 * use the c_flags field directly but should use the macros provided.
83 * 
84 * The c_iflags field holds internal flags that are protected by internal
85 * locks of the callout subsystem.  The c_flags field holds external flags.
86 * The caller must hold its own lock while manipulating or reading external
87 * flags via callout_active(), callout_deactivate(), callout_reset*(), or
88 * callout_stop() to avoid races.
89 */
90#define callout_active(c)       ((c)->c_flags & CALLOUT_ACTIVE)
91#define callout_deactivate(c)   ((c)->c_flags &= ~CALLOUT_ACTIVE)
92#define callout_drain(c)        _callout_stop_safe(c, CS_DRAIN, NULL)
93void    callout_init(struct callout *, int);
94void    _callout_init_lock(struct callout *, struct lock_object *, int);
95#define callout_init_mtx(c, mtx, flags)                                 \
96        _callout_init_lock((c), ((mtx) != NULL) ? &(mtx)->lock_object : \
97            NULL, (flags))
98#define callout_init_rm(c, rm, flags)                                   \
99        _callout_init_lock((c), ((rm) != NULL) ? &(rm)->lock_object :   \
100            NULL, (flags))
101#define callout_init_rw(c, rw, flags)                                   \
102        _callout_init_lock((c), ((rw) != NULL) ? &(rw)->lock_object :   \
103           NULL, (flags))
104#define callout_pending(c)      ((c)->c_iflags & CALLOUT_PENDING)
105int     callout_reset_sbt_on(struct callout *, sbintime_t, sbintime_t,
106            void (*)(void *), void *, int, int);
107#define callout_reset_sbt(c, sbt, pr, fn, arg, flags)                   \
108    callout_reset_sbt_on((c), (sbt), (pr), (fn), (arg), -1, (flags))
109#define callout_reset_sbt_curcpu(c, sbt, pr, fn, arg, flags)            \
110    callout_reset_sbt_on((c), (sbt), (pr), (fn), (arg), PCPU_GET(cpuid),\
111        (flags))
112#define callout_reset_on(c, to_ticks, fn, arg, cpu)                     \
113    callout_reset_sbt_on((c), tick_sbt * (to_ticks), 0, (fn), (arg),    \
114        (cpu), C_HARDCLOCK)
115#define callout_reset(c, on_tick, fn, arg)                              \
116    callout_reset_on((c), (on_tick), (fn), (arg), -1)
117#define callout_reset_curcpu(c, on_tick, fn, arg)                       \
118    callout_reset_on((c), (on_tick), (fn), (arg), PCPU_GET(cpuid))
119#define callout_schedule_sbt_on(c, sbt, pr, cpu, flags)                 \
120    callout_reset_sbt_on((c), (sbt), (pr), (c)->c_func, (c)->c_arg,     \
121        (cpu), (flags))
122#define callout_schedule_sbt(c, sbt, pr, flags)                         \
123    callout_schedule_sbt_on((c), (sbt), (pr), -1, (flags))
124#define callout_schedule_sbt_curcpu(c, sbt, pr, flags)                  \
125    callout_schedule_sbt_on((c), (sbt), (pr), PCPU_GET(cpuid), (flags))
126int     callout_schedule(struct callout *, int);
127int     callout_schedule_on(struct callout *, int, int);
128#define callout_schedule_curcpu(c, on_tick)                             \
129    callout_schedule_on((c), (on_tick), PCPU_GET(cpuid))
130#define callout_stop(c)         _callout_stop_safe(c, 0, NULL)
131int     _callout_stop_safe(struct callout *, int, void (*)(void *));
132void    callout_process(sbintime_t now);
133#define callout_async_drain(c, d)                                       \
134    _callout_stop_safe(c, 0, d)
135void callout_when(sbintime_t sbt, sbintime_t precision, int flags,
136    sbintime_t *sbt_res, sbintime_t *prec_res);
137#endif
138
139#endif /* _SYS_CALLOUT_H_ */
Note: See TracBrowser for help on using the repository browser.