diff options
author | cognet <cognet@FreeBSD.org> | 2006-07-15 23:01:54 +0000 |
---|---|---|
committer | cognet <cognet@FreeBSD.org> | 2006-07-15 23:01:54 +0000 |
commit | f4ecac7c4e7f0b48804ef817b8f78b9782976a22 (patch) | |
tree | 145419f4634185aa21842d551dc253ad032c9ea1 /sys/arm | |
parent | 140f31fa4d3d7de23f6f1de80e6f23e005657585 (diff) | |
download | FreeBSD-src-f4ecac7c4e7f0b48804ef817b8f78b9782976a22.zip FreeBSD-src-f4ecac7c4e7f0b48804ef817b8f78b9782976a22.tar.gz |
Make sure that if uma_small_alloc() gets called recursively, we just give up
and call kmem_malloc(), to avoid a deadlock.
Diffstat (limited to 'sys/arm')
-rw-r--r-- | sys/arm/arm/vm_machdep.c | 13 |
1 files changed, 6 insertions, 7 deletions
diff --git a/sys/arm/arm/vm_machdep.c b/sys/arm/arm/vm_machdep.c index ba5a248..3bdf45d 100644 --- a/sys/arm/arm/vm_machdep.c +++ b/sys/arm/arm/vm_machdep.c @@ -512,7 +512,7 @@ uma_small_alloc(uma_zone_t zone, int bytes, u_int8_t *flags, int wait) void *ret; struct arm_small_page *sp, *tmp; TAILQ_HEAD(,arm_small_page) *head; - static int in_alloc; + static struct thread *in_alloc; static int in_sleep; int should_wakeup = 0; @@ -532,12 +532,13 @@ retry: if (!sp) { /* No more free pages, need to alloc more. */ - if (!(wait & M_WAITOK)) { + if (!(wait & M_WAITOK) || + in_alloc == curthread) { mtx_unlock(&smallalloc_mtx); *flags = UMA_SLAB_KMEM; return ((void *)kmem_malloc(kmem_map, bytes, M_NOWAIT)); } - if (in_alloc) { + if (in_alloc != NULL) { /* Somebody else is already doing the allocation. */ in_sleep++; msleep(&in_alloc, &smallalloc_mtx, PWAIT, @@ -545,15 +546,13 @@ retry: in_sleep--; goto retry; } - in_alloc = 1; + in_alloc = curthread; mtx_unlock(&smallalloc_mtx); /* Try to alloc 1MB of contiguous memory. */ ret = arm_uma_do_alloc(&sp, bytes, zone == l2zone ? SECTION_PT : SECTION_CACHE); mtx_lock(&smallalloc_mtx); - in_alloc = 0; - if (in_sleep) - should_wakeup = 1; + in_alloc = NULL; if (sp) { for (int i = 0; i < (0x100000 / PAGE_SIZE) - 1; i++) { |