git: a8cbb835bfdf - main - uma_zalloc: assert M_NOWAIT ^ M_WAITOK
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 26 Mar 2022 01:11:44 UTC
The branch main has been updated by vangyzen:
URL: https://cgit.FreeBSD.org/src/commit/?id=a8cbb835bfdf086249fab8f9cb3d2a3533214eac
commit a8cbb835bfdf086249fab8f9cb3d2a3533214eac
Author: Eric van Gyzen <vangyzen@FreeBSD.org>
AuthorDate: 2022-03-04 11:23:08 +0000
Commit: Eric van Gyzen <vangyzen@FreeBSD.org>
CommitDate: 2022-03-26 01:10:37 +0000
uma_zalloc: assert M_NOWAIT ^ M_WAITOK
The uma_zalloc functions expect exactly one of [M_NOWAIT, M_WAITOK].
If neither or both are passed, print an error and a stack dump.
Only do this ten times, to prevent livelock. In the future, after
this exposes enough bad callers, this will be changed to a KASSERT().
Reviewed by: rstone, markj
MFC after: 1 month
Sponsored by: Dell EMC Isilon
Differential Revision: https://reviews.freebsd.org/D34452
---
sys/vm/uma_core.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c
index 341b12209f9d..9fd2fd5e5d03 100644
--- a/sys/vm/uma_core.c
+++ b/sys/vm/uma_core.c
@@ -3494,6 +3494,9 @@ item_domain(void *item)
#endif
#if defined(INVARIANTS) || defined(DEBUG_MEMGUARD) || defined(WITNESS)
+#if defined(INVARIANTS) && (defined(DDB) || defined(STACK))
+#include <sys/stack.h>
+#endif
#define UMA_ZALLOC_DEBUG
static int
uma_zalloc_debug(uma_zone_t zone, void **itemp, void *udata, int flags)
@@ -3515,6 +3518,31 @@ uma_zalloc_debug(uma_zone_t zone, void **itemp, void *udata, int flags)
("uma_zalloc_debug: called within spinlock or critical section"));
KASSERT((zone->uz_flags & UMA_ZONE_PCPU) == 0 || (flags & M_ZERO) == 0,
("uma_zalloc_debug: allocating from a pcpu zone with M_ZERO"));
+
+ _Static_assert(M_NOWAIT != 0 && M_WAITOK != 0,
+ "M_NOWAIT and M_WAITOK must be non-zero for this assertion:");
+#if 0
+ /*
+ * Give the #elif clause time to find problems, then remove it
+ * and enable this. (Remove <sys/stack.h> above, too.)
+ */
+ KASSERT((flags & (M_NOWAIT|M_WAITOK)) == M_NOWAIT ||
+ (flags & (M_NOWAIT|M_WAITOK)) == M_WAITOK,
+ ("uma_zalloc_debug: must pass one of M_NOWAIT or M_WAITOK"));
+#elif defined(DDB) || defined(STACK)
+ if (__predict_false((flags & (M_NOWAIT|M_WAITOK)) != M_NOWAIT &&
+ (flags & (M_NOWAIT|M_WAITOK)) != M_WAITOK)) {
+ static int stack_count;
+ struct stack st;
+
+ if (stack_count < 10) {
+ ++stack_count;
+ printf("uma_zalloc* called with bad WAIT flags:\n");
+ stack_save(&st);
+ stack_print(&st);
+ }
+ }
+#endif
#endif
#ifdef DEBUG_MEMGUARD