[BACK]Return to subr_pool.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / kern

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/kern/subr_pool.c between version 1.138.2.3 and 1.140

version 1.138.2.3, 2007/12/13 05:06:01 version 1.140, 2007/12/13 01:22:50
Line 40 
Line 40 
 #include <sys/cdefs.h>  #include <sys/cdefs.h>
 __KERNEL_RCSID(0, "$NetBSD$");  __KERNEL_RCSID(0, "$NetBSD$");
   
 #include "opt_ddb.h"  
 #include "opt_pool.h"  #include "opt_pool.h"
 #include "opt_poollog.h"  #include "opt_poollog.h"
 #include "opt_lockdebug.h"  #include "opt_lockdebug.h"
Line 102  static void pool_page_free_meta(struct p
Line 101  static void pool_page_free_meta(struct p
 /* allocator for pool metadata */  /* allocator for pool metadata */
 struct pool_allocator pool_allocator_meta = {  struct pool_allocator pool_allocator_meta = {
         pool_page_alloc_meta, pool_page_free_meta,          pool_page_alloc_meta, pool_page_free_meta,
         .pa_backingmapptr = &kernel_map,          .pa_backingmapptr = &kmem_map,
 };  };
   
 /* # of seconds to retain page after last use */  /* # of seconds to retain page after last use */
Line 128  struct pool_item_header {
Line 127  struct pool_item_header {
         void *                  ph_page;        /* this page's address */          void *                  ph_page;        /* this page's address */
         struct timeval          ph_time;        /* last referenced */          struct timeval          ph_time;        /* last referenced */
         uint16_t                ph_nmissing;    /* # of chunks in use */          uint16_t                ph_nmissing;    /* # of chunks in use */
         uint16_t                ph_off;         /* start offset in page */  
         union {          union {
                 /* !PR_NOTOUCH */                  /* !PR_NOTOUCH */
                 struct {                  struct {
Line 137  struct pool_item_header {
Line 135  struct pool_item_header {
                 } phu_normal;                  } phu_normal;
                 /* PR_NOTOUCH */                  /* PR_NOTOUCH */
                 struct {                  struct {
                         pool_item_bitmap_t phu_bitmap[1];                          uint16_t phu_off;       /* start offset in page */
                           pool_item_bitmap_t phu_bitmap[];
                 } phu_notouch;                  } phu_notouch;
         } ph_u;          } ph_u;
 };  };
 #define ph_itemlist     ph_u.phu_normal.phu_itemlist  #define ph_itemlist     ph_u.phu_normal.phu_itemlist
   #define ph_off          ph_u.phu_notouch.phu_off
 #define ph_bitmap       ph_u.phu_notouch.phu_bitmap  #define ph_bitmap       ph_u.phu_notouch.phu_bitmap
   
 struct pool_item {  struct pool_item {
Line 381  pr_item_notouch_get(const struct pool *p
Line 381  pr_item_notouch_get(const struct pool *p
 }  }
   
 static inline void  static inline void
 pr_item_notouch_init(const struct pool *pp, struct pool_item_header *ph)  pr_item_notouch_init(const struct pool *pp, struct pool_item_header *ph,
       unsigned int offset)
 {  {
         pool_item_bitmap_t *bitmap = ph->ph_bitmap;          pool_item_bitmap_t *bitmap = ph->ph_bitmap;
         const int n = howmany(pp->pr_itemsperpage, BITMAP_SIZE);          const int n = howmany(pp->pr_itemsperpage, BITMAP_SIZE);
         int i;          int i;
   
           ph->ph_off = offset;
         for (i = 0; i < n; i++) {          for (i = 0; i < n; i++) {
                 bitmap[i] = (pool_item_bitmap_t)-1;                  bitmap[i] = (pool_item_bitmap_t)-1;
         }          }
Line 412  phtree_compare(struct pool_item_header *
Line 414  phtree_compare(struct pool_item_header *
 SPLAY_PROTOTYPE(phtree, pool_item_header, ph_node, phtree_compare);  SPLAY_PROTOTYPE(phtree, pool_item_header, ph_node, phtree_compare);
 SPLAY_GENERATE(phtree, pool_item_header, ph_node, phtree_compare);  SPLAY_GENERATE(phtree, pool_item_header, ph_node, phtree_compare);
   
 static inline struct pool_item_header *  
 pr_find_pagehead_noalign(struct pool *pp, void *v)  
 {  
         struct pool_item_header *ph, tmp;  
   
         tmp.ph_page = (void *)(uintptr_t)v;  
         ph = SPLAY_FIND(phtree, &pp->pr_phtree, &tmp);  
         if (ph == NULL) {  
                 ph = SPLAY_ROOT(&pp->pr_phtree);  
                 if (ph != NULL && phtree_compare(&tmp, ph) >= 0) {  
                         ph = SPLAY_NEXT(phtree, &pp->pr_phtree, ph);  
                 }  
                 KASSERT(ph == NULL || phtree_compare(&tmp, ph) < 0);  
         }  
   
         return ph;  
 }  
   
 /*  /*
  * Return the pool page header based on item address.   * Return the pool page header based on item address.
  */   */
Line 439  pr_find_pagehead(struct pool *pp, void *
Line 423  pr_find_pagehead(struct pool *pp, void *
         struct pool_item_header *ph, tmp;          struct pool_item_header *ph, tmp;
   
         if ((pp->pr_roflags & PR_NOALIGN) != 0) {          if ((pp->pr_roflags & PR_NOALIGN) != 0) {
                 ph = pr_find_pagehead_noalign(pp, v);                  tmp.ph_page = (void *)(uintptr_t)v;
                   ph = SPLAY_FIND(phtree, &pp->pr_phtree, &tmp);
                   if (ph == NULL) {
                           ph = SPLAY_ROOT(&pp->pr_phtree);
                           if (ph != NULL && phtree_compare(&tmp, ph) >= 0) {
                                   ph = SPLAY_NEXT(phtree, &pp->pr_phtree, ph);
                           }
                           KASSERT(ph == NULL || phtree_compare(&tmp, ph) < 0);
                   }
         } else {          } else {
                 void *page =                  void *page =
                     (void *)((uintptr_t)v & pp->pr_alloc->pa_pagemask);                      (void *)((uintptr_t)v & pp->pr_alloc->pa_pagemask);
Line 800  pool_init(struct pool *pp, size_t size, 
Line 792  pool_init(struct pool *pp, size_t size, 
   
 #ifdef POOL_DIAGNOSTIC  #ifdef POOL_DIAGNOSTIC
         if (flags & PR_LOGGING) {          if (flags & PR_LOGGING) {
                 if (kernel_map == NULL ||                  if (kmem_map == NULL ||
                     (pp->pr_log = malloc(pool_logsize * sizeof(struct pool_log),                      (pp->pr_log = malloc(pool_logsize * sizeof(struct pool_log),
                      M_TEMP, M_NOWAIT)) == NULL)                       M_TEMP, M_NOWAIT)) == NULL)
                         pp->pr_roflags &= ~PR_LOGGING;                          pp->pr_roflags &= ~PR_LOGGING;
Line 1446  pool_prime_page(struct pool *pp, void *s
Line 1438  pool_prime_page(struct pool *pp, void *s
         /*          /*
          * Color this page.           * Color this page.
          */           */
         ph->ph_off = pp->pr_curcolor;          cp = (char *)cp + pp->pr_curcolor;
         cp = (char *)cp + ph->ph_off;  
         if ((pp->pr_curcolor += align) > pp->pr_maxcolor)          if ((pp->pr_curcolor += align) > pp->pr_maxcolor)
                 pp->pr_curcolor = 0;                  pp->pr_curcolor = 0;
   
Line 1466  pool_prime_page(struct pool *pp, void *s
Line 1457  pool_prime_page(struct pool *pp, void *s
         pp->pr_nitems += n;          pp->pr_nitems += n;
   
         if (pp->pr_roflags & PR_NOTOUCH) {          if (pp->pr_roflags & PR_NOTOUCH) {
                 pr_item_notouch_init(pp, ph);                  pr_item_notouch_init(pp, ph, (char *)cp - (char *)storage);
         } else {          } else {
                 while (n--) {                  while (n--) {
                         pi = (struct pool_item *)cp;                          pi = (struct pool_item *)cp;
Line 2122  pool_cache_bootstrap(pool_cache_t pc, si
Line 2113  pool_cache_bootstrap(pool_cache_t pc, si
 void  void
 pool_cache_destroy(pool_cache_t pc)  pool_cache_destroy(pool_cache_t pc)
 {  {
   
         pool_cache_bootstrap_destroy(pc);  
         pool_put(&cache_pool, pc);  
 }  
   
 /*  
  * pool_cache_bootstrap_destroy:  
  *  
  *      Kernel-private version of pool_cache_destroy().  
  *      Destroy a pool cache initialized by pool_cache_bootstrap.  
  */  
 void  
 pool_cache_bootstrap_destroy(pool_cache_t pc)  
 {  
         struct pool *pp = &pc->pc_pool;          struct pool *pp = &pc->pc_pool;
         pool_cache_cpu_t *cc;          pool_cache_cpu_t *cc;
         pcg_t *pcg;          pcg_t *pcg;
Line 2175  pool_cache_bootstrap_destroy(pool_cache_
Line 2152  pool_cache_bootstrap_destroy(pool_cache_
         /* Finally, destroy it. */          /* Finally, destroy it. */
         mutex_destroy(&pc->pc_lock);          mutex_destroy(&pc->pc_lock);
         pool_destroy(pp);          pool_destroy(pp);
           pool_put(&cache_pool, pc);
 }  }
   
 /*  /*
Line 2766  void pool_page_free(struct pool *, void 
Line 2744  void pool_page_free(struct pool *, void 
 #ifdef POOL_SUBPAGE  #ifdef POOL_SUBPAGE
 struct pool_allocator pool_allocator_kmem_fullpage = {  struct pool_allocator pool_allocator_kmem_fullpage = {
         pool_page_alloc, pool_page_free, 0,          pool_page_alloc, pool_page_free, 0,
         .pa_backingmapptr = &kernel_map,          .pa_backingmapptr = &kmem_map,
 };  };
 #else  #else
 struct pool_allocator pool_allocator_kmem = {  struct pool_allocator pool_allocator_kmem = {
         pool_page_alloc, pool_page_free, 0,          pool_page_alloc, pool_page_free, 0,
         .pa_backingmapptr = &kernel_map,          .pa_backingmapptr = &kmem_map,
 };  };
 #endif  #endif
   
Line 2796  void pool_subpage_free(struct pool *, vo
Line 2774  void pool_subpage_free(struct pool *, vo
   
 struct pool_allocator pool_allocator_kmem = {  struct pool_allocator pool_allocator_kmem = {
         pool_subpage_alloc, pool_subpage_free, POOL_SUBPAGE,          pool_subpage_alloc, pool_subpage_free, POOL_SUBPAGE,
         .pa_backingmapptr = &kernel_map,          .pa_backingmapptr = &kmem_map,
 };  };
   
 void    *pool_subpage_alloc_nointr(struct pool *, int);  void    *pool_subpage_alloc_nointr(struct pool *, int);
Line 2804  void pool_subpage_free_nointr(struct poo
Line 2782  void pool_subpage_free_nointr(struct poo
   
 struct pool_allocator pool_allocator_nointr = {  struct pool_allocator pool_allocator_nointr = {
         pool_subpage_alloc, pool_subpage_free, POOL_SUBPAGE,          pool_subpage_alloc, pool_subpage_free, POOL_SUBPAGE,
         .pa_backingmapptr = &kernel_map,          .pa_backingmapptr = &kmem_map,
 };  };
 #endif /* POOL_SUBPAGE */  #endif /* POOL_SUBPAGE */
   
Line 2842  pool_page_alloc(struct pool *pp, int fla
Line 2820  pool_page_alloc(struct pool *pp, int fla
 {  {
         bool waitok = (flags & PR_WAITOK) ? true : false;          bool waitok = (flags & PR_WAITOK) ? true : false;
   
         return ((void *) uvm_km_alloc_poolpage_cache(kernel_map, waitok));          return ((void *) uvm_km_alloc_poolpage_cache(kmem_map, waitok));
 }  }
   
 void  void
 pool_page_free(struct pool *pp, void *v)  pool_page_free(struct pool *pp, void *v)
 {  {
   
         uvm_km_free_poolpage_cache(kernel_map, (vaddr_t) v);          uvm_km_free_poolpage_cache(kmem_map, (vaddr_t) v);
 }  }
   
 static void *  static void *
Line 2857  pool_page_alloc_meta(struct pool *pp, in
Line 2835  pool_page_alloc_meta(struct pool *pp, in
 {  {
         bool waitok = (flags & PR_WAITOK) ? true : false;          bool waitok = (flags & PR_WAITOK) ? true : false;
   
         return ((void *) uvm_km_alloc_poolpage(kernel_map, waitok));          return ((void *) uvm_km_alloc_poolpage(kmem_map, waitok));
 }  }
   
 static void  static void
 pool_page_free_meta(struct pool *pp, void *v)  pool_page_free_meta(struct pool *pp, void *v)
 {  {
   
         uvm_km_free_poolpage(kernel_map, (vaddr_t) v);          uvm_km_free_poolpage(kmem_map, (vaddr_t) v);
 }  }
   
 #ifdef POOL_SUBPAGE  #ifdef POOL_SUBPAGE
Line 2910  pool_page_free_nointr(struct pool *pp, v
Line 2888  pool_page_free_nointr(struct pool *pp, v
   
         uvm_km_free_poolpage_cache(kernel_map, (vaddr_t) v);          uvm_km_free_poolpage_cache(kernel_map, (vaddr_t) v);
 }  }
   
 #if defined(DDB)  
 static bool  
 pool_in_page(struct pool *pp, struct pool_item_header *ph, uintptr_t addr)  
 {  
   
         return (uintptr_t)ph->ph_page <= addr &&  
             addr < (uintptr_t)ph->ph_page + pp->pr_alloc->pa_pagesz;  
 }  
   
 void  
 pool_whatis(uintptr_t addr, void (*pr)(const char *, ...))  
 {  
         struct pool *pp;  
   
         LIST_FOREACH(pp, &pool_head, pr_poollist) {  
                 struct pool_item_header *ph;  
                 uintptr_t item;  
   
                 if ((pp->pr_roflags & PR_PHINPAGE) != 0) {  
                         LIST_FOREACH(ph, &pp->pr_fullpages, ph_pagelist) {  
                                 if (pool_in_page(pp, ph, addr)) {  
                                         goto found;  
                                 }  
                         }  
                         LIST_FOREACH(ph, &pp->pr_partpages, ph_pagelist) {  
                                 if (pool_in_page(pp, ph, addr)) {  
                                         goto found;  
                                 }  
                         }  
                         continue;  
                 } else {  
                         ph = pr_find_pagehead_noalign(pp, (void *)addr);  
                         if (ph == NULL || !pool_in_page(pp, ph, addr)) {  
                                 continue;  
                         }  
                 }  
 found:  
                 item = (uintptr_t)ph->ph_page + ph->ph_off;  
                 item = item + rounddown(addr - item, pp->pr_size);  
                 (*pr)("%p is %p+%zu from POOL '%s'\n",  
                     (void *)addr, item, (size_t)(addr - item),  
                     pp->pr_wchan);  
         }  
 }  
 #endif /* defined(DDB) */  

Legend:
Removed from v.1.138.2.3  
changed lines
  Added in v.1.140

CVSweb <webmaster@jp.NetBSD.org>