Module Name: src Committed By: elad Date: Wed Dec 30 18:57:17 UTC 2009
Modified Files: src/sys/kern: subr_pool.c src/sys/sys: pool.h Log Message: Turn PA_INITIALIZED to a reference count for the pool allocator, and once it drops to zero destroy the mutex we initialize. This fixes the problem mentioned in http://mail-index.netbsd.org/tech-kern/2009/12/28/msg006727.html Also remove pa_flags now that it's no longer needed. Idea from matt@, okay m...@. To generate a diff of this commit: cvs rdiff -u -r1.177 -r1.178 src/sys/kern/subr_pool.c cvs rdiff -u -r1.67 -r1.68 src/sys/sys/pool.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/subr_pool.c diff -u src/sys/kern/subr_pool.c:1.177 src/sys/kern/subr_pool.c:1.178 --- src/sys/kern/subr_pool.c:1.177 Tue Oct 20 17:24:22 2009 +++ src/sys/kern/subr_pool.c Wed Dec 30 18:57:17 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: subr_pool.c,v 1.177 2009/10/20 17:24:22 jym Exp $ */ +/* $NetBSD: subr_pool.c,v 1.178 2009/12/30 18:57:17 elad Exp $ */ /*- * Copyright (c) 1997, 1999, 2000, 2002, 2007, 2008 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: subr_pool.c,v 1.177 2009/10/20 17:24:22 jym Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_pool.c,v 1.178 2009/12/30 18:57:17 elad Exp $"); #include "opt_ddb.h" #include "opt_pool.h" @@ -104,6 +104,9 @@ static kmutex_t pool_head_lock; static kcondvar_t pool_busy; +/* This lock protects initialization of a potentially shared pool allocator */ +static kmutex_t pool_allocator_lock; + typedef uint32_t pool_item_bitmap_t; #define BITMAP_SIZE (CHAR_BIT * sizeof(pool_item_bitmap_t)) #define BITMAP_MASK (BITMAP_SIZE - 1) @@ -604,6 +607,8 @@ pool_init(&cache_cpu_pool, sizeof(pool_cache_cpu_t), coherency_unit, 0, 0, "pcachecpu", &pool_allocator_nointr, IPL_NONE); + + mutex_init(&pool_allocator_lock, MUTEX_DEFAULT, IPL_NONE); } /* @@ -650,7 +655,8 @@ palloc = &pool_allocator_nointr_fullpage; } #endif /* POOL_SUBPAGE */ - if ((palloc->pa_flags & PA_INITIALIZED) == 0) { + mutex_enter(&pool_allocator_lock); + if (palloc->pa_refcnt++ == 0) { if (palloc->pa_pagesz == 0) palloc->pa_pagesz = PAGE_SIZE; @@ -663,8 +669,8 @@ if (palloc->pa_backingmapptr != NULL) { pa_reclaim_register(palloc); } - palloc->pa_flags |= PA_INITIALIZED; } + mutex_exit(&pool_allocator_lock); if (align == 0) align = ALIGN(1); @@ -892,6 +898,11 @@ TAILQ_REMOVE(&pp->pr_alloc->pa_list, pp, pr_alloc_list); mutex_exit(&pp->pr_alloc->pa_lock); + mutex_enter(&pool_allocator_lock); + if (--pp->pr_alloc->pa_refcnt == 0) + mutex_destroy(&pp->pr_alloc->pa_lock); + mutex_exit(&pool_allocator_lock); + mutex_enter(&pp->pr_lock); KASSERT(pp->pr_cache == NULL); Index: src/sys/sys/pool.h diff -u src/sys/sys/pool.h:1.67 src/sys/sys/pool.h:1.68 --- src/sys/sys/pool.h:1.67 Thu Oct 15 20:50:12 2009 +++ src/sys/sys/pool.h Wed Dec 30 18:57:16 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: pool.h,v 1.67 2009/10/15 20:50:12 thorpej Exp $ */ +/* $NetBSD: pool.h,v 1.68 2009/12/30 18:57:16 elad Exp $ */ /*- * Copyright (c) 1997, 1998, 1999, 2000, 2007 The NetBSD Foundation, Inc. @@ -63,8 +63,7 @@ /* The following fields are for internal use only. */ kmutex_t pa_lock; TAILQ_HEAD(, pool) pa_list; /* list of pools using this allocator */ - int pa_flags; -#define PA_INITIALIZED 0x01 + uint32_t pa_refcnt; /* number of pools using this allocator */ int pa_pagemask; int pa_pageshift; struct vm_map *pa_backingmap;