Subject: pool page header allocation strategy
To: None <tech-kern@netbsd.org>
From: enami tsugutomo <enami@but-b.or.jp>
List: tech-kern
Date: 02/15/2004 11:31:19
Hi.

I'd like to change pool page header allocation strategy as follows:

	1) If the header fits in the page without wasting any items,
	   put it there.

	2) Don't put the header in the page if it may consume large
	   part of the page (only this is the current strategy) or it
	   may consume rather big item.

For example, on i386, pools like fdescpl or sigapl will be affected by
1) and pools like buf1k or buf2k will be affected by 2).

enami.

Index: subr_pool.c
===================================================================
RCS file: /cvsroot/src/sys/kern/subr_pool.c,v
retrieving revision 1.91
diff -c -r1.91 subr_pool.c
*** subr_pool.c	16 Jan 2004 12:47:37 -0000	1.91
--- subr_pool.c	15 Feb 2004 02:23:22 -0000
***************
*** 367,372 ****
--- 367,373 ----
      const char *wchan, struct pool_allocator *palloc)
  {
  	int off, slack;
+ 	size_t trysize, phsize;
  
  #ifdef POOL_DIAGNOSTIC
  	/*
***************
*** 458,473 ****
  
  	/*
  	 * Decide whether to put the page header off page to avoid
! 	 * wasting too large a part of the page. Off-page page headers
! 	 * go on a hash table, so we can match a returned item
! 	 * with its header based on the page address.
! 	 * We use 1/16 of the page size as the threshold (XXX: tune)
  	 */
! 	if (pp->pr_size < palloc->pa_pagesz/16) {
  		/* Use the end of the page for the page header */
  		pp->pr_roflags |= PR_PHINPAGE;
! 		pp->pr_phoffset = off = palloc->pa_pagesz -
! 		    ALIGN(sizeof(struct pool_item_header));
  	} else {
  		/* The page header will be taken from our page header pool */
  		pp->pr_phoffset = 0;
--- 459,484 ----
  
  	/*
  	 * Decide whether to put the page header off page to avoid
! 	 * wasting too large a part of the page or too big item.
! 	 * Off-page page headers go on a hash table, so we can match
! 	 * a returned item with its header based on the page address.
! 	 * We use 1/16 of the page size and about 8 times of the item
! 	 * size as the threshold (XXX: tune)
! 	 *
! 	 * However, we'll put the header into the page if we can put
! 	 * it without wasting any items.
! 	 *
! 	 * Silently enforce `0 <= ioff < align'.
  	 */
! 	pp->pr_itemoffset = ioff %= align;
! 	/* See the comment below about reserved bytes. */
! 	trysize = palloc->pa_pagesz - ((align - ioff) % align);
! 	phsize = ALIGN(sizeof(struct pool_item_header));
! 	if (pp->pr_size < MIN(palloc->pa_pagesz / 16, phsize << 3) ||
! 	    trysize / pp->pr_size == (trysize - phsize) / pp->pr_size) {
  		/* Use the end of the page for the page header */
  		pp->pr_roflags |= PR_PHINPAGE;
! 		pp->pr_phoffset = off = palloc->pa_pagesz - phsize;
  	} else {
  		/* The page header will be taken from our page header pool */
  		pp->pr_phoffset = 0;
***************
*** 479,488 ****
  	 * Alignment is to take place at `ioff' within the item. This means
  	 * we must reserve up to `align - 1' bytes on the page to allow
  	 * appropriate positioning of each item.
- 	 *
- 	 * Silently enforce `0 <= ioff < align'.
  	 */
- 	pp->pr_itemoffset = ioff = ioff % align;
  	pp->pr_itemsperpage = (off - ((align - ioff) % align)) / pp->pr_size;
  	KASSERT(pp->pr_itemsperpage != 0);
  
--- 490,496 ----