[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.221.2.3 and 1.221.2.4

version 1.221.2.3, 2018/09/30 01:45:55 version 1.221.2.4, 2018/12/26 14:02:04
Line 1 
Line 1 
 /*      $NetBSD$        */  /*      $NetBSD$        */
   
 /*-  /*
  * Copyright (c) 1997, 1999, 2000, 2002, 2007, 2008, 2010, 2014, 2015   * Copyright (c) 1997, 1999, 2000, 2002, 2007, 2008, 2010, 2014, 2015, 2018
  *     The NetBSD Foundation, Inc.   *     The NetBSD Foundation, Inc.
  * All rights reserved.   * All rights reserved.
  *   *
Line 38  __KERNEL_RCSID(0, "$NetBSD$");
Line 38  __KERNEL_RCSID(0, "$NetBSD$");
 #ifdef _KERNEL_OPT  #ifdef _KERNEL_OPT
 #include "opt_ddb.h"  #include "opt_ddb.h"
 #include "opt_lockdebug.h"  #include "opt_lockdebug.h"
   #include "opt_kleak.h"
 #endif  #endif
   
 #include <sys/param.h>  #include <sys/param.h>
Line 99  static struct pool psppool;
Line 100  static struct pool psppool;
 static void pool_redzone_init(struct pool *, size_t);  static void pool_redzone_init(struct pool *, size_t);
 static void pool_redzone_fill(struct pool *, void *);  static void pool_redzone_fill(struct pool *, void *);
 static void pool_redzone_check(struct pool *, void *);  static void pool_redzone_check(struct pool *, void *);
   static void pool_cache_redzone_check(pool_cache_t, void *);
 #else  #else
 # define pool_redzone_init(pp, sz)      /* NOTHING */  # define pool_redzone_init(pp, sz)              __nothing
 # define pool_redzone_fill(pp, ptr)     /* NOTHING */  # define pool_redzone_fill(pp, ptr)             __nothing
 # define pool_redzone_check(pp, ptr)    /* NOTHING */  # define pool_redzone_check(pp, ptr)            __nothing
   # define pool_cache_redzone_check(pc, ptr)      __nothing
 #endif  #endif
   
   #ifdef KLEAK
   static void pool_kleak_fill(struct pool *, void *);
   static void pool_cache_kleak_fill(pool_cache_t, void *);
   #else
   #define pool_kleak_fill(pp, ptr)        __nothing
   #define pool_cache_kleak_fill(pc, ptr)  __nothing
   #endif
   
   #define pc_has_ctor(pc) \
           (pc->pc_ctor != (int (*)(void *, void *, int))nullop)
   #define pc_has_dtor(pc) \
           (pc->pc_dtor != (void (*)(void *, void *))nullop)
   
 static void *pool_page_alloc_meta(struct pool *, int);  static void *pool_page_alloc_meta(struct pool *, int);
 static void pool_page_free_meta(struct pool *, void *);  static void pool_page_free_meta(struct pool *, void *);
   
Line 161  struct pool_item_header {
Line 177  struct pool_item_header {
 #define ph_itemlist     ph_u.phu_normal.phu_itemlist  #define ph_itemlist     ph_u.phu_normal.phu_itemlist
 #define ph_bitmap       ph_u.phu_notouch.phu_bitmap  #define ph_bitmap       ph_u.phu_notouch.phu_bitmap
   
   #if defined(DIAGNOSTIC) && !defined(KASAN)
   #define POOL_CHECK_MAGIC
   #endif
   
 struct pool_item {  struct pool_item {
 #ifdef DIAGNOSTIC  #ifdef POOL_CHECK_MAGIC
         u_int pi_magic;          u_int pi_magic;
 #endif  #endif
 #define PI_MAGIC 0xdeaddeadU  #define PI_MAGIC 0xdeaddeadU
Line 881  pool_get(struct pool *pp, int flags)
Line 901  pool_get(struct pool *pp, int flags)
                 KASSERTMSG((pp->pr_nitems > 0),                  KASSERTMSG((pp->pr_nitems > 0),
                     "%s: [%s] nitems %u inconsistent on itemlist",                      "%s: [%s] nitems %u inconsistent on itemlist",
                     __func__, pp->pr_wchan, pp->pr_nitems);                      __func__, pp->pr_wchan, pp->pr_nitems);
   #ifdef POOL_CHECK_MAGIC
                 KASSERTMSG((pi->pi_magic == PI_MAGIC),                  KASSERTMSG((pi->pi_magic == PI_MAGIC),
                     "%s: [%s] free list modified: "                      "%s: [%s] free list modified: "
                     "magic=%x; page %p; item addr %p", __func__,                      "magic=%x; page %p; item addr %p", __func__,
                     pp->pr_wchan, pi->pi_magic, ph->ph_page, pi);                      pp->pr_wchan, pi->pi_magic, ph->ph_page, pi);
   #endif
   
                 /*                  /*
                  * Remove from item list.                   * Remove from item list.
Line 937  pool_get(struct pool *pp, int flags)
Line 959  pool_get(struct pool *pp, int flags)
         KASSERT((((vaddr_t)v + pp->pr_itemoffset) & (pp->pr_align - 1)) == 0);          KASSERT((((vaddr_t)v + pp->pr_itemoffset) & (pp->pr_align - 1)) == 0);
         FREECHECK_OUT(&pp->pr_freecheck, v);          FREECHECK_OUT(&pp->pr_freecheck, v);
         pool_redzone_fill(pp, v);          pool_redzone_fill(pp, v);
           pool_kleak_fill(pp, v);
         return (v);          return (v);
 }  }
   
Line 967  pool_do_put(struct pool *pp, void *v, st
Line 990  pool_do_put(struct pool *pp, void *v, st
         if (pp->pr_roflags & PR_NOTOUCH) {          if (pp->pr_roflags & PR_NOTOUCH) {
                 pr_item_notouch_put(pp, ph, v);                  pr_item_notouch_put(pp, ph, v);
         } else {          } else {
 #ifdef DIAGNOSTIC  #ifdef POOL_CHECK_MAGIC
                 pi->pi_magic = PI_MAGIC;                  pi->pi_magic = PI_MAGIC;
 #endif  #endif
 #ifdef DEBUG  
                 {  
                         int i, *ip = v;  
   
                         for (i = 0; i < pp->pr_size / sizeof(int); i++) {                  if (pp->pr_redzone) {
                                 *ip++ = PI_MAGIC;                          /*
                         }                           * Mark the pool_item as valid. The rest is already
                            * invalid.
                            */
                           kasan_mark(pi, sizeof(*pi), sizeof(*pi));
                 }                  }
 #endif  
   
                 LIST_INSERT_HEAD(&ph->ph_itemlist, pi, pi_list);                  LIST_INSERT_HEAD(&ph->ph_itemlist, pi, pi_list);
         }          }
Line 1227  pool_prime_page(struct pool *pp, void *s
Line 1249  pool_prime_page(struct pool *pp, void *s
   
                         /* Insert on page list */                          /* Insert on page list */
                         LIST_INSERT_HEAD(&ph->ph_itemlist, pi, pi_list);                          LIST_INSERT_HEAD(&ph->ph_itemlist, pi, pi_list);
 #ifdef DIAGNOSTIC  #ifdef POOL_CHECK_MAGIC
                         pi->pi_magic = PI_MAGIC;                          pi->pi_magic = PI_MAGIC;
 #endif  #endif
                         cp = (char *)cp + pp->pr_size;                          cp = (char *)cp + pp->pr_size;
Line 1530  pool_print_pagelist(struct pool *pp, str
Line 1552  pool_print_pagelist(struct pool *pp, str
     void (*pr)(const char *, ...))      void (*pr)(const char *, ...))
 {  {
         struct pool_item_header *ph;          struct pool_item_header *ph;
         struct pool_item *pi __diagused;  
   
         LIST_FOREACH(ph, pl, ph_pagelist) {          LIST_FOREACH(ph, pl, ph_pagelist) {
                 (*pr)("\t\tpage %p, nmissing %d, time %" PRIu32 "\n",                  (*pr)("\t\tpage %p, nmissing %d, time %" PRIu32 "\n",
                     ph->ph_page, ph->ph_nmissing, ph->ph_time);                      ph->ph_page, ph->ph_nmissing, ph->ph_time);
 #ifdef DIAGNOSTIC  #ifdef POOL_CHECK_MAGIC
                   struct pool_item *pi;
                 if (!(pp->pr_roflags & PR_NOTOUCH)) {                  if (!(pp->pr_roflags & PR_NOTOUCH)) {
                         LIST_FOREACH(pi, &ph->ph_itemlist, pi_list) {                          LIST_FOREACH(pi, &ph->ph_itemlist, pi_list) {
                                 if (pi->pi_magic != PI_MAGIC) {                                  if (pi->pi_magic != PI_MAGIC) {
Line 1690  pool_chk_page(struct pool *pp, const cha
Line 1712  pool_chk_page(struct pool *pp, const cha
              pi != NULL;               pi != NULL;
              pi = LIST_NEXT(pi,pi_list), n++) {               pi = LIST_NEXT(pi,pi_list), n++) {
   
 #ifdef DIAGNOSTIC  #ifdef POOL_CHECK_MAGIC
                 if (pi->pi_magic != PI_MAGIC) {                  if (pi->pi_magic != PI_MAGIC) {
                         if (label != NULL)                          if (label != NULL)
                                 printf("%s: ", label);                                  printf("%s: ", label);
Line 1996  pool_cache_reclaim(pool_cache_t pc)
Line 2018  pool_cache_reclaim(pool_cache_t pc)
 static void  static void
 pool_cache_destruct_object1(pool_cache_t pc, void *object)  pool_cache_destruct_object1(pool_cache_t pc, void *object)
 {  {
           if (pc->pc_pool.pr_redzone) {
                   /*
                    * The object is marked as invalid. Temporarily mark it as
                    * valid for the destructor. pool_put below will re-mark it
                    * as invalid.
                    */
                   kasan_mark(object, pc->pc_pool.pr_reqsize,
                       pc->pc_pool.pr_reqsize_with_redzone);
           }
   
         (*pc->pc_dtor)(pc->pc_arg, object);          (*pc->pc_dtor)(pc->pc_arg, object);
         pool_put(&pc->pc_pool, object);          pool_put(&pc->pc_pool, object);
Line 2256  pool_cache_get_slow(pool_cache_cpu_t *cc
Line 2287  pool_cache_get_slow(pool_cache_cpu_t *cc
   
         FREECHECK_OUT(&pc->pc_freecheck, object);          FREECHECK_OUT(&pc->pc_freecheck, object);
         pool_redzone_fill(&pc->pc_pool, object);          pool_redzone_fill(&pc->pc_pool, object);
           pool_cache_kleak_fill(pc, object);
         return false;          return false;
 }  }
   
Line 2303  pool_cache_get_paddr(pool_cache_t pc, in
Line 2335  pool_cache_get_paddr(pool_cache_t pc, in
                         splx(s);                          splx(s);
                         FREECHECK_OUT(&pc->pc_freecheck, object);                          FREECHECK_OUT(&pc->pc_freecheck, object);
                         pool_redzone_fill(&pc->pc_pool, object);                          pool_redzone_fill(&pc->pc_pool, object);
                           pool_cache_kleak_fill(pc, object);
                         return object;                          return object;
                 }                  }
   
Line 2451  pool_cache_put_paddr(pool_cache_t pc, vo
Line 2484  pool_cache_put_paddr(pool_cache_t pc, vo
         int s;          int s;
   
         KASSERT(object != NULL);          KASSERT(object != NULL);
         pool_redzone_check(&pc->pc_pool, object);          pool_cache_redzone_check(pc, object);
         FREECHECK_IN(&pc->pc_freecheck, object);          FREECHECK_IN(&pc->pc_freecheck, object);
   
         /* Lock out interrupts and disable preemption. */          /* Lock out interrupts and disable preemption. */
Line 2685  pool_allocator_free(struct pool *pp, voi
Line 2718  pool_allocator_free(struct pool *pp, voi
 {  {
         struct pool_allocator *pa = pp->pr_alloc;          struct pool_allocator *pa = pp->pr_alloc;
   
           if (pp->pr_redzone) {
                   kasan_mark(v, pa->pa_pagesz, pa->pa_pagesz);
           }
         (*pa->pa_free)(pp, v);          (*pa->pa_free)(pp, v);
 }  }
   
Line 2728  pool_page_free_meta(struct pool *pp, voi
Line 2764  pool_page_free_meta(struct pool *pp, voi
         vmem_free(kmem_meta_arena, (vmem_addr_t)v, pp->pr_alloc->pa_pagesz);          vmem_free(kmem_meta_arena, (vmem_addr_t)v, pp->pr_alloc->pa_pagesz);
 }  }
   
   #ifdef KLEAK
   static void
   pool_kleak_fill(struct pool *pp, void *p)
   {
           if (__predict_false(pp->pr_roflags & PR_NOTOUCH)) {
                   return;
           }
           kleak_fill_area(p, pp->pr_size);
   }
   
   static void
   pool_cache_kleak_fill(pool_cache_t pc, void *p)
   {
           if (__predict_false(pc_has_ctor(pc) || pc_has_dtor(pc))) {
                   return;
           }
           pool_kleak_fill(&pc->pc_pool, p);
   }
   #endif
   
 #ifdef POOL_REDZONE  #ifdef POOL_REDZONE
 #if defined(_LP64)  #if defined(_LP64)
 # define PRIME 0x9e37fffffffc0000UL  # define PRIME 0x9e37fffffffc0000UL
Line 2772  pool_redzone_init(struct pool *pp, size_
Line 2828  pool_redzone_init(struct pool *pp, size_
          */           */
         if (pp->pr_size - requested_size >= redzsz) {          if (pp->pr_size - requested_size >= redzsz) {
                 pp->pr_reqsize = requested_size;                  pp->pr_reqsize = requested_size;
                   pp->pr_reqsize_with_redzone = requested_size + redzsz;
                 pp->pr_redzone = true;                  pp->pr_redzone = true;
                 return;                  return;
         }          }
Line 2785  pool_redzone_init(struct pool *pp, size_
Line 2842  pool_redzone_init(struct pool *pp, size_
                 /* Ok, we can */                  /* Ok, we can */
                 pp->pr_size = nsz;                  pp->pr_size = nsz;
                 pp->pr_reqsize = requested_size;                  pp->pr_reqsize = requested_size;
                   pp->pr_reqsize_with_redzone = requested_size + redzsz;
                 pp->pr_redzone = true;                  pp->pr_redzone = true;
         } else {          } else {
                 /* No space for a red zone... snif :'( */                  /* No space for a red zone... snif :'( */
Line 2800  pool_redzone_fill(struct pool *pp, void 
Line 2858  pool_redzone_fill(struct pool *pp, void 
         if (!pp->pr_redzone)          if (!pp->pr_redzone)
                 return;                  return;
 #ifdef KASAN  #ifdef KASAN
         size_t size_with_redzone = pp->pr_reqsize;          kasan_mark(p, pp->pr_reqsize, pp->pr_reqsize_with_redzone);
         kasan_add_redzone(&size_with_redzone);  
         kasan_alloc(p, pp->pr_reqsize, size_with_redzone);  
 #else  #else
         uint8_t *cp, pat;          uint8_t *cp, pat;
         const uint8_t *ep;          const uint8_t *ep;
Line 2831  pool_redzone_check(struct pool *pp, void
Line 2887  pool_redzone_check(struct pool *pp, void
         if (!pp->pr_redzone)          if (!pp->pr_redzone)
                 return;                  return;
 #ifdef KASAN  #ifdef KASAN
         size_t size_with_redzone = pp->pr_reqsize;          kasan_mark(p, 0, pp->pr_reqsize_with_redzone);
         kasan_add_redzone(&size_with_redzone);  
         kasan_free(p, size_with_redzone);  
 #else  #else
         uint8_t *cp, pat, expected;          uint8_t *cp, pat, expected;
         const uint8_t *ep;          const uint8_t *ep;
Line 2860  pool_redzone_check(struct pool *pp, void
Line 2914  pool_redzone_check(struct pool *pp, void
 #endif  #endif
 }  }
   
   static void
   pool_cache_redzone_check(pool_cache_t pc, void *p)
   {
   #ifdef KASAN
           /* If there is a ctor/dtor, leave the data as valid. */
           if (__predict_false(pc_has_ctor(pc) || pc_has_dtor(pc))) {
                   return;
           }
   #endif
           pool_redzone_check(&pc->pc_pool, p);
   }
   
 #endif /* POOL_REDZONE */  #endif /* POOL_REDZONE */
   
   

Legend:
Removed from v.1.221.2.3  
changed lines
  Added in v.1.221.2.4

CVSweb <webmaster@jp.NetBSD.org>