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.21 retrieving revision 1.21.2.4 diff -u -p -r1.21 -r1.21.2.4 --- src/sys/kern/subr_pool.c 1999/03/31 23:23:48 1.21 +++ src/sys/kern/subr_pool.c 1999/06/25 00:08:22 1.21.2.4 @@ -1,4 +1,4 @@ -/* $NetBSD: subr_pool.c,v 1.21 1999/03/31 23:23:48 thorpej Exp $ */ +/* $NetBSD: subr_pool.c,v 1.21.2.4 1999/06/25 00:08:22 perry Exp $ */ /*- * Copyright (c) 1997, 1999 The NetBSD Foundation, Inc. @@ -73,7 +73,10 @@ static struct pool phpool; int pool_inactive_time = 10; /* Next candidate for drainage (see pool_drain()) */ -static struct pool *drainpp = NULL; +static struct pool *drainpp; + +/* This spin lock protects both pool_head and drainpp. */ +struct simplelock pool_head_slock = SIMPLELOCK_INITIALIZER; struct pool_item_header { /* Page headers */ @@ -254,6 +257,14 @@ pr_rmpage(pp, ph) pp->pr_npages--; pp->pr_npagefree++; + if ((pp->pr_roflags & PR_PHINPAGE) == 0) { + int s; + LIST_REMOVE(ph, ph_hashlist); + s = splhigh(); + pool_put(&phpool, ph); + splx(s); + } + if (pp->pr_curpage == ph) { /* * Find a new non-empty page header, if any. @@ -267,11 +278,6 @@ pr_rmpage(pp, ph) pp->pr_curpage = ph; } - - if ((pp->pr_roflags & PR_PHINPAGE) == 0) { - LIST_REMOVE(ph, ph_hashlist); - pool_put(&phpool, ph); - } } /* @@ -363,7 +369,6 @@ pool_init(pp, size, align, ioff, flags, /* * Initialize the pool structure. */ - TAILQ_INSERT_TAIL(&pool_head, pp, pr_poollist); TAILQ_INIT(&pp->pr_pagelist); pp->pr_curpage = NULL; pp->pr_npages = 0; @@ -451,13 +456,17 @@ pool_init(pp, size, align, ioff, flags, /* * Initialize private page header pool if we haven't done so yet. + * XXX LOCKING. */ if (phpool.pr_size == 0) { pool_init(&phpool, sizeof(struct pool_item_header), 0, 0, 0, "phpool", 0, 0, 0, 0); } - return; + /* Insert into the list of all pools. */ + simple_lock(&pool_head_slock); + TAILQ_INSERT_TAIL(&pool_head, pp, pr_poollist); + simple_unlock(&pool_head_slock); } /* @@ -483,8 +492,11 @@ pool_destroy(pp) pr_rmpage(pp, ph); /* Remove from global pool list */ + simple_lock(&pool_head_slock); TAILQ_REMOVE(&pool_head, pp, pr_poollist); + /* XXX Only clear this if we were drainpp? */ drainpp = NULL; + simple_unlock(&pool_head_slock); #ifdef POOL_DIAGNOSTIC if ((pp->pr_roflags & PR_LOGGING) != 0) @@ -924,12 +936,14 @@ pool_prime_page(pp, storage) caddr_t cp = storage; unsigned int align = pp->pr_align; unsigned int ioff = pp->pr_itemoffset; - int n; + int s, n; if ((pp->pr_roflags & PR_PHINPAGE) != 0) { ph = (struct pool_item_header *)(cp + pp->pr_phoffset); } else { + s = splhigh(); ph = pool_get(&phpool, PR_URGENT); + splx(s); LIST_INSERT_HEAD(&pp->pr_hashtab[PR_HASH_INDEX(pp, cp)], ph, ph_hashlist); } @@ -1215,19 +1229,21 @@ pool_drain(arg) void *arg; { struct pool *pp; - int s = splimp(); + int s; - /* XXX:lock pool head */ - if (drainpp == NULL && (drainpp = TAILQ_FIRST(&pool_head)) == NULL) { - splx(s); - return; - } + s = splimp(); + simple_lock(&pool_head_slock); + + if (drainpp == NULL && (drainpp = TAILQ_FIRST(&pool_head)) == NULL) + goto out; pp = drainpp; drainpp = TAILQ_NEXT(pp, pr_poollist); - /* XXX:unlock pool head */ pool_reclaim(pp); + + out: + simple_unlock(&pool_head_slock); splx(s); }