From 98fd4878e04a40df20d37039ee02a0fbd5e6e474 Mon Sep 17 00:00:00 2001 From: markj Date: Fri, 11 Dec 2015 20:05:07 +0000 Subject: [PATCH] Don't make assertions about td_critnest when the scheduler is stopped. A panicking thread always executes with a critical section held, so any attempt to allocate or free memory while dumping will otherwise cause a second panic. This can occur, for example, if xpt_polled_action() completes non-dump I/O that was pending at the time of the panic. The fact that this can occur is itself a bug, but asserting in this case does little but reduce the reliability of kernel dumps. Suggested by: kib Reported by: pho --- sys/kern/kern_malloc.c | 9 +++------ sys/vm/uma_core.c | 5 ++--- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c index 01aff78a37e6..e7c81d67e936 100644 --- a/sys/kern/kern_malloc.c +++ b/sys/kern/kern_malloc.c @@ -475,8 +475,7 @@ malloc(unsigned long size, struct malloc_type *mtp, int flags) if (flags & M_WAITOK) KASSERT(curthread->td_intr_nesting_level == 0, ("malloc(M_WAITOK) in interrupt context")); - - KASSERT(curthread->td_critnest == 0, + KASSERT(curthread->td_critnest == 0 || SCHEDULER_STOPPED(), ("malloc: called with spinlock or critical section held")); #ifdef DEBUG_MEMGUARD @@ -544,8 +543,7 @@ free(void *addr, struct malloc_type *mtp) u_long size; KASSERT(mtp->ks_magic == M_MAGIC, ("free: bad malloc type magic")); - - KASSERT(curthread->td_critnest == 0, + KASSERT(curthread->td_critnest == 0 || SCHEDULER_STOPPED(), ("free: called with spinlock or critical section held")); /* free(NULL, ...) does nothing */ @@ -610,8 +608,7 @@ realloc(void *addr, unsigned long size, struct malloc_type *mtp, int flags) KASSERT(mtp->ks_magic == M_MAGIC, ("realloc: bad malloc type magic")); - - KASSERT(curthread->td_critnest == 0, + KASSERT(curthread->td_critnest == 0 || SCHEDULER_STOPPED(), ("realloc: called with spinlock or critical section held")); /* realloc(NULL, ...) is equivalent to malloc(...) */ diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c index 1f57dfff898c..3a0a7993b814 100644 --- a/sys/vm/uma_core.c +++ b/sys/vm/uma_core.c @@ -2149,8 +2149,7 @@ uma_zalloc_arg(uma_zone_t zone, void *udata, int flags) WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, "uma_zalloc_arg: zone \"%s\"", zone->uz_name); } - - KASSERT(curthread->td_critnest == 0, + KASSERT(curthread->td_critnest == 0 || SCHEDULER_STOPPED(), ("uma_zalloc_arg: called with spinlock or critical section held")); #ifdef DEBUG_MEMGUARD @@ -2690,7 +2689,7 @@ uma_zfree_arg(uma_zone_t zone, void *item, void *udata) CTR2(KTR_UMA, "uma_zfree_arg thread %x zone %s", curthread, zone->uz_name); - KASSERT(curthread->td_critnest == 0, + KASSERT(curthread->td_critnest == 0 || SCHEDULER_STOPPED(), ("uma_zfree_arg: called with spinlock or critical section held")); /* uma_zfree(..., NULL) does nothing, to match free(9). */