Subject: Initialising the same pool multiple times
To: None <tech-kern@netbsd.org>
From: Simon Burge <simonb@wasabisystems.com>
List: tech-kern
Date: 02/13/2006 17:28:55
Hi folks,
At the moment, it's possible to call pool_init() multiple times for
same pool. Currently, this corrupts the "all-pools" list such that
"vmstat -m" will now endlessly loop. The patch below panics if this
happens when DIAGNOSTIC is enabled, and otherwise prints a warning
then returns early..
Is this the best way to handle this condition? Should the warning be
inside an "#ifdef DEBUG" check?
This same problem also affects the netbsd-3 branch, but because
the all-pools list uses a tailq instead of a list, you need to
s/LIST_FOREACH/TAILQ_FOREACH/.
Note that if you have multiple raid sets with RAIDframe you'll
trigger this condition. Greg Oster will fix that side of things
in the next day or so...
Cheers,
Simon.
--
Simon Burge <simonb@wasabisystems.com>
NetBSD Development, Support and Service: http://www.wasabisystems.com/
Index: subr_pool.c
===================================================================
RCS file: /cvsroot/src/sys/kern/subr_pool.c,v
retrieving revision 1.111
diff -d -p -u -r1.111 subr_pool.c
--- subr_pool.c 26 Jan 2006 15:07:25 -0000 1.111
+++ subr_pool.c 13 Feb 2006 05:10:31 -0000
@@ -467,13 +467,29 @@ void
pool_init(struct pool *pp, size_t size, u_int align, u_int ioff, int flags,
const char *wchan, struct pool_allocator *palloc)
{
- int off, slack;
+ struct pool *pp1;
size_t trysize, phsize;
- int s;
+ int off, slack, s;
KASSERT((1UL << (CHAR_BIT * sizeof(pool_item_freelist_t))) - 2 >=
PHPOOL_FREELIST_NELEM(PHPOOL_MAX - 1));
+ /*
+ * Check that the pool hasn't already been initialised and
+ * added to the list of all pools.
+ */
+ LIST_FOREACH(pp1, &pool_head, pr_poollist) {
+ if (pp == pp1) {
+#ifdef DIAGNOSTIC
+ panic("pool_init: pool %s already initialised",
+ wchan);
+#endif
+ printf("pool_init: pool %s already initialised\n",
+ wchan);
+ return;
+ }
+ }
+
#ifdef POOL_DIAGNOSTIC
/*
* Always log if POOL_DIAGNOSTIC is defined.