Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/kern/subr_pool.c,v retrieving revision 1.128.2.5 retrieving revision 1.128.2.6 diff -u -p -r1.128.2.5 -r1.128.2.6 --- src/sys/kern/subr_pool.c 2007/07/29 11:34:47 1.128.2.5 +++ src/sys/kern/subr_pool.c 2007/08/20 21:27:37 1.128.2.6 @@ -1,4 +1,4 @@ -/* $NetBSD: subr_pool.c,v 1.128.2.5 2007/07/29 11:34:47 ad Exp $ */ +/* $NetBSD: subr_pool.c,v 1.128.2.6 2007/08/20 21:27:37 ad Exp $ */ /*- * Copyright (c) 1997, 1999, 2000, 2002, 2007 The NetBSD Foundation, Inc. @@ -38,7 +38,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: subr_pool.c,v 1.128.2.5 2007/07/29 11:34:47 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_pool.c,v 1.128.2.6 2007/08/20 21:27:37 ad Exp $"); #include "opt_pool.h" #include "opt_poollog.h" @@ -1615,6 +1615,8 @@ pool_reclaim(struct pool *pp) * Drain pools, one at a time. * * Note, we must never be called from an interrupt context. + * + * XXX Pool can disappear while draining. */ void pool_drain(void *arg) @@ -2170,26 +2172,43 @@ pool_cache_destruct_object(struct pool_c pool_put(pc->pc_pool, object); } +/* + * pool_do_cache_invalidate_grouplist: + * + * Invalidate a single grouplist and destruct all objects. + * XXX This is too expensive. We should swap the list then + * unlock. + */ static void pool_do_cache_invalidate_grouplist(struct pool_cache_grouplist *pcgsl, struct pool_cache *pc, struct pool_pagelist *pq, struct pool_cache_grouplist *pcgdl) { - struct pool_cache_group *pcg, *npcg; + struct pool_cache_group *pcg; void *object; - for (pcg = LIST_FIRST(pcgsl); pcg != NULL; pcg = npcg) { - npcg = LIST_NEXT(pcg, pcg_list); + KASSERT(mutex_owned(&pc->pc_lock)); + KASSERT(mutex_owned(&pc->pc_pool->pr_lock)); + + while ((pcg = LIST_FIRST(pcgsl)) != NULL) { + pc->pc_ngroups--; + LIST_REMOVE(pcg, pcg_list); + LIST_INSERT_HEAD(pcgdl, pcg, pcg_list); + pc->pc_nitems -= pcg->pcg_avail; + mutex_exit(&pc->pc_pool->pr_lock); + mutex_exit(&pc->pc_lock); + while (pcg->pcg_avail != 0) { - pc->pc_nitems--; object = pcg_get(pcg, NULL); if (pc->pc_dtor != NULL) (*pc->pc_dtor)(pc->pc_arg, object); + mutex_enter(&pc->pc_pool->pr_lock); pool_do_put(pc->pc_pool, object, pq); + mutex_exit(&pc->pc_pool->pr_lock); } - pc->pc_ngroups--; - LIST_REMOVE(pcg, pcg_list); - LIST_INSERT_HEAD(pcgdl, pcg, pcg_list); + + mutex_enter(&pc->pc_lock); + mutex_enter(&pc->pc_pool->pr_lock); } }