summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorcognet <cognet@FreeBSD.org>2005-10-03 14:16:41 +0000
committercognet <cognet@FreeBSD.org>2005-10-03 14:16:41 +0000
commit929dc4bed6f0ba8ce74d430befa618c6ac516a3d (patch)
treee9ba09b71b98573aff5b582b588f30af863724f5 /sys
parent5e32ed69e939e49b84f9b9e2fa32fb7c256dd4ce (diff)
downloadFreeBSD-src-929dc4bed6f0ba8ce74d430befa618c6ac516a3d.zip
FreeBSD-src-929dc4bed6f0ba8ce74d430befa618c6ac516a3d.tar.gz
If a thread already tries to allocate a new memory range, wait for it
instead of trying to do the same.
Diffstat (limited to 'sys')
-rw-r--r--sys/arm/arm/vm_machdep.c29
1 files changed, 22 insertions, 7 deletions
diff --git a/sys/arm/arm/vm_machdep.c b/sys/arm/arm/vm_machdep.c
index 154958d..6114a06 100644
--- a/sys/arm/arm/vm_machdep.c
+++ b/sys/arm/arm/vm_machdep.c
@@ -8,7 +8,7 @@
* the Systems Programming Group of the University of Utah Computer
* Science Department, and William Jolitz.
*
- * Redistribution and use in source and binary forms, with or without
+ * Redistribution and use in source and binary :forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
@@ -242,7 +242,7 @@ sf_buf_alloc(struct vm_page *m, int flags)
sf->m = m;
nsfbufsused++;
nsfbufspeak = imax(nsfbufspeak, nsfbufsused);
- pmap_qenter(sf->kva, &sf->m, 1);
+ pmap_kenter(sf->kva, VM_PAGE_TO_PHYS(sf->m));
done:
mtx_unlock(&sf_buf_lock);
return (sf);
@@ -409,7 +409,6 @@ arm_uma_do_alloc(struct arm_small_page **pglist, int bytes, int pagetable)
{
void *ret;
vm_page_t page_array = NULL;
-
*pglist = (void *)kmem_malloc(kmem_map, (0x100000 / PAGE_SIZE) *
sizeof(struct arm_small_page), M_WAITOK);
@@ -430,8 +429,6 @@ arm_uma_do_alloc(struct arm_small_page **pglist, int bytes, int pagetable)
mtx_unlock(&smallalloc_mtx);
pmap_kenter_section((vm_offset_t)ret, pa
, pagetable);
-
-
} else {
kmem_free(kmem_map, (vm_offset_t)*pglist,
(0x100000 / PAGE_SIZE) * sizeof(struct arm_small_page));
@@ -447,6 +444,8 @@ 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 int in_sleep;
*flags = UMA_SLAB_PRIV;
/*
@@ -459,12 +458,24 @@ uma_small_alloc(uma_zone_t zone, int bytes, u_int8_t *flags, int wait)
head = (void *)&pages_normal;
mtx_lock(&smallalloc_mtx);
+retry:
sp = TAILQ_FIRST(head);
if (!sp) {
/* No more free pages, need to alloc more. */
+ if (in_alloc && (wait & M_WAITOK)) {
+ /* Somebody else is already doing the allocation. */
+ in_sleep++;
+ msleep(&in_alloc, &smallalloc_mtx, PWAIT,
+ "smallalloc", 0);
+ in_sleep--;
+ goto retry;
+ }
+ if (wait & M_WAITOK)
+ in_alloc = 1;
mtx_unlock(&smallalloc_mtx);
if (!(wait & M_WAITOK)) {
+ *flags = UMA_SLAB_KMEM;
ret = (void *)kmem_malloc(kmem_map, bytes, wait);
return (ret);
}
@@ -482,7 +493,8 @@ uma_small_alloc(uma_zone_t zone, int bytes, u_int8_t *flags, int wait)
ret = (char *)ret + 0x100000 - PAGE_SIZE;
TAILQ_INSERT_HEAD(&free_pgdesc, &sp[(0x100000 / (
PAGE_SIZE)) - 1], pg_list);
- }
+ } else
+ *flags = UMA_SLAB_KMEM;
} else {
sp = TAILQ_FIRST(head);
@@ -490,6 +502,9 @@ uma_small_alloc(uma_zone_t zone, int bytes, u_int8_t *flags, int wait)
TAILQ_INSERT_HEAD(&free_pgdesc, sp, pg_list);
ret = sp->addr;
}
+ in_alloc = 0;
+ if (in_sleep)
+ wakeup(&in_alloc);
mtx_unlock(&smallalloc_mtx);
if ((wait & M_ZERO))
bzero(ret, bytes);
@@ -502,7 +517,7 @@ uma_small_free(void *mem, int size, u_int8_t flags)
pd_entry_t *pd;
pt_entry_t *pt;
- if (mem < (void *)alloc_firstaddr)
+ if (flags & UMA_SLAB_KMEM)
kmem_free(kmem_map, (vm_offset_t)mem, size);
else {
struct arm_small_page *sp;
OpenPOWER on IntegriCloud