From f2aa140123cb6701c58f52302538181a623480c4 Mon Sep 17 00:00:00 2001 From: jtl Date: Thu, 19 Nov 2015 14:04:53 +0000 Subject: Consistently enforce the restriction against calling malloc/free when in a critical section. uma_zalloc_arg()/uma_zalloc_free() may acquire a sleepable lock on the zone. The malloc() family of functions may call uma_zalloc_arg() or uma_zalloc_free(). The malloc(9) man page currently claims that free() will never sleep. It also implies that the malloc() family of functions will not sleep when called with M_NOWAIT. However, it is more correct to say that these functions will not sleep indefinitely. Indeed, they may acquire a sleepable lock. However, a developer may overlook this restriction because the WITNESS check that catches attempts to call the malloc() family of functions within a critical section is inconsistenly applied. This change clarifies the language of the malloc(9) man page to clarify the restriction against calling the malloc() family of functions while in a critical section or holding a spin lock. It also adds KASSERTs at appropriate points to make the enforcement of this restriction more consistent. PR: 204633 Differential Revision: https://reviews.freebsd.org/D4197 Reviewed by: markj Approved by: gnn (mentor) Sponsored by: Juniper Networks --- sys/vm/uma_core.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'sys/vm') diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c index 8169256..1f57dff 100644 --- a/sys/vm/uma_core.c +++ b/sys/vm/uma_core.c @@ -2149,6 +2149,10 @@ 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, + ("uma_zalloc_arg: called with spinlock or critical section held")); + #ifdef DEBUG_MEMGUARD if (memguard_cmp_zone(zone)) { item = memguard_alloc(zone->uz_size, flags); @@ -2686,6 +2690,9 @@ 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, + ("uma_zfree_arg: called with spinlock or critical section held")); + /* uma_zfree(..., NULL) does nothing, to match free(9). */ if (item == NULL) return; -- cgit v1.1