Changeset View
Changeset View
Standalone View
Standalone View
sys/sys/systm.h
Show First 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | |||||
#include <machine/atomic.h> | #include <machine/atomic.h> | ||||
#include <machine/cpufunc.h> | #include <machine/cpufunc.h> | ||||
#include <sys/callout.h> | #include <sys/callout.h> | ||||
#include <sys/queue.h> | #include <sys/queue.h> | ||||
#include <sys/stdint.h> /* for people using printf mainly */ | #include <sys/stdint.h> /* for people using printf mainly */ | ||||
__NULLABILITY_PRAGMA_PUSH | __NULLABILITY_PRAGMA_PUSH | ||||
#ifdef _KERNEL | |||||
extern int cold; /* nonzero if we are doing a cold boot */ | extern int cold; /* nonzero if we are doing a cold boot */ | ||||
extern int suspend_blocked; /* block suspend due to pending shutdown */ | extern int suspend_blocked; /* block suspend due to pending shutdown */ | ||||
extern int rebooting; /* kern_reboot() has been called. */ | extern int rebooting; /* kern_reboot() has been called. */ | ||||
extern const char *panicstr; /* panic message */ | extern const char *panicstr; /* panic message */ | ||||
extern bool panicked; | extern bool panicked; | ||||
#define KERNEL_PANICKED() __predict_false(panicked) | #define KERNEL_PANICKED() __predict_false(panicked) | ||||
extern char version[]; /* system version */ | extern char version[]; /* system version */ | ||||
extern char compiler_version[]; /* compiler version */ | extern char compiler_version[]; /* compiler version */ | ||||
Show All 18 Lines | |||||
* and/or add to the VM_GUEST_VM type if specific VM functionality is | * and/or add to the VM_GUEST_VM type if specific VM functionality is | ||||
* ever implemented (e.g. vendor-specific paravirtualization features). | * ever implemented (e.g. vendor-specific paravirtualization features). | ||||
* Keep in sync with vm_guest_sysctl_names[]. | * Keep in sync with vm_guest_sysctl_names[]. | ||||
*/ | */ | ||||
enum VM_GUEST { VM_GUEST_NO = 0, VM_GUEST_VM, VM_GUEST_XEN, VM_GUEST_HV, | enum VM_GUEST { VM_GUEST_NO = 0, VM_GUEST_VM, VM_GUEST_XEN, VM_GUEST_HV, | ||||
VM_GUEST_VMWARE, VM_GUEST_KVM, VM_GUEST_BHYVE, VM_GUEST_VBOX, | VM_GUEST_VMWARE, VM_GUEST_KVM, VM_GUEST_BHYVE, VM_GUEST_VBOX, | ||||
VM_GUEST_PARALLELS, VM_LAST }; | VM_GUEST_PARALLELS, VM_LAST }; | ||||
/* | |||||
* These functions need to be declared before the KASSERT macro is invoked in | |||||
* !KASSERT_PANIC_OPTIONAL builds, so their declarations are sort of out of | |||||
* place compared to other function definitions in this header. On the other | |||||
* hand, this header is a bit disorganized anyway. | |||||
*/ | |||||
void panic(const char *, ...) __dead2 __printflike(1, 2); | |||||
void vpanic(const char *, __va_list) __dead2 __printflike(1, 0); | |||||
#if defined(WITNESS) || defined(INVARIANT_SUPPORT) | |||||
#ifdef KASSERT_PANIC_OPTIONAL | |||||
void kassert_panic(const char *fmt, ...) __printflike(1, 2); | |||||
#else | |||||
#define kassert_panic panic | |||||
#endif | |||||
#endif | |||||
#ifdef INVARIANTS /* The option is always available */ | #ifdef INVARIANTS /* The option is always available */ | ||||
#define KASSERT(exp,msg) do { \ | |||||
if (__predict_false(!(exp))) \ | |||||
kassert_panic msg; \ | |||||
} while (0) | |||||
#define VNASSERT(exp, vp, msg) do { \ | #define VNASSERT(exp, vp, msg) do { \ | ||||
jhb: It's hard to imagine that you are using VNASSERT() outside of the kernel.
Which of these are… | |||||
Done Inline ActionsThis is for old code being brought into stand: There's bits of ZFS that are now being more aggressively pulled in. So there's no repeat of the past, just using things... I'll confirm they are actually used, though... imp: This is for old code being brought into stand: There's bits of ZFS that are now being more… | |||||
if (__predict_false(!(exp))) { \ | if (__predict_false(!(exp))) { \ | ||||
vn_printf(vp, "VNASSERT failed: %s not true at %s:%d (%s)\n",\ | vn_printf(vp, "VNASSERT failed: %s not true at %s:%d (%s)\n",\ | ||||
#exp, __FILE__, __LINE__, __func__); \ | #exp, __FILE__, __LINE__, __func__); \ | ||||
kassert_panic msg; \ | kassert_panic msg; \ | ||||
} \ | } \ | ||||
} while (0) | } while (0) | ||||
#define VNPASS(exp, vp) do { \ | #define VNPASS(exp, vp) do { \ | ||||
const char *_exp = #exp; \ | const char *_exp = #exp; \ | ||||
VNASSERT(exp, vp, ("condition %s not met at %s:%d (%s)", \ | VNASSERT(exp, vp, ("condition %s not met at %s:%d (%s)", \ | ||||
_exp, __FILE__, __LINE__, __func__)); \ | _exp, __FILE__, __LINE__, __func__)); \ | ||||
} while (0) | } while (0) | ||||
#define __assert_unreachable() \ | #define __assert_unreachable() \ | ||||
panic("executing segment marked as unreachable at %s:%d (%s)\n", \ | panic("executing segment marked as unreachable at %s:%d (%s)\n", \ | ||||
__FILE__, __LINE__, __func__) | __FILE__, __LINE__, __func__) | ||||
#else | #else | ||||
#define KASSERT(exp,msg) do { \ | |||||
} while (0) | |||||
#define VNASSERT(exp, vp, msg) do { \ | #define VNASSERT(exp, vp, msg) do { \ | ||||
} while (0) | } while (0) | ||||
#define VNPASS(exp, vp) do { \ | #define VNPASS(exp, vp) do { \ | ||||
} while (0) | } while (0) | ||||
#define __assert_unreachable() __unreachable() | #define __assert_unreachable() __unreachable() | ||||
#endif | #endif | ||||
#ifndef CTASSERT /* Allow lint to override */ | #ifndef CTASSERT /* Allow lint to override */ | ||||
#define CTASSERT(x) _Static_assert(x, "compile-time assertion failed") | #define CTASSERT(x) _Static_assert(x, "compile-time assertion failed") | ||||
#endif | #endif | ||||
#endif /* KERNEL */ | |||||
#if defined(_KERNEL) | /* | ||||
#include <sys/param.h> /* MAXCPU */ | * These function declarations are sort of out of place compared to other | ||||
#include <sys/pcpu.h> /* curthread */ | * function definitions in this header. On the other hand, this header is a bit | ||||
#include <sys/kpilite.h> | * disorganized anyway. | ||||
*/ | |||||
void panic(const char *, ...) __dead2 __printflike(1, 2); | |||||
void vpanic(const char *, __va_list) __dead2 __printflike(1, 0); | |||||
#if defined(_STANDALONE) | |||||
/* | |||||
* Until we have more experience with KASSERTS that are called | |||||
* from the boot loader, they are off. The bootloader does this | |||||
* a little differently than the kernel (we just call printf atm). | |||||
* we avoid most of the common functions in the boot loader, so | |||||
* declare printf() here too. | |||||
*/ | |||||
int printf(const char *, ...) __printflike(1, 2); | |||||
# define kassert_panic printf | |||||
#else /* !_STANDALONE */ | |||||
# if defined(WITNESS) || defined(INVARIANT_SUPPORT) | |||||
# ifdef KASSERT_PANIC_OPTIONAL | |||||
void kassert_panic(const char *fmt, ...) __printflike(1, 2); | |||||
# else | |||||
# define kassert_panic panic | |||||
# endif /* KASSERT_PANIC_OPTIONAL */ | |||||
# endif /* defined(WITNESS) || defined(INVARIANT_SUPPORT) */ | |||||
#endif /* _STANDALONE */ | |||||
#if defined(INVARIANTS) || defined(_STANDALONE) | |||||
#define KASSERT(exp,msg) do { \ | |||||
if (__predict_false(!(exp))) \ | |||||
kassert_panic msg; \ | |||||
} while (0) | |||||
#else | |||||
#define KASSERT(exp,msg) do { \ | |||||
} while (0) | |||||
#endif | #endif | ||||
/* | /* | ||||
* Helpful macros for quickly coming up with assertions with informative | * Helpful macros for quickly coming up with assertions with informative | ||||
* panic messages. | * panic messages. | ||||
*/ | */ | ||||
#define MPASS(ex) MPASS4(ex, #ex, __FILE__, __LINE__) | #define MPASS(ex) MPASS4(ex, #ex, __FILE__, __LINE__) | ||||
#define MPASS2(ex, what) MPASS4(ex, what, __FILE__, __LINE__) | #define MPASS2(ex, what) MPASS4(ex, what, __FILE__, __LINE__) | ||||
#define MPASS3(ex, file, line) MPASS4(ex, #ex, file, line) | #define MPASS3(ex, file, line) MPASS4(ex, #ex, file, line) | ||||
#define MPASS4(ex, what, file, line) \ | #define MPASS4(ex, what, file, line) \ | ||||
KASSERT((ex), ("Assertion %s failed at %s:%d", what, file, line)) | KASSERT((ex), ("Assertion %s failed at %s:%d", what, file, line)) | ||||
/* | /* | ||||
* Align variables. | |||||
*/ | |||||
#define __read_mostly __section(".data.read_mostly") | |||||
#define __read_frequently __section(".data.read_frequently") | |||||
#define __exclusive_cache_line __aligned(CACHE_LINE_SIZE) \ | |||||
__section(".data.exclusive_cache_line") | |||||
#ifdef _KERNEL | |||||
#include <sys/param.h> /* MAXCPU */ | |||||
#include <sys/pcpu.h> /* curthread */ | |||||
#include <sys/kpilite.h> | |||||
/* | |||||
* Assert that a pointer can be loaded from memory atomically. | * Assert that a pointer can be loaded from memory atomically. | ||||
* | * | ||||
* This assertion enforces stronger alignment than necessary. For example, | * This assertion enforces stronger alignment than necessary. For example, | ||||
* on some architectures, atomicity for unaligned loads will depend on | * on some architectures, atomicity for unaligned loads will depend on | ||||
* whether or not the load spans multiple cache lines. | * whether or not the load spans multiple cache lines. | ||||
*/ | */ | ||||
#define ASSERT_ATOMIC_LOAD_PTR(var, msg) \ | #define ASSERT_ATOMIC_LOAD_PTR(var, msg) \ | ||||
KASSERT(sizeof(var) == sizeof(void *) && \ | KASSERT(sizeof(var) == sizeof(void *) && \ | ||||
Show All 13 Lines | |||||
*/ | */ | ||||
#define SCHEDULER_STOPPED_TD(td) ({ \ | #define SCHEDULER_STOPPED_TD(td) ({ \ | ||||
MPASS((td) == curthread); \ | MPASS((td) == curthread); \ | ||||
__predict_false((td)->td_stopsched); \ | __predict_false((td)->td_stopsched); \ | ||||
}) | }) | ||||
#define SCHEDULER_STOPPED() SCHEDULER_STOPPED_TD(curthread) | #define SCHEDULER_STOPPED() SCHEDULER_STOPPED_TD(curthread) | ||||
/* | /* | ||||
* Align variables. | |||||
*/ | |||||
#define __read_mostly __section(".data.read_mostly") | |||||
#define __read_frequently __section(".data.read_frequently") | |||||
#define __exclusive_cache_line __aligned(CACHE_LINE_SIZE) \ | |||||
__section(".data.exclusive_cache_line") | |||||
/* | |||||
* XXX the hints declarations are even more misplaced than most declarations | * XXX the hints declarations are even more misplaced than most declarations | ||||
* in this file, since they are needed in one file (per arch) and only used | * in this file, since they are needed in one file (per arch) and only used | ||||
* in two files. | * in two files. | ||||
* XXX most of these variables should be const. | * XXX most of these variables should be const. | ||||
*/ | */ | ||||
extern int osreldate; | extern int osreldate; | ||||
extern bool dynamic_kenv; | extern bool dynamic_kenv; | ||||
extern struct mtx kenv_lock; | extern struct mtx kenv_lock; | ||||
Done Inline ActionsNote: we should likely fix this... there's only two files (and not one per arch) that use it. osreldate is more wide spread imp: Note: we should likely fix this... there's only two files (and not one per arch) that use it. | |||||
extern char *kern_envp; | extern char *kern_envp; | ||||
extern char *md_envp; | extern char *md_envp; | ||||
extern char static_env[]; | extern char static_env[]; | ||||
extern char static_hints[]; /* by config for now */ | extern char static_hints[]; /* by config for now */ | ||||
extern char **kenvp; | extern char **kenvp; | ||||
extern const void *zero_region; /* address space maps to a zeroed page */ | extern const void *zero_region; /* address space maps to a zeroed page */ | ||||
▲ Show 20 Lines • Show All 414 Lines • ▼ Show 20 Lines | |||||
#define __gone_ok(m, msg) \ | #define __gone_ok(m, msg) \ | ||||
_Static_assert(m < P_OSREL_MAJOR(__FreeBSD_version)), \ | _Static_assert(m < P_OSREL_MAJOR(__FreeBSD_version)), \ | ||||
"Obsolete code: " msg); | "Obsolete code: " msg); | ||||
#else | #else | ||||
#define __gone_ok(m, msg) | #define __gone_ok(m, msg) | ||||
#endif | #endif | ||||
#define gone_in(major, msg) __gone_ok(major, msg) _gone_in(major, msg) | #define gone_in(major, msg) __gone_ok(major, msg) _gone_in(major, msg) | ||||
#define gone_in_dev(dev, major, msg) __gone_ok(major, msg) _gone_in_dev(dev, major, msg) | #define gone_in_dev(dev, major, msg) __gone_ok(major, msg) _gone_in_dev(dev, major, msg) | ||||
#endif /* _KERNEL */ | |||||
__NULLABILITY_PRAGMA_POP | __NULLABILITY_PRAGMA_POP | ||||
#endif /* !_SYS_SYSTM_H_ */ | #endif /* !_SYS_SYSTM_H_ */ |
It's hard to imagine that you are using VNASSERT() outside of the kernel.
Which of these are you actually using? I still think new code should use _Static_assert() directly rather than CTASSERT, and KASSERT() is kind of crummy due to its lack of using VAR_ARGS, so I would rather stand.h grow a useful macro that works with VAR_ARGS instead rather than repeating that mistake if possible.