Use mutexes.

This commit is contained in:
ad 2007-03-12 16:42:14 +00:00
parent 3eeb069c1f
commit 3fcdeca2cc
1 changed files with 18 additions and 26 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_malloc.c,v 1.108 2007/03/04 06:03:05 christos Exp $ */ /* $NetBSD: kern_malloc.c,v 1.109 2007/03/12 16:42:14 ad Exp $ */
/* /*
* Copyright (c) 1987, 1991, 1993 * Copyright (c) 1987, 1991, 1993
@ -66,7 +66,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_malloc.c,v 1.108 2007/03/04 06:03:05 christos Exp $"); __KERNEL_RCSID(0, "$NetBSD: kern_malloc.c,v 1.109 2007/03/12 16:42:14 ad Exp $");
#include "opt_lockdebug.h" #include "opt_lockdebug.h"
@ -76,6 +76,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_malloc.c,v 1.108 2007/03/04 06:03:05 christos E
#include <sys/malloc.h> #include <sys/malloc.h>
#include <sys/systm.h> #include <sys/systm.h>
#include <sys/debug.h> #include <sys/debug.h>
#include <sys/mutex.h>
#include <uvm/uvm_extern.h> #include <uvm/uvm_extern.h>
@ -302,7 +303,7 @@ MALLOC_DEFINE(M_MRTABLE, "mrt", "multicast routing tables");
MALLOC_DEFINE(M_BWMETER, "bwmeter", "multicast upcall bw meters"); MALLOC_DEFINE(M_BWMETER, "bwmeter", "multicast upcall bw meters");
MALLOC_DEFINE(M_1394DATA, "1394data", "IEEE 1394 data buffers"); MALLOC_DEFINE(M_1394DATA, "1394data", "IEEE 1394 data buffers");
struct simplelock malloc_slock = SIMPLELOCK_INITIALIZER; kmutex_t malloc_lock;
/* /*
* Allocate a block of memory * Allocate a block of memory
@ -320,7 +321,6 @@ malloc(unsigned long size, struct malloc_type *ksp, int flags)
struct kmemusage *kup; struct kmemusage *kup;
struct freelist *freep; struct freelist *freep;
long indx, npg, allocsize; long indx, npg, allocsize;
int s;
char *va, *cp, *savedlist; char *va, *cp, *savedlist;
#ifdef DIAGNOSTIC #ifdef DIAGNOSTIC
uint32_t *end, *lp; uint32_t *end, *lp;
@ -340,19 +340,17 @@ malloc(unsigned long size, struct malloc_type *ksp, int flags)
#endif #endif
indx = BUCKETINDX(size); indx = BUCKETINDX(size);
kbp = &kmembuckets[indx]; kbp = &kmembuckets[indx];
s = splvm(); mutex_enter(&malloc_lock);
simple_lock(&malloc_slock);
#ifdef KMEMSTATS #ifdef KMEMSTATS
while (ksp->ks_memuse >= ksp->ks_limit) { while (ksp->ks_memuse >= ksp->ks_limit) {
if (flags & M_NOWAIT) { if (flags & M_NOWAIT) {
simple_unlock(&malloc_slock); mutex_exit(&malloc_lock);
splx(s);
return ((void *) NULL); return ((void *) NULL);
} }
if (ksp->ks_limblocks < 65535) if (ksp->ks_limblocks < 65535)
ksp->ks_limblocks++; ksp->ks_limblocks++;
ltsleep((void *)ksp, PSWP+2, ksp->ks_shortdesc, 0, mtsleep((void *)ksp, PSWP+2, ksp->ks_shortdesc, 0,
&malloc_slock); &malloc_lock);
} }
ksp->ks_size |= 1 << indx; ksp->ks_size |= 1 << indx;
#endif #endif
@ -366,7 +364,7 @@ malloc(unsigned long size, struct malloc_type *ksp, int flags)
else else
allocsize = 1 << indx; allocsize = 1 << indx;
npg = btoc(allocsize); npg = btoc(allocsize);
simple_unlock(&malloc_slock); mutex_exit(&malloc_lock);
va = (void *) uvm_km_alloc(kmem_map, va = (void *) uvm_km_alloc(kmem_map,
(vsize_t)ctob(npg), 0, (vsize_t)ctob(npg), 0,
((flags & M_NOWAIT) ? UVM_KMF_NOWAIT : 0) | ((flags & M_NOWAIT) ? UVM_KMF_NOWAIT : 0) |
@ -383,10 +381,9 @@ malloc(unsigned long size, struct malloc_type *ksp, int flags)
*/ */
if ((flags & (M_NOWAIT|M_CANFAIL)) == 0) if ((flags & (M_NOWAIT|M_CANFAIL)) == 0)
panic("malloc: out of space in kmem_map"); panic("malloc: out of space in kmem_map");
splx(s);
return (NULL); return (NULL);
} }
simple_lock(&malloc_slock); mutex_enter(&malloc_lock);
#ifdef KMEMSTATS #ifdef KMEMSTATS
kbp->kb_total += kbp->kb_elmpercl; kbp->kb_total += kbp->kb_elmpercl;
#endif #endif
@ -511,8 +508,7 @@ out:
#ifdef MALLOCLOG #ifdef MALLOCLOG
domlog(va, size, ksp, 1, file, line); domlog(va, size, ksp, 1, file, line);
#endif #endif
simple_unlock(&malloc_slock); mutex_exit(&malloc_lock);
splx(s);
if ((flags & M_ZERO) != 0) if ((flags & M_ZERO) != 0)
memset(va, 0, size); memset(va, 0, size);
FREECHECK_OUT(&malloc_freecheck, (void *)va); FREECHECK_OUT(&malloc_freecheck, (void *)va);
@ -534,7 +530,6 @@ free(void *addr, struct malloc_type *ksp)
struct kmemusage *kup; struct kmemusage *kup;
struct freelist *freep; struct freelist *freep;
long size; long size;
int s;
#ifdef DIAGNOSTIC #ifdef DIAGNOSTIC
void *cp; void *cp;
int32_t *end, *lp; int32_t *end, *lp;
@ -562,8 +557,7 @@ free(void *addr, struct malloc_type *ksp)
kup = btokup(addr); kup = btokup(addr);
size = 1 << kup->ku_indx; size = 1 << kup->ku_indx;
kbp = &kmembuckets[kup->ku_indx]; kbp = &kmembuckets[kup->ku_indx];
s = splvm(); mutex_enter(&malloc_lock);
simple_lock(&malloc_slock);
#ifdef MALLOCLOG #ifdef MALLOCLOG
domlog(addr, 0, ksp, 2, file, line); domlog(addr, 0, ksp, 2, file, line);
#endif #endif
@ -598,8 +592,7 @@ free(void *addr, struct malloc_type *ksp)
ksp->ks_inuse--; ksp->ks_inuse--;
kbp->kb_total -= 1; kbp->kb_total -= 1;
#endif #endif
simple_unlock(&malloc_slock); mutex_exit(&malloc_lock);
splx(s);
return; return;
} }
freep = (struct freelist *)addr; freep = (struct freelist *)addr;
@ -663,8 +656,7 @@ free(void *addr, struct malloc_type *ksp)
((struct freelist *)kbp->kb_last)->next = addr; ((struct freelist *)kbp->kb_last)->next = addr;
freep->next = NULL; freep->next = NULL;
kbp->kb_last = addr; kbp->kb_last = addr;
simple_unlock(&malloc_slock); mutex_exit(&malloc_lock);
splx(s);
} }
/* /*
@ -839,11 +831,9 @@ void
malloc_type_setlimit(struct malloc_type *type, u_long limit) malloc_type_setlimit(struct malloc_type *type, u_long limit)
{ {
#ifdef KMEMSTATS #ifdef KMEMSTATS
int s; mutex_enter(&malloc_lock);
s = splvm();
type->ks_limit = limit; type->ks_limit = limit;
splx(s); mutex_exit(&malloc_lock);
#endif #endif
} }
@ -901,6 +891,8 @@ kmeminit(void)
if (sizeof(struct freelist) > (1 << MINBUCKET)) if (sizeof(struct freelist) > (1 << MINBUCKET))
panic("minbucket too small/struct freelist too big"); panic("minbucket too small/struct freelist too big");
mutex_init(&malloc_lock, MUTEX_DRIVER, IPL_VM);
/* /*
* Compute the number of kmem_map pages, if we have not * Compute the number of kmem_map pages, if we have not
* done so already. * done so already.