The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/vm/uma_core.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2002, 2003, 2004, 2005 Jeffrey Roberson <jeff@FreeBSD.org>
    3  * Copyright (c) 2004, 2005 Bosko Milekic <bmilekic@FreeBSD.org>
    4  * Copyright (c) 2004-2006 Robert N. M. Watson
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice unmodified, this list of conditions, and the following
   12  *    disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   27  */
   28 
   29 /*
   30  * uma_core.c  Implementation of the Universal Memory allocator
   31  *
   32  * This allocator is intended to replace the multitude of similar object caches
   33  * in the standard FreeBSD kernel.  The intent is to be flexible as well as
   34  * effecient.  A primary design goal is to return unused memory to the rest of
   35  * the system.  This will make the system as a whole more flexible due to the
   36  * ability to move memory to subsystems which most need it instead of leaving
   37  * pools of reserved memory unused.
   38  *
   39  * The basic ideas stem from similar slab/zone based allocators whose algorithms
   40  * are well known.
   41  *
   42  */
   43 
   44 /*
   45  * TODO:
   46  *      - Improve memory usage for large allocations
   47  *      - Investigate cache size adjustments
   48  */
   49 
   50 #include <sys/cdefs.h>
   51 __FBSDID("$FreeBSD$");
   52 
   53 /* I should really use ktr.. */
   54 /*
   55 #define UMA_DEBUG 1
   56 #define UMA_DEBUG_ALLOC 1
   57 #define UMA_DEBUG_ALLOC_1 1
   58 */
   59 
   60 #include "opt_ddb.h"
   61 #include "opt_param.h"
   62 
   63 #include <sys/param.h>
   64 #include <sys/systm.h>
   65 #include <sys/kernel.h>
   66 #include <sys/types.h>
   67 #include <sys/queue.h>
   68 #include <sys/malloc.h>
   69 #include <sys/ktr.h>
   70 #include <sys/lock.h>
   71 #include <sys/sysctl.h>
   72 #include <sys/mutex.h>
   73 #include <sys/proc.h>
   74 #include <sys/sbuf.h>
   75 #include <sys/smp.h>
   76 #include <sys/vmmeter.h>
   77 
   78 #include <vm/vm.h>
   79 #include <vm/vm_object.h>
   80 #include <vm/vm_page.h>
   81 #include <vm/vm_param.h>
   82 #include <vm/vm_map.h>
   83 #include <vm/vm_kern.h>
   84 #include <vm/vm_extern.h>
   85 #include <vm/uma.h>
   86 #include <vm/uma_int.h>
   87 #include <vm/uma_dbg.h>
   88 
   89 #include <machine/vmparam.h>
   90 
   91 #include <ddb/ddb.h>
   92 
   93 /*
   94  * This is the zone and keg from which all zones are spawned.  The idea is that
   95  * even the zone & keg heads are allocated from the allocator, so we use the
   96  * bss section to bootstrap us.
   97  */
   98 static struct uma_keg masterkeg;
   99 static struct uma_zone masterzone_k;
  100 static struct uma_zone masterzone_z;
  101 static uma_zone_t kegs = &masterzone_k;
  102 static uma_zone_t zones = &masterzone_z;
  103 
  104 /* This is the zone from which all of uma_slab_t's are allocated. */
  105 static uma_zone_t slabzone;
  106 static uma_zone_t slabrefzone;  /* With refcounters (for UMA_ZONE_REFCNT) */
  107 
  108 /*
  109  * The initial hash tables come out of this zone so they can be allocated
  110  * prior to malloc coming up.
  111  */
  112 static uma_zone_t hashzone;
  113 
  114 /* The boot-time adjusted value for cache line alignment. */
  115 static int uma_align_cache = 16 - 1;
  116 
  117 static MALLOC_DEFINE(M_UMAHASH, "UMAHash", "UMA Hash Buckets");
  118 
  119 /*
  120  * Are we allowed to allocate buckets?
  121  */
  122 static int bucketdisable = 1;
  123 
  124 /* Linked list of all kegs in the system */
  125 static LIST_HEAD(,uma_keg) uma_kegs = LIST_HEAD_INITIALIZER(&uma_kegs);
  126 
  127 /* This mutex protects the keg list */
  128 static struct mtx uma_mtx;
  129 
  130 /* Linked list of boot time pages */
  131 static LIST_HEAD(,uma_slab) uma_boot_pages =
  132     LIST_HEAD_INITIALIZER(&uma_boot_pages);
  133 
  134 /* This mutex protects the boot time pages list */
  135 static struct mtx uma_boot_pages_mtx;
  136 
  137 /* Is the VM done starting up? */
  138 static int booted = 0;
  139 
  140 /* Maximum number of allowed items-per-slab if the slab header is OFFPAGE */
  141 static u_int uma_max_ipers;
  142 static u_int uma_max_ipers_ref;
  143 
  144 /*
  145  * This is the handle used to schedule events that need to happen
  146  * outside of the allocation fast path.
  147  */
  148 static struct callout uma_callout;
  149 #define UMA_TIMEOUT     20              /* Seconds for callout interval. */
  150 
  151 /*
  152  * This structure is passed as the zone ctor arg so that I don't have to create
  153  * a special allocation function just for zones.
  154  */
  155 struct uma_zctor_args {
  156         char *name;
  157         size_t size;
  158         uma_ctor ctor;
  159         uma_dtor dtor;
  160         uma_init uminit;
  161         uma_fini fini;
  162         uma_keg_t keg;
  163         int align;
  164         u_int32_t flags;
  165 };
  166 
  167 struct uma_kctor_args {
  168         uma_zone_t zone;
  169         size_t size;
  170         uma_init uminit;
  171         uma_fini fini;
  172         int align;
  173         u_int32_t flags;
  174 };
  175 
  176 struct uma_bucket_zone {
  177         uma_zone_t      ubz_zone;
  178         char            *ubz_name;
  179         int             ubz_entries;
  180 };
  181 
  182 #define BUCKET_MAX      128
  183 
  184 struct uma_bucket_zone bucket_zones[] = {
  185         { NULL, "16 Bucket", 16 },
  186         { NULL, "32 Bucket", 32 },
  187         { NULL, "64 Bucket", 64 },
  188         { NULL, "128 Bucket", 128 },
  189         { NULL, NULL, 0}
  190 };
  191 
  192 #define BUCKET_SHIFT    4
  193 #define BUCKET_ZONES    ((BUCKET_MAX >> BUCKET_SHIFT) + 1)
  194 
  195 /*
  196  * bucket_size[] maps requested bucket sizes to zones that allocate a bucket
  197  * of approximately the right size.
  198  */
  199 static uint8_t bucket_size[BUCKET_ZONES];
  200 
  201 /*
  202  * Flags and enumerations to be passed to internal functions.
  203  */
  204 enum zfreeskip { SKIP_NONE, SKIP_DTOR, SKIP_FINI };
  205 
  206 #define ZFREE_STATFAIL  0x00000001      /* Update zone failure statistic. */
  207 #define ZFREE_STATFREE  0x00000002      /* Update zone free statistic. */
  208 
  209 /* Prototypes.. */
  210 
  211 static void *obj_alloc(uma_zone_t, int, u_int8_t *, int);
  212 static void *page_alloc(uma_zone_t, int, u_int8_t *, int);
  213 static void *startup_alloc(uma_zone_t, int, u_int8_t *, int);
  214 static void page_free(void *, int, u_int8_t);
  215 static uma_slab_t slab_zalloc(uma_zone_t, int);
  216 static void cache_drain(uma_zone_t);
  217 static void bucket_drain(uma_zone_t, uma_bucket_t);
  218 static void bucket_cache_drain(uma_zone_t zone);
  219 static int keg_ctor(void *, int, void *, int);
  220 static void keg_dtor(void *, int, void *);
  221 static int zone_ctor(void *, int, void *, int);
  222 static void zone_dtor(void *, int, void *);
  223 static int zero_init(void *, int, int);
  224 static void zone_small_init(uma_zone_t zone);
  225 static void zone_large_init(uma_zone_t zone);
  226 static void zone_foreach(void (*zfunc)(uma_zone_t));
  227 static void zone_timeout(uma_zone_t zone);
  228 static int hash_alloc(struct uma_hash *);
  229 static int hash_expand(struct uma_hash *, struct uma_hash *);
  230 static void hash_free(struct uma_hash *hash);
  231 static void uma_timeout(void *);
  232 static void uma_startup3(void);
  233 static void *uma_zalloc_internal(uma_zone_t, void *, int);
  234 static void uma_zfree_internal(uma_zone_t, void *, void *, enum zfreeskip,
  235     int);
  236 static void bucket_enable(void);
  237 static void bucket_init(void);
  238 static uma_bucket_t bucket_alloc(int, int);
  239 static void bucket_free(uma_bucket_t);
  240 static void bucket_zone_drain(void);
  241 static int uma_zalloc_bucket(uma_zone_t zone, int flags);
  242 static uma_slab_t uma_zone_slab(uma_zone_t zone, int flags);
  243 static void *uma_slab_alloc(uma_zone_t zone, uma_slab_t slab);
  244 static uma_zone_t uma_kcreate(uma_zone_t zone, size_t size, uma_init uminit,
  245     uma_fini fini, int align, u_int32_t flags);
  246 
  247 void uma_print_zone(uma_zone_t);
  248 void uma_print_stats(void);
  249 static int sysctl_vm_zone_count(SYSCTL_HANDLER_ARGS);
  250 static int sysctl_vm_zone_stats(SYSCTL_HANDLER_ARGS);
  251 
  252 #ifdef WITNESS
  253 static int nosleepwithlocks = 1;
  254 #else
  255 static int nosleepwithlocks = 0;
  256 #endif
  257 SYSCTL_INT(_debug, OID_AUTO, nosleepwithlocks, CTLFLAG_RW, &nosleepwithlocks,
  258     0, "Convert M_WAITOK to M_NOWAIT to avoid lock-held-across-sleep paths");
  259 SYSINIT(uma_startup3, SI_SUB_VM_CONF, SI_ORDER_SECOND, uma_startup3, NULL);
  260 
  261 SYSCTL_PROC(_vm, OID_AUTO, zone_count, CTLFLAG_RD|CTLTYPE_INT,
  262     0, 0, sysctl_vm_zone_count, "I", "Number of UMA zones");
  263 
  264 SYSCTL_PROC(_vm, OID_AUTO, zone_stats, CTLFLAG_RD|CTLTYPE_STRUCT,
  265     0, 0, sysctl_vm_zone_stats, "s,struct uma_type_header", "Zone Stats");
  266 
  267 /*
  268  * This routine checks to see whether or not it's safe to enable buckets.
  269  */
  270 
  271 static void
  272 bucket_enable(void)
  273 {
  274         if (cnt.v_free_count < cnt.v_free_min)
  275                 bucketdisable = 1;
  276         else
  277                 bucketdisable = 0;
  278 }
  279 
  280 /*
  281  * Initialize bucket_zones, the array of zones of buckets of various sizes.
  282  *
  283  * For each zone, calculate the memory required for each bucket, consisting
  284  * of the header and an array of pointers.  Initialize bucket_size[] to point
  285  * the range of appropriate bucket sizes at the zone.
  286  */
  287 static void
  288 bucket_init(void)
  289 {
  290         struct uma_bucket_zone *ubz;
  291         int i;
  292         int j;
  293 
  294         for (i = 0, j = 0; bucket_zones[j].ubz_entries != 0; j++) {
  295                 int size;
  296 
  297                 ubz = &bucket_zones[j];
  298                 size = roundup(sizeof(struct uma_bucket), sizeof(void *));
  299                 size += sizeof(void *) * ubz->ubz_entries;
  300                 ubz->ubz_zone = uma_zcreate(ubz->ubz_name, size,
  301                     NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZFLAG_INTERNAL);
  302                 for (; i <= ubz->ubz_entries; i += (1 << BUCKET_SHIFT))
  303                         bucket_size[i >> BUCKET_SHIFT] = j;
  304         }
  305 }
  306 
  307 /*
  308  * Given a desired number of entries for a bucket, return the zone from which
  309  * to allocate the bucket.
  310  */
  311 static struct uma_bucket_zone *
  312 bucket_zone_lookup(int entries)
  313 {
  314         int idx;
  315 
  316         idx = howmany(entries, 1 << BUCKET_SHIFT);
  317         return (&bucket_zones[bucket_size[idx]]);
  318 }
  319 
  320 static uma_bucket_t
  321 bucket_alloc(int entries, int bflags)
  322 {
  323         struct uma_bucket_zone *ubz;
  324         uma_bucket_t bucket;
  325 
  326         /*
  327          * This is to stop us from allocating per cpu buckets while we're
  328          * running out of vm.boot_pages.  Otherwise, we would exhaust the
  329          * boot pages.  This also prevents us from allocating buckets in
  330          * low memory situations.
  331          */
  332         if (bucketdisable)
  333                 return (NULL);
  334 
  335         ubz = bucket_zone_lookup(entries);
  336         bucket = uma_zalloc_internal(ubz->ubz_zone, NULL, bflags);
  337         if (bucket) {
  338 #ifdef INVARIANTS
  339                 bzero(bucket->ub_bucket, sizeof(void *) * ubz->ubz_entries);
  340 #endif
  341                 bucket->ub_cnt = 0;
  342                 bucket->ub_entries = ubz->ubz_entries;
  343         }
  344 
  345         return (bucket);
  346 }
  347 
  348 static void
  349 bucket_free(uma_bucket_t bucket)
  350 {
  351         struct uma_bucket_zone *ubz;
  352 
  353         ubz = bucket_zone_lookup(bucket->ub_entries);
  354         uma_zfree_internal(ubz->ubz_zone, bucket, NULL, SKIP_NONE,
  355             ZFREE_STATFREE);
  356 }
  357 
  358 static void
  359 bucket_zone_drain(void)
  360 {
  361         struct uma_bucket_zone *ubz;
  362 
  363         for (ubz = &bucket_zones[0]; ubz->ubz_entries != 0; ubz++)
  364                 zone_drain(ubz->ubz_zone);
  365 }
  366 
  367 
  368 /*
  369  * Routine called by timeout which is used to fire off some time interval
  370  * based calculations.  (stats, hash size, etc.)
  371  *
  372  * Arguments:
  373  *      arg   Unused
  374  *
  375  * Returns:
  376  *      Nothing
  377  */
  378 static void
  379 uma_timeout(void *unused)
  380 {
  381         bucket_enable();
  382         zone_foreach(zone_timeout);
  383 
  384         /* Reschedule this event */
  385         callout_reset(&uma_callout, UMA_TIMEOUT * hz, uma_timeout, NULL);
  386 }
  387 
  388 /*
  389  * Routine to perform timeout driven calculations.  This expands the
  390  * hashes and does per cpu statistics aggregation.
  391  *
  392  *  Arguments:
  393  *      zone  The zone to operate on
  394  *
  395  *  Returns:
  396  *      Nothing
  397  */
  398 static void
  399 zone_timeout(uma_zone_t zone)
  400 {
  401         uma_keg_t keg;
  402         u_int64_t alloc;
  403 
  404         keg = zone->uz_keg;
  405         alloc = 0;
  406 
  407         /*
  408          * Expand the zone hash table.
  409          *
  410          * This is done if the number of slabs is larger than the hash size.
  411          * What I'm trying to do here is completely reduce collisions.  This
  412          * may be a little aggressive.  Should I allow for two collisions max?
  413          */
  414         ZONE_LOCK(zone);
  415         if (keg->uk_flags & UMA_ZONE_HASH &&
  416             keg->uk_pages / keg->uk_ppera >= keg->uk_hash.uh_hashsize) {
  417                 struct uma_hash newhash;
  418                 struct uma_hash oldhash;
  419                 int ret;
  420 
  421                 /*
  422                  * This is so involved because allocating and freeing
  423                  * while the zone lock is held will lead to deadlock.
  424                  * I have to do everything in stages and check for
  425                  * races.
  426                  */
  427                 newhash = keg->uk_hash;
  428                 ZONE_UNLOCK(zone);
  429                 ret = hash_alloc(&newhash);
  430                 ZONE_LOCK(zone);
  431                 if (ret) {
  432                         if (hash_expand(&keg->uk_hash, &newhash)) {
  433                                 oldhash = keg->uk_hash;
  434                                 keg->uk_hash = newhash;
  435                         } else
  436                                 oldhash = newhash;
  437 
  438                         ZONE_UNLOCK(zone);
  439                         hash_free(&oldhash);
  440                         ZONE_LOCK(zone);
  441                 }
  442         }
  443         ZONE_UNLOCK(zone);
  444 }
  445 
  446 /*
  447  * Allocate and zero fill the next sized hash table from the appropriate
  448  * backing store.
  449  *
  450  * Arguments:
  451  *      hash  A new hash structure with the old hash size in uh_hashsize
  452  *
  453  * Returns:
  454  *      1 on sucess and 0 on failure.
  455  */
  456 static int
  457 hash_alloc(struct uma_hash *hash)
  458 {
  459         int oldsize;
  460         int alloc;
  461 
  462         oldsize = hash->uh_hashsize;
  463 
  464         /* We're just going to go to a power of two greater */
  465         if (oldsize)  {
  466                 hash->uh_hashsize = oldsize * 2;
  467                 alloc = sizeof(hash->uh_slab_hash[0]) * hash->uh_hashsize;
  468                 hash->uh_slab_hash = (struct slabhead *)malloc(alloc,
  469                     M_UMAHASH, M_NOWAIT);
  470         } else {
  471                 alloc = sizeof(hash->uh_slab_hash[0]) * UMA_HASH_SIZE_INIT;
  472                 hash->uh_slab_hash = uma_zalloc_internal(hashzone, NULL,
  473                     M_WAITOK);
  474                 hash->uh_hashsize = UMA_HASH_SIZE_INIT;
  475         }
  476         if (hash->uh_slab_hash) {
  477                 bzero(hash->uh_slab_hash, alloc);
  478                 hash->uh_hashmask = hash->uh_hashsize - 1;
  479                 return (1);
  480         }
  481 
  482         return (0);
  483 }
  484 
  485 /*
  486  * Expands the hash table for HASH zones.  This is done from zone_timeout
  487  * to reduce collisions.  This must not be done in the regular allocation
  488  * path, otherwise, we can recurse on the vm while allocating pages.
  489  *
  490  * Arguments:
  491  *      oldhash  The hash you want to expand
  492  *      newhash  The hash structure for the new table
  493  *
  494  * Returns:
  495  *      Nothing
  496  *
  497  * Discussion:
  498  */
  499 static int
  500 hash_expand(struct uma_hash *oldhash, struct uma_hash *newhash)
  501 {
  502         uma_slab_t slab;
  503         int hval;
  504         int i;
  505 
  506         if (!newhash->uh_slab_hash)
  507                 return (0);
  508 
  509         if (oldhash->uh_hashsize >= newhash->uh_hashsize)
  510                 return (0);
  511 
  512         /*
  513          * I need to investigate hash algorithms for resizing without a
  514          * full rehash.
  515          */
  516 
  517         for (i = 0; i < oldhash->uh_hashsize; i++)
  518                 while (!SLIST_EMPTY(&oldhash->uh_slab_hash[i])) {
  519                         slab = SLIST_FIRST(&oldhash->uh_slab_hash[i]);
  520                         SLIST_REMOVE_HEAD(&oldhash->uh_slab_hash[i], us_hlink);
  521                         hval = UMA_HASH(newhash, slab->us_data);
  522                         SLIST_INSERT_HEAD(&newhash->uh_slab_hash[hval],
  523                             slab, us_hlink);
  524                 }
  525 
  526         return (1);
  527 }
  528 
  529 /*
  530  * Free the hash bucket to the appropriate backing store.
  531  *
  532  * Arguments:
  533  *      slab_hash  The hash bucket we're freeing
  534  *      hashsize   The number of entries in that hash bucket
  535  *
  536  * Returns:
  537  *      Nothing
  538  */
  539 static void
  540 hash_free(struct uma_hash *hash)
  541 {
  542         if (hash->uh_slab_hash == NULL)
  543                 return;
  544         if (hash->uh_hashsize == UMA_HASH_SIZE_INIT)
  545                 uma_zfree_internal(hashzone,
  546                     hash->uh_slab_hash, NULL, SKIP_NONE, ZFREE_STATFREE);
  547         else
  548                 free(hash->uh_slab_hash, M_UMAHASH);
  549 }
  550 
  551 /*
  552  * Frees all outstanding items in a bucket
  553  *
  554  * Arguments:
  555  *      zone   The zone to free to, must be unlocked.
  556  *      bucket The free/alloc bucket with items, cpu queue must be locked.
  557  *
  558  * Returns:
  559  *      Nothing
  560  */
  561 
  562 static void
  563 bucket_drain(uma_zone_t zone, uma_bucket_t bucket)
  564 {
  565         uma_slab_t slab;
  566         int mzone;
  567         void *item;
  568 
  569         if (bucket == NULL)
  570                 return;
  571 
  572         slab = NULL;
  573         mzone = 0;
  574 
  575         /* We have to lookup the slab again for malloc.. */
  576         if (zone->uz_keg->uk_flags & UMA_ZONE_MALLOC)
  577                 mzone = 1;
  578 
  579         while (bucket->ub_cnt > 0)  {
  580                 bucket->ub_cnt--;
  581                 item = bucket->ub_bucket[bucket->ub_cnt];
  582 #ifdef INVARIANTS
  583                 bucket->ub_bucket[bucket->ub_cnt] = NULL;
  584                 KASSERT(item != NULL,
  585                     ("bucket_drain: botched ptr, item is NULL"));
  586 #endif
  587                 /*
  588                  * This is extremely inefficient.  The slab pointer was passed
  589                  * to uma_zfree_arg, but we lost it because the buckets don't
  590                  * hold them.  This will go away when free() gets a size passed
  591                  * to it.
  592                  */
  593                 if (mzone)
  594                         slab = vtoslab((vm_offset_t)item & (~UMA_SLAB_MASK));
  595                 uma_zfree_internal(zone, item, slab, SKIP_DTOR, 0);
  596         }
  597 }
  598 
  599 /*
  600  * Drains the per cpu caches for a zone.
  601  *
  602  * NOTE: This may only be called while the zone is being turn down, and not
  603  * during normal operation.  This is necessary in order that we do not have
  604  * to migrate CPUs to drain the per-CPU caches.
  605  *
  606  * Arguments:
  607  *      zone     The zone to drain, must be unlocked.
  608  *
  609  * Returns:
  610  *      Nothing
  611  */
  612 static void
  613 cache_drain(uma_zone_t zone)
  614 {
  615         uma_cache_t cache;
  616         int cpu;
  617 
  618         /*
  619          * XXX: It is safe to not lock the per-CPU caches, because we're
  620          * tearing down the zone anyway.  I.e., there will be no further use
  621          * of the caches at this point.
  622          *
  623          * XXX: It would good to be able to assert that the zone is being
  624          * torn down to prevent improper use of cache_drain().
  625          *
  626          * XXX: We lock the zone before passing into bucket_cache_drain() as
  627          * it is used elsewhere.  Should the tear-down path be made special
  628          * there in some form?
  629          */
  630         for (cpu = 0; cpu <= mp_maxid; cpu++) {
  631                 if (CPU_ABSENT(cpu))
  632                         continue;
  633                 cache = &zone->uz_cpu[cpu];
  634                 bucket_drain(zone, cache->uc_allocbucket);
  635                 bucket_drain(zone, cache->uc_freebucket);
  636                 if (cache->uc_allocbucket != NULL)
  637                         bucket_free(cache->uc_allocbucket);
  638                 if (cache->uc_freebucket != NULL)
  639                         bucket_free(cache->uc_freebucket);
  640                 cache->uc_allocbucket = cache->uc_freebucket = NULL;
  641         }
  642         ZONE_LOCK(zone);
  643         bucket_cache_drain(zone);
  644         ZONE_UNLOCK(zone);
  645 }
  646 
  647 /*
  648  * Drain the cached buckets from a zone.  Expects a locked zone on entry.
  649  */
  650 static void
  651 bucket_cache_drain(uma_zone_t zone)
  652 {
  653         uma_bucket_t bucket;
  654 
  655         /*
  656          * Drain the bucket queues and free the buckets, we just keep two per
  657          * cpu (alloc/free).
  658          */
  659         while ((bucket = LIST_FIRST(&zone->uz_full_bucket)) != NULL) {
  660                 LIST_REMOVE(bucket, ub_link);
  661                 ZONE_UNLOCK(zone);
  662                 bucket_drain(zone, bucket);
  663                 bucket_free(bucket);
  664                 ZONE_LOCK(zone);
  665         }
  666 
  667         /* Now we do the free queue.. */
  668         while ((bucket = LIST_FIRST(&zone->uz_free_bucket)) != NULL) {
  669                 LIST_REMOVE(bucket, ub_link);
  670                 bucket_free(bucket);
  671         }
  672 }
  673 
  674 /*
  675  * Frees pages from a zone back to the system.  This is done on demand from
  676  * the pageout daemon.
  677  *
  678  * Arguments:
  679  *      zone  The zone to free pages from
  680  *       all  Should we drain all items?
  681  *
  682  * Returns:
  683  *      Nothing.
  684  */
  685 void
  686 zone_drain(uma_zone_t zone)
  687 {
  688         struct slabhead freeslabs = { 0 };
  689         uma_keg_t keg;
  690         uma_slab_t slab;
  691         uma_slab_t n;
  692         u_int8_t flags;
  693         u_int8_t *mem;
  694         int i;
  695 
  696         keg = zone->uz_keg;
  697 
  698         /*
  699          * We don't want to take pages from statically allocated zones at this
  700          * time
  701          */
  702         if (keg->uk_flags & UMA_ZONE_NOFREE || keg->uk_freef == NULL)
  703                 return;
  704 
  705         ZONE_LOCK(zone);
  706 
  707 #ifdef UMA_DEBUG
  708         printf("%s free items: %u\n", zone->uz_name, keg->uk_free);
  709 #endif
  710         bucket_cache_drain(zone);
  711         if (keg->uk_free == 0)
  712                 goto finished;
  713 
  714         slab = LIST_FIRST(&keg->uk_free_slab);
  715         while (slab) {
  716                 n = LIST_NEXT(slab, us_link);
  717 
  718                 /* We have no where to free these to */
  719                 if (slab->us_flags & UMA_SLAB_BOOT) {
  720                         slab = n;
  721                         continue;
  722                 }
  723 
  724                 LIST_REMOVE(slab, us_link);
  725                 keg->uk_pages -= keg->uk_ppera;
  726                 keg->uk_free -= keg->uk_ipers;
  727 
  728                 if (keg->uk_flags & UMA_ZONE_HASH)
  729                         UMA_HASH_REMOVE(&keg->uk_hash, slab, slab->us_data);
  730 
  731                 SLIST_INSERT_HEAD(&freeslabs, slab, us_hlink);
  732 
  733                 slab = n;
  734         }
  735 finished:
  736         ZONE_UNLOCK(zone);
  737 
  738         while ((slab = SLIST_FIRST(&freeslabs)) != NULL) {
  739                 SLIST_REMOVE(&freeslabs, slab, uma_slab, us_hlink);
  740                 if (keg->uk_fini)
  741                         for (i = 0; i < keg->uk_ipers; i++)
  742                                 keg->uk_fini(
  743                                     slab->us_data + (keg->uk_rsize * i),
  744                                     keg->uk_size);
  745                 flags = slab->us_flags;
  746                 mem = slab->us_data;
  747 
  748                 if ((keg->uk_flags & UMA_ZONE_MALLOC) ||
  749                     (keg->uk_flags & UMA_ZONE_REFCNT)) {
  750                         vm_object_t obj;
  751 
  752                         if (flags & UMA_SLAB_KMEM)
  753                                 obj = kmem_object;
  754                         else
  755                                 obj = NULL;
  756                         for (i = 0; i < keg->uk_ppera; i++)
  757                                 vsetobj((vm_offset_t)mem + (i * PAGE_SIZE),
  758                                     obj);
  759                 }
  760                 if (keg->uk_flags & UMA_ZONE_OFFPAGE)
  761                         uma_zfree_internal(keg->uk_slabzone, slab, NULL,
  762                             SKIP_NONE, ZFREE_STATFREE);
  763 #ifdef UMA_DEBUG
  764                 printf("%s: Returning %d bytes.\n",
  765                     zone->uz_name, UMA_SLAB_SIZE * keg->uk_ppera);
  766 #endif
  767                 keg->uk_freef(mem, UMA_SLAB_SIZE * keg->uk_ppera, flags);
  768         }
  769 }
  770 
  771 /*
  772  * Allocate a new slab for a zone.  This does not insert the slab onto a list.
  773  *
  774  * Arguments:
  775  *      zone  The zone to allocate slabs for
  776  *      wait  Shall we wait?
  777  *
  778  * Returns:
  779  *      The slab that was allocated or NULL if there is no memory and the
  780  *      caller specified M_NOWAIT.
  781  */
  782 static uma_slab_t
  783 slab_zalloc(uma_zone_t zone, int wait)
  784 {
  785         uma_slabrefcnt_t slabref;
  786         uma_slab_t slab;
  787         uma_keg_t keg;
  788         u_int8_t *mem;
  789         u_int8_t flags;
  790         int i;
  791 
  792         slab = NULL;
  793         keg = zone->uz_keg;
  794 
  795 #ifdef UMA_DEBUG
  796         printf("slab_zalloc:  Allocating a new slab for %s\n", zone->uz_name);
  797 #endif
  798         ZONE_UNLOCK(zone);
  799 
  800         if (keg->uk_flags & UMA_ZONE_OFFPAGE) {
  801                 slab = uma_zalloc_internal(keg->uk_slabzone, NULL, wait);
  802                 if (slab == NULL) {
  803                         ZONE_LOCK(zone);
  804                         return NULL;
  805                 }
  806         }
  807 
  808         /*
  809          * This reproduces the old vm_zone behavior of zero filling pages the
  810          * first time they are added to a zone.
  811          *
  812          * Malloced items are zeroed in uma_zalloc.
  813          */
  814 
  815         if ((keg->uk_flags & UMA_ZONE_MALLOC) == 0)
  816                 wait |= M_ZERO;
  817         else
  818                 wait &= ~M_ZERO;
  819 
  820         mem = keg->uk_allocf(zone, keg->uk_ppera * UMA_SLAB_SIZE,
  821             &flags, wait);
  822         if (mem == NULL) {
  823                 if (keg->uk_flags & UMA_ZONE_OFFPAGE)
  824                         uma_zfree_internal(keg->uk_slabzone, slab, NULL,
  825                             SKIP_NONE, ZFREE_STATFREE);
  826                 ZONE_LOCK(zone);
  827                 return (NULL);
  828         }
  829 
  830         /* Point the slab into the allocated memory */
  831         if (!(keg->uk_flags & UMA_ZONE_OFFPAGE))
  832                 slab = (uma_slab_t )(mem + keg->uk_pgoff);
  833 
  834         if ((keg->uk_flags & UMA_ZONE_MALLOC) ||
  835             (keg->uk_flags & UMA_ZONE_REFCNT))
  836                 for (i = 0; i < keg->uk_ppera; i++)
  837                         vsetslab((vm_offset_t)mem + (i * PAGE_SIZE), slab);
  838 
  839         slab->us_keg = keg;
  840         slab->us_data = mem;
  841         slab->us_freecount = keg->uk_ipers;
  842         slab->us_firstfree = 0;
  843         slab->us_flags = flags;
  844 
  845         if (keg->uk_flags & UMA_ZONE_REFCNT) {
  846                 slabref = (uma_slabrefcnt_t)slab;
  847                 for (i = 0; i < keg->uk_ipers; i++) {
  848                         slabref->us_freelist[i].us_refcnt = 0;
  849                         slabref->us_freelist[i].us_item = i+1;
  850                 }
  851         } else {
  852                 for (i = 0; i < keg->uk_ipers; i++)
  853                         slab->us_freelist[i].us_item = i+1;
  854         }
  855 
  856         if (keg->uk_init != NULL) {
  857                 for (i = 0; i < keg->uk_ipers; i++)
  858                         if (keg->uk_init(slab->us_data + (keg->uk_rsize * i),
  859                             keg->uk_size, wait) != 0)
  860                                 break;
  861                 if (i != keg->uk_ipers) {
  862                         if (keg->uk_fini != NULL) {
  863                                 for (i--; i > -1; i--)
  864                                         keg->uk_fini(slab->us_data +
  865                                             (keg->uk_rsize * i),
  866                                             keg->uk_size);
  867                         }
  868                         if ((keg->uk_flags & UMA_ZONE_MALLOC) ||
  869                             (keg->uk_flags & UMA_ZONE_REFCNT)) {
  870                                 vm_object_t obj;
  871 
  872                                 if (flags & UMA_SLAB_KMEM)
  873                                         obj = kmem_object;
  874                                 else
  875                                         obj = NULL;
  876                                 for (i = 0; i < keg->uk_ppera; i++)
  877                                         vsetobj((vm_offset_t)mem +
  878                                             (i * PAGE_SIZE), obj);
  879                         }
  880                         if (keg->uk_flags & UMA_ZONE_OFFPAGE)
  881                                 uma_zfree_internal(keg->uk_slabzone, slab,
  882                                     NULL, SKIP_NONE, ZFREE_STATFREE);
  883                         keg->uk_freef(mem, UMA_SLAB_SIZE * keg->uk_ppera,
  884                             flags);
  885                         ZONE_LOCK(zone);
  886                         return (NULL);
  887                 }
  888         }
  889         ZONE_LOCK(zone);
  890 
  891         if (keg->uk_flags & UMA_ZONE_HASH)
  892                 UMA_HASH_INSERT(&keg->uk_hash, slab, mem);
  893 
  894         keg->uk_pages += keg->uk_ppera;
  895         keg->uk_free += keg->uk_ipers;
  896 
  897         return (slab);
  898 }
  899 
  900 /*
  901  * This function is intended to be used early on in place of page_alloc() so
  902  * that we may use the boot time page cache to satisfy allocations before
  903  * the VM is ready.
  904  */
  905 static void *
  906 startup_alloc(uma_zone_t zone, int bytes, u_int8_t *pflag, int wait)
  907 {
  908         uma_keg_t keg;
  909         uma_slab_t tmps;
  910 
  911         keg = zone->uz_keg;
  912 
  913         /*
  914          * Check our small startup cache to see if it has pages remaining.
  915          */
  916         mtx_lock(&uma_boot_pages_mtx);
  917         if ((tmps = LIST_FIRST(&uma_boot_pages)) != NULL) {
  918                 LIST_REMOVE(tmps, us_link);
  919                 mtx_unlock(&uma_boot_pages_mtx);
  920                 *pflag = tmps->us_flags;
  921                 return (tmps->us_data);
  922         }
  923         mtx_unlock(&uma_boot_pages_mtx);
  924         if (booted == 0)
  925                 panic("UMA: Increase vm.boot_pages");
  926         /*
  927          * Now that we've booted reset these users to their real allocator.
  928          */
  929 #ifdef UMA_MD_SMALL_ALLOC
  930         keg->uk_allocf = uma_small_alloc;
  931 #else
  932         keg->uk_allocf = page_alloc;
  933 #endif
  934         return keg->uk_allocf(zone, bytes, pflag, wait);
  935 }
  936 
  937 /*
  938  * Allocates a number of pages from the system
  939  *
  940  * Arguments:
  941  *      zone  Unused
  942  *      bytes  The number of bytes requested
  943  *      wait  Shall we wait?
  944  *
  945  * Returns:
  946  *      A pointer to the alloced memory or possibly
  947  *      NULL if M_NOWAIT is set.
  948  */
  949 static void *
  950 page_alloc(uma_zone_t zone, int bytes, u_int8_t *pflag, int wait)
  951 {
  952         void *p;        /* Returned page */
  953 
  954         *pflag = UMA_SLAB_KMEM;
  955         p = (void *) kmem_malloc(kmem_map, bytes, wait);
  956 
  957         return (p);
  958 }
  959 
  960 /*
  961  * Allocates a number of pages from within an object
  962  *
  963  * Arguments:
  964  *      zone   Unused
  965  *      bytes  The number of bytes requested
  966  *      wait   Shall we wait?
  967  *
  968  * Returns:
  969  *      A pointer to the alloced memory or possibly
  970  *      NULL if M_NOWAIT is set.
  971  */
  972 static void *
  973 obj_alloc(uma_zone_t zone, int bytes, u_int8_t *flags, int wait)
  974 {
  975         vm_object_t object;
  976         vm_offset_t retkva, zkva;
  977         vm_page_t p;
  978         int pages, startpages;
  979 
  980         object = zone->uz_keg->uk_obj;
  981         retkva = 0;
  982 
  983         /*
  984          * This looks a little weird since we're getting one page at a time.
  985          */
  986         VM_OBJECT_LOCK(object);
  987         p = TAILQ_LAST(&object->memq, pglist);
  988         pages = p != NULL ? p->pindex + 1 : 0;
  989         startpages = pages;
  990         zkva = zone->uz_keg->uk_kva + pages * PAGE_SIZE;
  991         for (; bytes > 0; bytes -= PAGE_SIZE) {
  992                 p = vm_page_alloc(object, pages,
  993                     VM_ALLOC_INTERRUPT | VM_ALLOC_WIRED);
  994                 if (p == NULL) {
  995                         if (pages != startpages)
  996                                 pmap_qremove(retkva, pages - startpages);
  997                         while (pages != startpages) {
  998                                 pages--;
  999                                 p = TAILQ_LAST(&object->memq, pglist);
 1000                                 vm_page_lock_queues();
 1001                                 vm_page_unwire(p, 0);
 1002                                 vm_page_free(p);
 1003                                 vm_page_unlock_queues();
 1004                         }
 1005                         retkva = 0;
 1006                         goto done;
 1007                 }
 1008                 pmap_qenter(zkva, &p, 1);
 1009                 if (retkva == 0)
 1010                         retkva = zkva;
 1011                 zkva += PAGE_SIZE;
 1012                 pages += 1;
 1013         }
 1014 done:
 1015         VM_OBJECT_UNLOCK(object);
 1016         *flags = UMA_SLAB_PRIV;
 1017 
 1018         return ((void *)retkva);
 1019 }
 1020 
 1021 /*
 1022  * Frees a number of pages to the system
 1023  *
 1024  * Arguments:
 1025  *      mem   A pointer to the memory to be freed
 1026  *      size  The size of the memory being freed
 1027  *      flags The original p->us_flags field
 1028  *
 1029  * Returns:
 1030  *      Nothing
 1031  */
 1032 static void
 1033 page_free(void *mem, int size, u_int8_t flags)
 1034 {
 1035         vm_map_t map;
 1036 
 1037         if (flags & UMA_SLAB_KMEM)
 1038                 map = kmem_map;
 1039         else
 1040                 panic("UMA: page_free used with invalid flags %d\n", flags);
 1041 
 1042         kmem_free(map, (vm_offset_t)mem, size);
 1043 }
 1044 
 1045 /*
 1046  * Zero fill initializer
 1047  *
 1048  * Arguments/Returns follow uma_init specifications
 1049  */
 1050 static int
 1051 zero_init(void *mem, int size, int flags)
 1052 {
 1053         bzero(mem, size);
 1054         return (0);
 1055 }
 1056 
 1057 /*
 1058  * Finish creating a small uma zone.  This calculates ipers, and the zone size.
 1059  *
 1060  * Arguments
 1061  *      zone  The zone we should initialize
 1062  *
 1063  * Returns
 1064  *      Nothing
 1065  */
 1066 static void
 1067 zone_small_init(uma_zone_t zone)
 1068 {
 1069         uma_keg_t keg;
 1070         u_int rsize;
 1071         u_int memused;
 1072         u_int wastedspace;
 1073         u_int shsize;
 1074 
 1075         keg = zone->uz_keg;
 1076         KASSERT(keg != NULL, ("Keg is null in zone_small_init"));
 1077         rsize = keg->uk_size;
 1078 
 1079         if (rsize < UMA_SMALLEST_UNIT)
 1080                 rsize = UMA_SMALLEST_UNIT;
 1081         if (rsize & keg->uk_align)
 1082                 rsize = (rsize & ~keg->uk_align) + (keg->uk_align + 1);
 1083 
 1084         keg->uk_rsize = rsize;
 1085         keg->uk_ppera = 1;
 1086 
 1087         if (keg->uk_flags & UMA_ZONE_REFCNT) {
 1088                 rsize += UMA_FRITMREF_SZ;       /* linkage & refcnt */
 1089                 shsize = sizeof(struct uma_slab_refcnt);
 1090         } else {
 1091                 rsize += UMA_FRITM_SZ;  /* Account for linkage */
 1092                 shsize = sizeof(struct uma_slab);
 1093         }
 1094 
 1095         keg->uk_ipers = (UMA_SLAB_SIZE - shsize) / rsize;
 1096         KASSERT(keg->uk_ipers != 0, ("zone_small_init: ipers is 0"));
 1097         memused = keg->uk_ipers * rsize + shsize;
 1098         wastedspace = UMA_SLAB_SIZE - memused;
 1099 
 1100         /*
 1101          * We can't do OFFPAGE if we're internal or if we've been
 1102          * asked to not go to the VM for buckets.  If we do this we
 1103          * may end up going to the VM (kmem_map) for slabs which we
 1104          * do not want to do if we're UMA_ZFLAG_CACHEONLY as a
 1105          * result of UMA_ZONE_VM, which clearly forbids it.
 1106          */
 1107         if ((keg->uk_flags & UMA_ZFLAG_INTERNAL) ||
 1108             (keg->uk_flags & UMA_ZFLAG_CACHEONLY))
 1109                 return;
 1110 
 1111         if ((wastedspace >= UMA_MAX_WASTE) &&
 1112             (keg->uk_ipers < (UMA_SLAB_SIZE / keg->uk_rsize))) {
 1113                 keg->uk_ipers = UMA_SLAB_SIZE / keg->uk_rsize;
 1114                 KASSERT(keg->uk_ipers <= 255,
 1115                     ("zone_small_init: keg->uk_ipers too high!"));
 1116 #ifdef UMA_DEBUG
 1117                 printf("UMA decided we need offpage slab headers for "
 1118                     "zone: %s, calculated wastedspace = %d, "
 1119                     "maximum wasted space allowed = %d, "
 1120                     "calculated ipers = %d, "
 1121                     "new wasted space = %d\n", zone->uz_name, wastedspace,
 1122                     UMA_MAX_WASTE, keg->uk_ipers,
 1123                     UMA_SLAB_SIZE - keg->uk_ipers * keg->uk_rsize);
 1124 #endif
 1125                 keg->uk_flags |= UMA_ZONE_OFFPAGE;
 1126                 if ((keg->uk_flags & UMA_ZONE_MALLOC) == 0)
 1127                         keg->uk_flags |= UMA_ZONE_HASH;
 1128         }
 1129 }
 1130 
 1131 /*
 1132  * Finish creating a large (> UMA_SLAB_SIZE) uma zone.  Just give in and do
 1133  * OFFPAGE for now.  When I can allow for more dynamic slab sizes this will be
 1134  * more complicated.
 1135  *
 1136  * Arguments
 1137  *      zone  The zone we should initialize
 1138  *
 1139  * Returns
 1140  *      Nothing
 1141  */
 1142 static void
 1143 zone_large_init(uma_zone_t zone)
 1144 {
 1145         uma_keg_t keg;
 1146         int pages;
 1147 
 1148         keg = zone->uz_keg;
 1149 
 1150         KASSERT(keg != NULL, ("Keg is null in zone_large_init"));
 1151         KASSERT((keg->uk_flags & UMA_ZFLAG_CACHEONLY) == 0,
 1152             ("zone_large_init: Cannot large-init a UMA_ZFLAG_CACHEONLY zone"));
 1153 
 1154         pages = keg->uk_size / UMA_SLAB_SIZE;
 1155 
 1156         /* Account for remainder */
 1157         if ((pages * UMA_SLAB_SIZE) < keg->uk_size)
 1158                 pages++;
 1159 
 1160         keg->uk_ppera = pages;
 1161         keg->uk_ipers = 1;
 1162 
 1163         keg->uk_flags |= UMA_ZONE_OFFPAGE;
 1164         if ((keg->uk_flags & UMA_ZONE_MALLOC) == 0)
 1165                 keg->uk_flags |= UMA_ZONE_HASH;
 1166 
 1167         keg->uk_rsize = keg->uk_size;
 1168 }
 1169 
 1170 /*
 1171  * Keg header ctor.  This initializes all fields, locks, etc.  And inserts
 1172  * the keg onto the global keg list.
 1173  *
 1174  * Arguments/Returns follow uma_ctor specifications
 1175  *      udata  Actually uma_kctor_args
 1176  */
 1177 static int
 1178 keg_ctor(void *mem, int size, void *udata, int flags)
 1179 {
 1180         struct uma_kctor_args *arg = udata;
 1181         uma_keg_t keg = mem;
 1182         uma_zone_t zone;
 1183 
 1184         bzero(keg, size);
 1185         keg->uk_size = arg->size;
 1186         keg->uk_init = arg->uminit;
 1187         keg->uk_fini = arg->fini;
 1188         keg->uk_align = arg->align;
 1189         keg->uk_free = 0;
 1190         keg->uk_pages = 0;
 1191         keg->uk_flags = arg->flags;
 1192         keg->uk_allocf = page_alloc;
 1193         keg->uk_freef = page_free;
 1194         keg->uk_recurse = 0;
 1195         keg->uk_slabzone = NULL;
 1196 
 1197         /*
 1198          * The master zone is passed to us at keg-creation time.
 1199          */
 1200         zone = arg->zone;
 1201         zone->uz_keg = keg;
 1202 
 1203         if (arg->flags & UMA_ZONE_VM)
 1204                 keg->uk_flags |= UMA_ZFLAG_CACHEONLY;
 1205 
 1206         if (arg->flags & UMA_ZONE_ZINIT)
 1207                 keg->uk_init = zero_init;
 1208 
 1209         /*
 1210          * The +UMA_FRITM_SZ added to uk_size is to account for the
 1211          * linkage that is added to the size in zone_small_init().  If
 1212          * we don't account for this here then we may end up in
 1213          * zone_small_init() with a calculated 'ipers' of 0.
 1214          */
 1215         if (keg->uk_flags & UMA_ZONE_REFCNT) {
 1216                 if ((keg->uk_size+UMA_FRITMREF_SZ) >
 1217                     (UMA_SLAB_SIZE - sizeof(struct uma_slab_refcnt)))
 1218                         zone_large_init(zone);
 1219                 else
 1220                         zone_small_init(zone);
 1221         } else {
 1222                 if ((keg->uk_size+UMA_FRITM_SZ) >
 1223                     (UMA_SLAB_SIZE - sizeof(struct uma_slab)))
 1224                         zone_large_init(zone);
 1225                 else
 1226                         zone_small_init(zone);
 1227         }
 1228 
 1229         if (keg->uk_flags & UMA_ZONE_OFFPAGE) {
 1230                 if (keg->uk_flags & UMA_ZONE_REFCNT)
 1231                         keg->uk_slabzone = slabrefzone;
 1232                 else
 1233                         keg->uk_slabzone = slabzone;
 1234         }
 1235 
 1236         /*
 1237          * If we haven't booted yet we need allocations to go through the
 1238          * startup cache until the vm is ready.
 1239          */
 1240         if (keg->uk_ppera == 1) {
 1241 #ifdef UMA_MD_SMALL_ALLOC
 1242                 keg->uk_allocf = uma_small_alloc;
 1243                 keg->uk_freef = uma_small_free;
 1244 #endif
 1245                 if (booted == 0)
 1246                         keg->uk_allocf = startup_alloc;
 1247         }
 1248 
 1249         /*
 1250          * Initialize keg's lock (shared among zones) through
 1251          * Master zone
 1252          */
 1253         zone->uz_lock = &keg->uk_lock;
 1254         if (arg->flags & UMA_ZONE_MTXCLASS)
 1255                 ZONE_LOCK_INIT(zone, 1);
 1256         else
 1257                 ZONE_LOCK_INIT(zone, 0);
 1258 
 1259         /*
 1260          * If we're putting the slab header in the actual page we need to
 1261          * figure out where in each page it goes.  This calculates a right
 1262          * justified offset into the memory on an ALIGN_PTR boundary.
 1263          */
 1264         if (!(keg->uk_flags & UMA_ZONE_OFFPAGE)) {
 1265                 u_int totsize;
 1266 
 1267                 /* Size of the slab struct and free list */
 1268                 if (keg->uk_flags & UMA_ZONE_REFCNT)
 1269                         totsize = sizeof(struct uma_slab_refcnt) +
 1270                             keg->uk_ipers * UMA_FRITMREF_SZ;
 1271                 else
 1272                         totsize = sizeof(struct uma_slab) +
 1273                             keg->uk_ipers * UMA_FRITM_SZ;
 1274 
 1275                 if (totsize & UMA_ALIGN_PTR)
 1276                         totsize = (totsize & ~UMA_ALIGN_PTR) +
 1277                             (UMA_ALIGN_PTR + 1);
 1278                 keg->uk_pgoff = UMA_SLAB_SIZE - totsize;
 1279 
 1280                 if (keg->uk_flags & UMA_ZONE_REFCNT)
 1281                         totsize = keg->uk_pgoff + sizeof(struct uma_slab_refcnt)
 1282                             + keg->uk_ipers * UMA_FRITMREF_SZ;
 1283                 else
 1284                         totsize = keg->uk_pgoff + sizeof(struct uma_slab)
 1285                             + keg->uk_ipers * UMA_FRITM_SZ;
 1286 
 1287                 /*
 1288                  * The only way the following is possible is if with our
 1289                  * UMA_ALIGN_PTR adjustments we are now bigger than
 1290                  * UMA_SLAB_SIZE.  I haven't checked whether this is
 1291                  * mathematically possible for all cases, so we make
 1292                  * sure here anyway.
 1293                  */
 1294                 if (totsize > UMA_SLAB_SIZE) {
 1295                         printf("zone %s ipers %d rsize %d size %d\n",
 1296                             zone->uz_name, keg->uk_ipers, keg->uk_rsize,
 1297                             keg->uk_size);
 1298                         panic("UMA slab won't fit.\n");
 1299                 }
 1300         }
 1301 
 1302         if (keg->uk_flags & UMA_ZONE_HASH)
 1303                 hash_alloc(&keg->uk_hash);
 1304 
 1305 #ifdef UMA_DEBUG
 1306         printf("%s(%p) size = %d ipers = %d ppera = %d pgoff = %d\n",
 1307             zone->uz_name, zone,
 1308             keg->uk_size, keg->uk_ipers,
 1309             keg->uk_ppera, keg->uk_pgoff);
 1310 #endif
 1311 
 1312         LIST_INSERT_HEAD(&keg->uk_zones, zone, uz_link);
 1313 
 1314         mtx_lock(&uma_mtx);
 1315         LIST_INSERT_HEAD(&uma_kegs, keg, uk_link);
 1316         mtx_unlock(&uma_mtx);
 1317         return (0);
 1318 }
 1319 
 1320 /*
 1321  * Zone header ctor.  This initializes all fields, locks, etc.
 1322  *
 1323  * Arguments/Returns follow uma_ctor specifications
 1324  *      udata  Actually uma_zctor_args
 1325  */
 1326 
 1327 static int
 1328 zone_ctor(void *mem, int size, void *udata, int flags)
 1329 {
 1330         struct uma_zctor_args *arg = udata;
 1331         uma_zone_t zone = mem;
 1332         uma_zone_t z;
 1333         uma_keg_t keg;
 1334 
 1335         bzero(zone, size);
 1336         zone->uz_name = arg->name;
 1337         zone->uz_ctor = arg->ctor;
 1338         zone->uz_dtor = arg->dtor;
 1339         zone->uz_init = NULL;
 1340         zone->uz_fini = NULL;
 1341         zone->uz_allocs = 0;
 1342         zone->uz_frees = 0;
 1343         zone->uz_fails = 0;
 1344         zone->uz_fills = zone->uz_count = 0;
 1345 
 1346         if (arg->flags & UMA_ZONE_SECONDARY) {
 1347                 KASSERT(arg->keg != NULL, ("Secondary zone on zero'd keg"));
 1348                 keg = arg->keg;
 1349                 zone->uz_keg = keg;
 1350                 zone->uz_init = arg->uminit;
 1351                 zone->uz_fini = arg->fini;
 1352                 zone->uz_lock = &keg->uk_lock;
 1353                 mtx_lock(&uma_mtx);
 1354                 ZONE_LOCK(zone);
 1355                 keg->uk_flags |= UMA_ZONE_SECONDARY;
 1356                 LIST_FOREACH(z, &keg->uk_zones, uz_link) {
 1357                         if (LIST_NEXT(z, uz_link) == NULL) {
 1358                                 LIST_INSERT_AFTER(z, zone, uz_link);
 1359                                 break;
 1360                         }
 1361                 }
 1362                 ZONE_UNLOCK(zone);
 1363                 mtx_unlock(&uma_mtx);
 1364         } else if (arg->keg == NULL) {
 1365                 if (uma_kcreate(zone, arg->size, arg->uminit, arg->fini,
 1366                     arg->align, arg->flags) == NULL)
 1367                         return (ENOMEM);
 1368         } else {
 1369                 struct uma_kctor_args karg;
 1370                 int error;
 1371 
 1372                 /* We should only be here from uma_startup() */
 1373                 karg.size = arg->size;
 1374                 karg.uminit = arg->uminit;
 1375                 karg.fini = arg->fini;
 1376                 karg.align = arg->align;
 1377                 karg.flags = arg->flags;
 1378                 karg.zone = zone;
 1379                 error = keg_ctor(arg->keg, sizeof(struct uma_keg), &karg,
 1380                     flags);
 1381                 if (error)
 1382                         return (error);
 1383         }
 1384         keg = zone->uz_keg;
 1385         zone->uz_lock = &keg->uk_lock;
 1386 
 1387         /*
 1388          * Some internal zones don't have room allocated for the per cpu
 1389          * caches.  If we're internal, bail out here.
 1390          */
 1391         if (keg->uk_flags & UMA_ZFLAG_INTERNAL) {
 1392                 KASSERT((keg->uk_flags & UMA_ZONE_SECONDARY) == 0,
 1393                     ("Secondary zone requested UMA_ZFLAG_INTERNAL"));
 1394                 return (0);
 1395         }
 1396 
 1397         if (keg->uk_flags & UMA_ZONE_MAXBUCKET)
 1398                 zone->uz_count = BUCKET_MAX;
 1399         else if (keg->uk_ipers <= BUCKET_MAX)
 1400                 zone->uz_count = keg->uk_ipers;
 1401         else
 1402                 zone->uz_count = BUCKET_MAX;
 1403         return (0);
 1404 }
 1405 
 1406 /*
 1407  * Keg header dtor.  This frees all data, destroys locks, frees the hash
 1408  * table and removes the keg from the global list.
 1409  *
 1410  * Arguments/Returns follow uma_dtor specifications
 1411  *      udata  unused
 1412  */
 1413 static void
 1414 keg_dtor(void *arg, int size, void *udata)
 1415 {
 1416         uma_keg_t keg;
 1417 
 1418         keg = (uma_keg_t)arg;
 1419         mtx_lock(&keg->uk_lock);
 1420         if (keg->uk_free != 0) {
 1421                 printf("Freed UMA keg was not empty (%d items). "
 1422                     " Lost %d pages of memory.\n",
 1423                     keg->uk_free, keg->uk_pages);
 1424         }
 1425         mtx_unlock(&keg->uk_lock);
 1426 
 1427         if (keg->uk_flags & UMA_ZONE_HASH)
 1428                 hash_free(&keg->uk_hash);
 1429 
 1430         mtx_destroy(&keg->uk_lock);
 1431 }
 1432 
 1433 /*
 1434  * Zone header dtor.
 1435  *
 1436  * Arguments/Returns follow uma_dtor specifications
 1437  *      udata  unused
 1438  */
 1439 static void
 1440 zone_dtor(void *arg, int size, void *udata)
 1441 {
 1442         uma_zone_t zone;
 1443         uma_keg_t keg;
 1444 
 1445         zone = (uma_zone_t)arg;
 1446         keg = zone->uz_keg;
 1447 
 1448         if (!(keg->uk_flags & UMA_ZFLAG_INTERNAL))
 1449                 cache_drain(zone);
 1450 
 1451         mtx_lock(&uma_mtx);
 1452         zone_drain(zone);
 1453         if (keg->uk_flags & UMA_ZONE_SECONDARY) {
 1454                 LIST_REMOVE(zone, uz_link);
 1455                 /*
 1456                  * XXX there are some races here where
 1457                  * the zone can be drained but zone lock
 1458                  * released and then refilled before we
 1459                  * remove it... we dont care for now
 1460                  */
 1461                 ZONE_LOCK(zone);
 1462                 if (LIST_EMPTY(&keg->uk_zones))
 1463                         keg->uk_flags &= ~UMA_ZONE_SECONDARY;
 1464                 ZONE_UNLOCK(zone);
 1465                 mtx_unlock(&uma_mtx);
 1466         } else {
 1467                 LIST_REMOVE(keg, uk_link);
 1468                 LIST_REMOVE(zone, uz_link);
 1469                 mtx_unlock(&uma_mtx);
 1470                 uma_zfree_internal(kegs, keg, NULL, SKIP_NONE,
 1471                     ZFREE_STATFREE);
 1472         }
 1473         zone->uz_keg = NULL;
 1474 }
 1475 
 1476 /*
 1477  * Traverses every zone in the system and calls a callback
 1478  *
 1479  * Arguments:
 1480  *      zfunc  A pointer to a function which accepts a zone
 1481  *              as an argument.
 1482  *
 1483  * Returns:
 1484  *      Nothing
 1485  */
 1486 static void
 1487 zone_foreach(void (*zfunc)(uma_zone_t))
 1488 {
 1489         uma_keg_t keg;
 1490         uma_zone_t zone;
 1491 
 1492         mtx_lock(&uma_mtx);
 1493         LIST_FOREACH(keg, &uma_kegs, uk_link) {
 1494                 LIST_FOREACH(zone, &keg->uk_zones, uz_link)
 1495                         zfunc(zone);
 1496         }
 1497         mtx_unlock(&uma_mtx);
 1498 }
 1499 
 1500 /* Public functions */
 1501 /* See uma.h */
 1502 void
 1503 uma_startup(void *bootmem, int boot_pages)
 1504 {
 1505         struct uma_zctor_args args;
 1506         uma_slab_t slab;
 1507         u_int slabsize;
 1508         u_int objsize, totsize, wsize;
 1509         int i;
 1510 
 1511 #ifdef UMA_DEBUG
 1512         printf("Creating uma keg headers zone and keg.\n");
 1513 #endif
 1514         mtx_init(&uma_mtx, "UMA lock", NULL, MTX_DEF);
 1515 
 1516         /*
 1517          * Figure out the maximum number of items-per-slab we'll have if
 1518          * we're using the OFFPAGE slab header to track free items, given
 1519          * all possible object sizes and the maximum desired wastage
 1520          * (UMA_MAX_WASTE).
 1521          *
 1522          * We iterate until we find an object size for
 1523          * which the calculated wastage in zone_small_init() will be
 1524          * enough to warrant OFFPAGE.  Since wastedspace versus objsize
 1525          * is an overall increasing see-saw function, we find the smallest
 1526          * objsize such that the wastage is always acceptable for objects
 1527          * with that objsize or smaller.  Since a smaller objsize always
 1528          * generates a larger possible uma_max_ipers, we use this computed
 1529          * objsize to calculate the largest ipers possible.  Since the
 1530          * ipers calculated for OFFPAGE slab headers is always larger than
 1531          * the ipers initially calculated in zone_small_init(), we use
 1532          * the former's equation (UMA_SLAB_SIZE / keg->uk_rsize) to
 1533          * obtain the maximum ipers possible for offpage slab headers.
 1534          *
 1535          * It should be noted that ipers versus objsize is an inversly
 1536          * proportional function which drops off rather quickly so as
 1537          * long as our UMA_MAX_WASTE is such that the objsize we calculate
 1538          * falls into the portion of the inverse relation AFTER the steep
 1539          * falloff, then uma_max_ipers shouldn't be too high (~10 on i386).
 1540          *
 1541          * Note that we have 8-bits (1 byte) to use as a freelist index
 1542          * inside the actual slab header itself and this is enough to
 1543          * accomodate us.  In the worst case, a UMA_SMALLEST_UNIT sized
 1544          * object with offpage slab header would have ipers =
 1545          * UMA_SLAB_SIZE / UMA_SMALLEST_UNIT (currently = 256), which is
 1546          * 1 greater than what our byte-integer freelist index can
 1547          * accomodate, but we know that this situation never occurs as
 1548          * for UMA_SMALLEST_UNIT-sized objects, we will never calculate
 1549          * that we need to go to offpage slab headers.  Or, if we do,
 1550          * then we trap that condition below and panic in the INVARIANTS case.
 1551          */
 1552         wsize = UMA_SLAB_SIZE - sizeof(struct uma_slab) - UMA_MAX_WASTE;
 1553         totsize = wsize;
 1554         objsize = UMA_SMALLEST_UNIT;
 1555         while (totsize >= wsize) {
 1556                 totsize = (UMA_SLAB_SIZE - sizeof(struct uma_slab)) /
 1557                     (objsize + UMA_FRITM_SZ);
 1558                 totsize *= (UMA_FRITM_SZ + objsize);
 1559                 objsize++;
 1560         }
 1561         if (objsize > UMA_SMALLEST_UNIT)
 1562                 objsize--;
 1563         uma_max_ipers = UMA_SLAB_SIZE / objsize;
 1564 
 1565         wsize = UMA_SLAB_SIZE - sizeof(struct uma_slab_refcnt) - UMA_MAX_WASTE;
 1566         totsize = wsize;
 1567         objsize = UMA_SMALLEST_UNIT;
 1568         while (totsize >= wsize) {
 1569                 totsize = (UMA_SLAB_SIZE - sizeof(struct uma_slab_refcnt)) /
 1570                     (objsize + UMA_FRITMREF_SZ);
 1571                 totsize *= (UMA_FRITMREF_SZ + objsize);
 1572                 objsize++;
 1573         }
 1574         if (objsize > UMA_SMALLEST_UNIT)
 1575                 objsize--;
 1576         uma_max_ipers_ref = UMA_SLAB_SIZE / objsize;
 1577 
 1578         KASSERT((uma_max_ipers_ref <= 255) && (uma_max_ipers <= 255),
 1579             ("uma_startup: calculated uma_max_ipers values too large!"));
 1580 
 1581 #ifdef UMA_DEBUG
 1582         printf("Calculated uma_max_ipers (for OFFPAGE) is %d\n", uma_max_ipers);
 1583         printf("Calculated uma_max_ipers_slab (for OFFPAGE) is %d\n",
 1584             uma_max_ipers_ref);
 1585 #endif
 1586 
 1587         /* "manually" create the initial zone */
 1588         args.name = "UMA Kegs";
 1589         args.size = sizeof(struct uma_keg);
 1590         args.ctor = keg_ctor;
 1591         args.dtor = keg_dtor;
 1592         args.uminit = zero_init;
 1593         args.fini = NULL;
 1594         args.keg = &masterkeg;
 1595         args.align = 32 - 1;
 1596         args.flags = UMA_ZFLAG_INTERNAL;
 1597         /* The initial zone has no Per cpu queues so it's smaller */
 1598         zone_ctor(kegs, sizeof(struct uma_zone), &args, M_WAITOK);
 1599 
 1600 #ifdef UMA_DEBUG
 1601         printf("Filling boot free list.\n");
 1602 #endif
 1603         for (i = 0; i < boot_pages; i++) {
 1604                 slab = (uma_slab_t)((u_int8_t *)bootmem + (i * UMA_SLAB_SIZE));
 1605                 slab->us_data = (u_int8_t *)slab;
 1606                 slab->us_flags = UMA_SLAB_BOOT;
 1607                 LIST_INSERT_HEAD(&uma_boot_pages, slab, us_link);
 1608         }
 1609         mtx_init(&uma_boot_pages_mtx, "UMA boot pages", NULL, MTX_DEF);
 1610 
 1611 #ifdef UMA_DEBUG
 1612         printf("Creating uma zone headers zone and keg.\n");
 1613 #endif
 1614         args.name = "UMA Zones";
 1615         args.size = sizeof(struct uma_zone) +
 1616             (sizeof(struct uma_cache) * (mp_maxid + 1));
 1617         args.ctor = zone_ctor;
 1618         args.dtor = zone_dtor;
 1619         args.uminit = zero_init;
 1620         args.fini = NULL;
 1621         args.keg = NULL;
 1622         args.align = 32 - 1;
 1623         args.flags = UMA_ZFLAG_INTERNAL;
 1624         /* The initial zone has no Per cpu queues so it's smaller */
 1625         zone_ctor(zones, sizeof(struct uma_zone), &args, M_WAITOK);
 1626 
 1627 #ifdef UMA_DEBUG
 1628         printf("Initializing pcpu cache locks.\n");
 1629 #endif
 1630 #ifdef UMA_DEBUG
 1631         printf("Creating slab and hash zones.\n");
 1632 #endif
 1633 
 1634         /*
 1635          * This is the max number of free list items we'll have with
 1636          * offpage slabs.
 1637          */
 1638         slabsize = uma_max_ipers * UMA_FRITM_SZ;
 1639         slabsize += sizeof(struct uma_slab);
 1640 
 1641         /* Now make a zone for slab headers */
 1642         slabzone = uma_zcreate("UMA Slabs",
 1643                                 slabsize,
 1644                                 NULL, NULL, NULL, NULL,
 1645                                 UMA_ALIGN_PTR, UMA_ZFLAG_INTERNAL);
 1646 
 1647         /*
 1648          * We also create a zone for the bigger slabs with reference
 1649          * counts in them, to accomodate UMA_ZONE_REFCNT zones.
 1650          */
 1651         slabsize = uma_max_ipers_ref * UMA_FRITMREF_SZ;
 1652         slabsize += sizeof(struct uma_slab_refcnt);
 1653         slabrefzone = uma_zcreate("UMA RCntSlabs",
 1654                                   slabsize,
 1655                                   NULL, NULL, NULL, NULL,
 1656                                   UMA_ALIGN_PTR,
 1657                                   UMA_ZFLAG_INTERNAL);
 1658 
 1659         hashzone = uma_zcreate("UMA Hash",
 1660             sizeof(struct slabhead *) * UMA_HASH_SIZE_INIT,
 1661             NULL, NULL, NULL, NULL,
 1662             UMA_ALIGN_PTR, UMA_ZFLAG_INTERNAL);
 1663 
 1664         bucket_init();
 1665 
 1666 #ifdef UMA_MD_SMALL_ALLOC
 1667         booted = 1;
 1668 #endif
 1669 
 1670 #ifdef UMA_DEBUG
 1671         printf("UMA startup complete.\n");
 1672 #endif
 1673 }
 1674 
 1675 /* see uma.h */
 1676 void
 1677 uma_startup2(void)
 1678 {
 1679         booted = 1;
 1680         bucket_enable();
 1681 #ifdef UMA_DEBUG
 1682         printf("UMA startup2 complete.\n");
 1683 #endif
 1684 }
 1685 
 1686 /*
 1687  * Initialize our callout handle
 1688  *
 1689  */
 1690 
 1691 static void
 1692 uma_startup3(void)
 1693 {
 1694 #ifdef UMA_DEBUG
 1695         printf("Starting callout.\n");
 1696 #endif
 1697         callout_init(&uma_callout, CALLOUT_MPSAFE);
 1698         callout_reset(&uma_callout, UMA_TIMEOUT * hz, uma_timeout, NULL);
 1699 #ifdef UMA_DEBUG
 1700         printf("UMA startup3 complete.\n");
 1701 #endif
 1702 }
 1703 
 1704 static uma_zone_t
 1705 uma_kcreate(uma_zone_t zone, size_t size, uma_init uminit, uma_fini fini,
 1706                 int align, u_int32_t flags)
 1707 {
 1708         struct uma_kctor_args args;
 1709 
 1710         args.size = size;
 1711         args.uminit = uminit;
 1712         args.fini = fini;
 1713         args.align = (align == UMA_ALIGN_CACHE) ? uma_align_cache : align;
 1714         args.flags = flags;
 1715         args.zone = zone;
 1716         return (uma_zalloc_internal(kegs, &args, M_WAITOK));
 1717 }
 1718 
 1719 /* See uma.h */
 1720 void
 1721 uma_set_align(int align)
 1722 {
 1723 
 1724         if (align != UMA_ALIGN_CACHE)
 1725                 uma_align_cache = align;
 1726 }
 1727 
 1728 /* See uma.h */
 1729 uma_zone_t
 1730 uma_zcreate(char *name, size_t size, uma_ctor ctor, uma_dtor dtor,
 1731                 uma_init uminit, uma_fini fini, int align, u_int32_t flags)
 1732 
 1733 {
 1734         struct uma_zctor_args args;
 1735 
 1736         /* This stuff is essential for the zone ctor */
 1737         args.name = name;
 1738         args.size = size;
 1739         args.ctor = ctor;
 1740         args.dtor = dtor;
 1741         args.uminit = uminit;
 1742         args.fini = fini;
 1743         args.align = align;
 1744         args.flags = flags;
 1745         args.keg = NULL;
 1746 
 1747         return (uma_zalloc_internal(zones, &args, M_WAITOK));
 1748 }
 1749 
 1750 /* See uma.h */
 1751 uma_zone_t
 1752 uma_zsecond_create(char *name, uma_ctor ctor, uma_dtor dtor,
 1753                     uma_init zinit, uma_fini zfini, uma_zone_t master)
 1754 {
 1755         struct uma_zctor_args args;
 1756 
 1757         args.name = name;
 1758         args.size = master->uz_keg->uk_size;
 1759         args.ctor = ctor;
 1760         args.dtor = dtor;
 1761         args.uminit = zinit;
 1762         args.fini = zfini;
 1763         args.align = master->uz_keg->uk_align;
 1764         args.flags = master->uz_keg->uk_flags | UMA_ZONE_SECONDARY;
 1765         args.keg = master->uz_keg;
 1766 
 1767         return (uma_zalloc_internal(zones, &args, M_WAITOK));
 1768 }
 1769 
 1770 /* See uma.h */
 1771 void
 1772 uma_zdestroy(uma_zone_t zone)
 1773 {
 1774 
 1775         uma_zfree_internal(zones, zone, NULL, SKIP_NONE, ZFREE_STATFREE);
 1776 }
 1777 
 1778 /* See uma.h */
 1779 void *
 1780 uma_zalloc_arg(uma_zone_t zone, void *udata, int flags)
 1781 {
 1782         void *item;
 1783         uma_cache_t cache;
 1784         uma_bucket_t bucket;
 1785         int cpu;
 1786 
 1787         /* This is the fast path allocation */
 1788 #ifdef UMA_DEBUG_ALLOC_1
 1789         printf("Allocating one item from %s(%p)\n", zone->uz_name, zone);
 1790 #endif
 1791         CTR3(KTR_UMA, "uma_zalloc_arg thread %x zone %s flags %d", curthread,
 1792             zone->uz_name, flags);
 1793 
 1794         if (flags & M_WAITOK) {
 1795                 WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
 1796                     "uma_zalloc_arg: zone \"%s\"", zone->uz_name);
 1797         }
 1798 
 1799         /*
 1800          * If possible, allocate from the per-CPU cache.  There are two
 1801          * requirements for safe access to the per-CPU cache: (1) the thread
 1802          * accessing the cache must not be preempted or yield during access,
 1803          * and (2) the thread must not migrate CPUs without switching which
 1804          * cache it accesses.  We rely on a critical section to prevent
 1805          * preemption and migration.  We release the critical section in
 1806          * order to acquire the zone mutex if we are unable to allocate from
 1807          * the current cache; when we re-acquire the critical section, we
 1808          * must detect and handle migration if it has occurred.
 1809          */
 1810 zalloc_restart:
 1811         critical_enter();
 1812         cpu = curcpu;
 1813         cache = &zone->uz_cpu[cpu];
 1814 
 1815 zalloc_start:
 1816         bucket = cache->uc_allocbucket;
 1817 
 1818         if (bucket) {
 1819                 if (bucket->ub_cnt > 0) {
 1820                         bucket->ub_cnt--;
 1821                         item = bucket->ub_bucket[bucket->ub_cnt];
 1822 #ifdef INVARIANTS
 1823                         bucket->ub_bucket[bucket->ub_cnt] = NULL;
 1824 #endif
 1825                         KASSERT(item != NULL,
 1826                             ("uma_zalloc: Bucket pointer mangled."));
 1827                         cache->uc_allocs++;
 1828                         critical_exit();
 1829 #ifdef INVARIANTS
 1830                         ZONE_LOCK(zone);
 1831                         uma_dbg_alloc(zone, NULL, item);
 1832                         ZONE_UNLOCK(zone);
 1833 #endif
 1834                         if (zone->uz_ctor != NULL) {
 1835                                 if (zone->uz_ctor(item, zone->uz_keg->uk_size,
 1836                                     udata, flags) != 0) {
 1837                                         uma_zfree_internal(zone, item, udata,
 1838                                             SKIP_DTOR, ZFREE_STATFAIL |
 1839                                             ZFREE_STATFREE);
 1840                                         return (NULL);
 1841                                 }
 1842                         }
 1843                         if (flags & M_ZERO)
 1844                                 bzero(item, zone->uz_keg->uk_size);
 1845                         return (item);
 1846                 } else if (cache->uc_freebucket) {
 1847                         /*
 1848                          * We have run out of items in our allocbucket.
 1849                          * See if we can switch with our free bucket.
 1850                          */
 1851                         if (cache->uc_freebucket->ub_cnt > 0) {
 1852 #ifdef UMA_DEBUG_ALLOC
 1853                                 printf("uma_zalloc: Swapping empty with"
 1854                                     " alloc.\n");
 1855 #endif
 1856                                 bucket = cache->uc_freebucket;
 1857                                 cache->uc_freebucket = cache->uc_allocbucket;
 1858                                 cache->uc_allocbucket = bucket;
 1859 
 1860                                 goto zalloc_start;
 1861                         }
 1862                 }
 1863         }
 1864         /*
 1865          * Attempt to retrieve the item from the per-CPU cache has failed, so
 1866          * we must go back to the zone.  This requires the zone lock, so we
 1867          * must drop the critical section, then re-acquire it when we go back
 1868          * to the cache.  Since the critical section is released, we may be
 1869          * preempted or migrate.  As such, make sure not to maintain any
 1870          * thread-local state specific to the cache from prior to releasing
 1871          * the critical section.
 1872          */
 1873         critical_exit();
 1874         ZONE_LOCK(zone);
 1875         critical_enter();
 1876         cpu = curcpu;
 1877         cache = &zone->uz_cpu[cpu];
 1878         bucket = cache->uc_allocbucket;
 1879         if (bucket != NULL) {
 1880                 if (bucket->ub_cnt > 0) {
 1881                         ZONE_UNLOCK(zone);
 1882                         goto zalloc_start;
 1883                 }
 1884                 bucket = cache->uc_freebucket;
 1885                 if (bucket != NULL && bucket->ub_cnt > 0) {
 1886                         ZONE_UNLOCK(zone);
 1887                         goto zalloc_start;
 1888                 }
 1889         }
 1890 
 1891         /* Since we have locked the zone we may as well send back our stats */
 1892         zone->uz_allocs += cache->uc_allocs;
 1893         cache->uc_allocs = 0;
 1894         zone->uz_frees += cache->uc_frees;
 1895         cache->uc_frees = 0;
 1896 
 1897         /* Our old one is now a free bucket */
 1898         if (cache->uc_allocbucket) {
 1899                 KASSERT(cache->uc_allocbucket->ub_cnt == 0,
 1900                     ("uma_zalloc_arg: Freeing a non free bucket."));
 1901                 LIST_INSERT_HEAD(&zone->uz_free_bucket,
 1902                     cache->uc_allocbucket, ub_link);
 1903                 cache->uc_allocbucket = NULL;
 1904         }
 1905 
 1906         /* Check the free list for a new alloc bucket */
 1907         if ((bucket = LIST_FIRST(&zone->uz_full_bucket)) != NULL) {
 1908                 KASSERT(bucket->ub_cnt != 0,
 1909                     ("uma_zalloc_arg: Returning an empty bucket."));
 1910 
 1911                 LIST_REMOVE(bucket, ub_link);
 1912                 cache->uc_allocbucket = bucket;
 1913                 ZONE_UNLOCK(zone);
 1914                 goto zalloc_start;
 1915         }
 1916         /* We are no longer associated with this CPU. */
 1917         critical_exit();
 1918 
 1919         /* Bump up our uz_count so we get here less */
 1920         if (zone->uz_count < BUCKET_MAX)
 1921                 zone->uz_count++;
 1922 
 1923         /*
 1924          * Now lets just fill a bucket and put it on the free list.  If that
 1925          * works we'll restart the allocation from the begining.
 1926          */
 1927         if (uma_zalloc_bucket(zone, flags)) {
 1928                 ZONE_UNLOCK(zone);
 1929                 goto zalloc_restart;
 1930         }
 1931         ZONE_UNLOCK(zone);
 1932         /*
 1933          * We may not be able to get a bucket so return an actual item.
 1934          */
 1935 #ifdef UMA_DEBUG
 1936         printf("uma_zalloc_arg: Bucketzone returned NULL\n");
 1937 #endif
 1938 
 1939         return (uma_zalloc_internal(zone, udata, flags));
 1940 }
 1941 
 1942 static uma_slab_t
 1943 uma_zone_slab(uma_zone_t zone, int flags)
 1944 {
 1945         uma_slab_t slab;
 1946         uma_keg_t keg;
 1947 
 1948         keg = zone->uz_keg;
 1949 
 1950         /*
 1951          * This is to prevent us from recursively trying to allocate
 1952          * buckets.  The problem is that if an allocation forces us to
 1953          * grab a new bucket we will call page_alloc, which will go off
 1954          * and cause the vm to allocate vm_map_entries.  If we need new
 1955          * buckets there too we will recurse in kmem_alloc and bad
 1956          * things happen.  So instead we return a NULL bucket, and make
 1957          * the code that allocates buckets smart enough to deal with it
 1958          *
 1959          * XXX: While we want this protection for the bucket zones so that
 1960          * recursion from the VM is handled (and the calling code that
 1961          * allocates buckets knows how to deal with it), we do not want
 1962          * to prevent allocation from the slab header zones (slabzone
 1963          * and slabrefzone) if uk_recurse is not zero for them.  The
 1964          * reason is that it could lead to NULL being returned for
 1965          * slab header allocations even in the M_WAITOK case, and the
 1966          * caller can't handle that. 
 1967          */
 1968         if (keg->uk_flags & UMA_ZFLAG_INTERNAL && keg->uk_recurse != 0)
 1969                 if (zone != slabzone && zone != slabrefzone && zone != zones)
 1970                         return (NULL);
 1971 
 1972         slab = NULL;
 1973 
 1974         for (;;) {
 1975                 /*
 1976                  * Find a slab with some space.  Prefer slabs that are partially
 1977                  * used over those that are totally full.  This helps to reduce
 1978                  * fragmentation.
 1979                  */
 1980                 if (keg->uk_free != 0) {
 1981                         if (!LIST_EMPTY(&keg->uk_part_slab)) {
 1982                                 slab = LIST_FIRST(&keg->uk_part_slab);
 1983                         } else {
 1984                                 slab = LIST_FIRST(&keg->uk_free_slab);
 1985                                 LIST_REMOVE(slab, us_link);
 1986                                 LIST_INSERT_HEAD(&keg->uk_part_slab, slab,
 1987                                     us_link);
 1988                         }
 1989                         return (slab);
 1990                 }
 1991 
 1992                 /*
 1993                  * M_NOVM means don't ask at all!
 1994                  */
 1995                 if (flags & M_NOVM)
 1996                         break;
 1997 
 1998                 if (keg->uk_maxpages &&
 1999                     keg->uk_pages >= keg->uk_maxpages) {
 2000                         keg->uk_flags |= UMA_ZFLAG_FULL;
 2001 
 2002                         if (flags & M_NOWAIT)
 2003                                 break;
 2004                         else
 2005                                 msleep(keg, &keg->uk_lock, PVM,
 2006                                     "zonelimit", 0);
 2007                         continue;
 2008                 }
 2009                 keg->uk_recurse++;
 2010                 slab = slab_zalloc(zone, flags);
 2011                 keg->uk_recurse--;
 2012 
 2013                 /*
 2014                  * If we got a slab here it's safe to mark it partially used
 2015                  * and return.  We assume that the caller is going to remove
 2016                  * at least one item.
 2017                  */
 2018                 if (slab) {
 2019                         LIST_INSERT_HEAD(&keg->uk_part_slab, slab, us_link);
 2020                         return (slab);
 2021                 }
 2022                 /*
 2023                  * We might not have been able to get a slab but another cpu
 2024                  * could have while we were unlocked.  Check again before we
 2025                  * fail.
 2026                  */
 2027                 if (flags & M_NOWAIT)
 2028                         flags |= M_NOVM;
 2029         }
 2030         return (slab);
 2031 }
 2032 
 2033 static void *
 2034 uma_slab_alloc(uma_zone_t zone, uma_slab_t slab)
 2035 {
 2036         uma_keg_t keg;
 2037         uma_slabrefcnt_t slabref;
 2038         void *item;
 2039         u_int8_t freei;
 2040 
 2041         keg = zone->uz_keg;
 2042 
 2043         freei = slab->us_firstfree;
 2044         if (keg->uk_flags & UMA_ZONE_REFCNT) {
 2045                 slabref = (uma_slabrefcnt_t)slab;
 2046                 slab->us_firstfree = slabref->us_freelist[freei].us_item;
 2047         } else {
 2048                 slab->us_firstfree = slab->us_freelist[freei].us_item;
 2049         }
 2050         item = slab->us_data + (keg->uk_rsize * freei);
 2051 
 2052         slab->us_freecount--;
 2053         keg->uk_free--;
 2054 #ifdef INVARIANTS
 2055         uma_dbg_alloc(zone, slab, item);
 2056 #endif
 2057         /* Move this slab to the full list */
 2058         if (slab->us_freecount == 0) {
 2059                 LIST_REMOVE(slab, us_link);
 2060                 LIST_INSERT_HEAD(&keg->uk_full_slab, slab, us_link);
 2061         }
 2062 
 2063         return (item);
 2064 }
 2065 
 2066 static int
 2067 uma_zalloc_bucket(uma_zone_t zone, int flags)
 2068 {
 2069         uma_bucket_t bucket;
 2070         uma_slab_t slab;
 2071         int16_t saved;
 2072         int max, origflags = flags;
 2073 
 2074         /*
 2075          * Try this zone's free list first so we don't allocate extra buckets.
 2076          */
 2077         if ((bucket = LIST_FIRST(&zone->uz_free_bucket)) != NULL) {
 2078                 KASSERT(bucket->ub_cnt == 0,
 2079                     ("uma_zalloc_bucket: Bucket on free list is not empty."));
 2080                 LIST_REMOVE(bucket, ub_link);
 2081         } else {
 2082                 int bflags;
 2083 
 2084                 bflags = (flags & ~M_ZERO);
 2085                 if (zone->uz_keg->uk_flags & UMA_ZFLAG_CACHEONLY)
 2086                         bflags |= M_NOVM;
 2087 
 2088                 ZONE_UNLOCK(zone);
 2089                 bucket = bucket_alloc(zone->uz_count, bflags);
 2090                 ZONE_LOCK(zone);
 2091         }
 2092 
 2093         if (bucket == NULL)
 2094                 return (0);
 2095 
 2096 #ifdef SMP
 2097         /*
 2098          * This code is here to limit the number of simultaneous bucket fills
 2099          * for any given zone to the number of per cpu caches in this zone. This
 2100          * is done so that we don't allocate more memory than we really need.
 2101          */
 2102         if (zone->uz_fills >= mp_ncpus)
 2103                 goto done;
 2104 
 2105 #endif
 2106         zone->uz_fills++;
 2107 
 2108         max = MIN(bucket->ub_entries, zone->uz_count);
 2109         /* Try to keep the buckets totally full */
 2110         saved = bucket->ub_cnt;
 2111         while (bucket->ub_cnt < max &&
 2112             (slab = uma_zone_slab(zone, flags)) != NULL) {
 2113                 while (slab->us_freecount && bucket->ub_cnt < max) {
 2114                         bucket->ub_bucket[bucket->ub_cnt++] =
 2115                             uma_slab_alloc(zone, slab);
 2116                 }
 2117 
 2118                 /* Don't block on the next fill */
 2119                 flags |= M_NOWAIT;
 2120         }
 2121 
 2122         /*
 2123          * We unlock here because we need to call the zone's init.
 2124          * It should be safe to unlock because the slab dealt with
 2125          * above is already on the appropriate list within the keg
 2126          * and the bucket we filled is not yet on any list, so we
 2127          * own it.
 2128          */
 2129         if (zone->uz_init != NULL) {
 2130                 int i;
 2131 
 2132                 ZONE_UNLOCK(zone);
 2133                 for (i = saved; i < bucket->ub_cnt; i++)
 2134                         if (zone->uz_init(bucket->ub_bucket[i],
 2135                             zone->uz_keg->uk_size, origflags) != 0)
 2136                                 break;
 2137                 /*
 2138                  * If we couldn't initialize the whole bucket, put the
 2139                  * rest back onto the freelist.
 2140                  */
 2141                 if (i != bucket->ub_cnt) {
 2142                         int j;
 2143 
 2144                         for (j = i; j < bucket->ub_cnt; j++) {
 2145                                 uma_zfree_internal(zone, bucket->ub_bucket[j],
 2146                                     NULL, SKIP_FINI, 0);
 2147 #ifdef INVARIANTS
 2148                                 bucket->ub_bucket[j] = NULL;
 2149 #endif
 2150                         }
 2151                         bucket->ub_cnt = i;
 2152                 }
 2153                 ZONE_LOCK(zone);
 2154         }
 2155 
 2156         zone->uz_fills--;
 2157         if (bucket->ub_cnt != 0) {
 2158                 LIST_INSERT_HEAD(&zone->uz_full_bucket,
 2159                     bucket, ub_link);
 2160                 return (1);
 2161         }
 2162 #ifdef SMP
 2163 done:
 2164 #endif
 2165         bucket_free(bucket);
 2166 
 2167         return (0);
 2168 }
 2169 /*
 2170  * Allocates an item for an internal zone
 2171  *
 2172  * Arguments
 2173  *      zone   The zone to alloc for.
 2174  *      udata  The data to be passed to the constructor.
 2175  *      flags  M_WAITOK, M_NOWAIT, M_ZERO.
 2176  *
 2177  * Returns
 2178  *      NULL if there is no memory and M_NOWAIT is set
 2179  *      An item if successful
 2180  */
 2181 
 2182 static void *
 2183 uma_zalloc_internal(uma_zone_t zone, void *udata, int flags)
 2184 {
 2185         uma_keg_t keg;
 2186         uma_slab_t slab;
 2187         void *item;
 2188 
 2189         item = NULL;
 2190         keg = zone->uz_keg;
 2191 
 2192 #ifdef UMA_DEBUG_ALLOC
 2193         printf("INTERNAL: Allocating one item from %s(%p)\n", zone->uz_name, zone);
 2194 #endif
 2195         ZONE_LOCK(zone);
 2196 
 2197         slab = uma_zone_slab(zone, flags);
 2198         if (slab == NULL) {
 2199                 zone->uz_fails++;
 2200                 ZONE_UNLOCK(zone);
 2201                 return (NULL);
 2202         }
 2203 
 2204         item = uma_slab_alloc(zone, slab);
 2205 
 2206         zone->uz_allocs++;
 2207 
 2208         ZONE_UNLOCK(zone);
 2209 
 2210         /*
 2211          * We have to call both the zone's init (not the keg's init)
 2212          * and the zone's ctor.  This is because the item is going from
 2213          * a keg slab directly to the user, and the user is expecting it
 2214          * to be both zone-init'd as well as zone-ctor'd.
 2215          */
 2216         if (zone->uz_init != NULL) {
 2217                 if (zone->uz_init(item, keg->uk_size, flags) != 0) {
 2218                         uma_zfree_internal(zone, item, udata, SKIP_FINI,
 2219                             ZFREE_STATFAIL | ZFREE_STATFREE);
 2220                         return (NULL);
 2221                 }
 2222         }
 2223         if (zone->uz_ctor != NULL) {
 2224                 if (zone->uz_ctor(item, keg->uk_size, udata, flags) != 0) {
 2225                         uma_zfree_internal(zone, item, udata, SKIP_DTOR,
 2226                             ZFREE_STATFAIL | ZFREE_STATFREE);
 2227                         return (NULL);
 2228                 }
 2229         }
 2230         if (flags & M_ZERO)
 2231                 bzero(item, keg->uk_size);
 2232 
 2233         return (item);
 2234 }
 2235 
 2236 /* See uma.h */
 2237 void
 2238 uma_zfree_arg(uma_zone_t zone, void *item, void *udata)
 2239 {
 2240         uma_keg_t keg;
 2241         uma_cache_t cache;
 2242         uma_bucket_t bucket;
 2243         int bflags;
 2244         int cpu;
 2245 
 2246         keg = zone->uz_keg;
 2247 
 2248 #ifdef UMA_DEBUG_ALLOC_1
 2249         printf("Freeing item %p to %s(%p)\n", item, zone->uz_name, zone);
 2250 #endif
 2251         CTR2(KTR_UMA, "uma_zfree_arg thread %x zone %s", curthread,
 2252             zone->uz_name);
 2253 
 2254         if (zone->uz_dtor)
 2255                 zone->uz_dtor(item, keg->uk_size, udata);
 2256 #ifdef INVARIANTS
 2257         ZONE_LOCK(zone);
 2258         if (keg->uk_flags & UMA_ZONE_MALLOC)
 2259                 uma_dbg_free(zone, udata, item);
 2260         else
 2261                 uma_dbg_free(zone, NULL, item);
 2262         ZONE_UNLOCK(zone);
 2263 #endif
 2264         /*
 2265          * The race here is acceptable.  If we miss it we'll just have to wait
 2266          * a little longer for the limits to be reset.
 2267          */
 2268         if (keg->uk_flags & UMA_ZFLAG_FULL)
 2269                 goto zfree_internal;
 2270 
 2271         /*
 2272          * If possible, free to the per-CPU cache.  There are two
 2273          * requirements for safe access to the per-CPU cache: (1) the thread
 2274          * accessing the cache must not be preempted or yield during access,
 2275          * and (2) the thread must not migrate CPUs without switching which
 2276          * cache it accesses.  We rely on a critical section to prevent
 2277          * preemption and migration.  We release the critical section in
 2278          * order to acquire the zone mutex if we are unable to free to the
 2279          * current cache; when we re-acquire the critical section, we must
 2280          * detect and handle migration if it has occurred.
 2281          */
 2282 zfree_restart:
 2283         critical_enter();
 2284         cpu = curcpu;
 2285         cache = &zone->uz_cpu[cpu];
 2286 
 2287 zfree_start:
 2288         bucket = cache->uc_freebucket;
 2289 
 2290         if (bucket) {
 2291                 /*
 2292                  * Do we have room in our bucket? It is OK for this uz count
 2293                  * check to be slightly out of sync.
 2294                  */
 2295 
 2296                 if (bucket->ub_cnt < bucket->ub_entries) {
 2297                         KASSERT(bucket->ub_bucket[bucket->ub_cnt] == NULL,
 2298                             ("uma_zfree: Freeing to non free bucket index."));
 2299                         bucket->ub_bucket[bucket->ub_cnt] = item;
 2300                         bucket->ub_cnt++;
 2301                         cache->uc_frees++;
 2302                         critical_exit();
 2303                         return;
 2304                 } else if (cache->uc_allocbucket) {
 2305 #ifdef UMA_DEBUG_ALLOC
 2306                         printf("uma_zfree: Swapping buckets.\n");
 2307 #endif
 2308                         /*
 2309                          * We have run out of space in our freebucket.
 2310                          * See if we can switch with our alloc bucket.
 2311                          */
 2312                         if (cache->uc_allocbucket->ub_cnt <
 2313                             cache->uc_freebucket->ub_cnt) {
 2314                                 bucket = cache->uc_freebucket;
 2315                                 cache->uc_freebucket = cache->uc_allocbucket;
 2316                                 cache->uc_allocbucket = bucket;
 2317                                 goto zfree_start;
 2318                         }
 2319                 }
 2320         }
 2321         /*
 2322          * We can get here for two reasons:
 2323          *
 2324          * 1) The buckets are NULL
 2325          * 2) The alloc and free buckets are both somewhat full.
 2326          *
 2327          * We must go back the zone, which requires acquiring the zone lock,
 2328          * which in turn means we must release and re-acquire the critical
 2329          * section.  Since the critical section is released, we may be
 2330          * preempted or migrate.  As such, make sure not to maintain any
 2331          * thread-local state specific to the cache from prior to releasing
 2332          * the critical section.
 2333          */
 2334         critical_exit();
 2335         ZONE_LOCK(zone);
 2336         critical_enter();
 2337         cpu = curcpu;
 2338         cache = &zone->uz_cpu[cpu];
 2339         if (cache->uc_freebucket != NULL) {
 2340                 if (cache->uc_freebucket->ub_cnt <
 2341                     cache->uc_freebucket->ub_entries) {
 2342                         ZONE_UNLOCK(zone);
 2343                         goto zfree_start;
 2344                 }
 2345                 if (cache->uc_allocbucket != NULL &&
 2346                     (cache->uc_allocbucket->ub_cnt <
 2347                     cache->uc_freebucket->ub_cnt)) {
 2348                         ZONE_UNLOCK(zone);
 2349                         goto zfree_start;
 2350                 }
 2351         }
 2352 
 2353         /* Since we have locked the zone we may as well send back our stats */
 2354         zone->uz_allocs += cache->uc_allocs;
 2355         cache->uc_allocs = 0;
 2356         zone->uz_frees += cache->uc_frees;
 2357         cache->uc_frees = 0;
 2358 
 2359         bucket = cache->uc_freebucket;
 2360         cache->uc_freebucket = NULL;
 2361 
 2362         /* Can we throw this on the zone full list? */
 2363         if (bucket != NULL) {
 2364 #ifdef UMA_DEBUG_ALLOC
 2365                 printf("uma_zfree: Putting old bucket on the free list.\n");
 2366 #endif
 2367                 /* ub_cnt is pointing to the last free item */
 2368                 KASSERT(bucket->ub_cnt != 0,
 2369                     ("uma_zfree: Attempting to insert an empty bucket onto the full list.\n"));
 2370                 LIST_INSERT_HEAD(&zone->uz_full_bucket,
 2371                     bucket, ub_link);
 2372         }
 2373         if ((bucket = LIST_FIRST(&zone->uz_free_bucket)) != NULL) {
 2374                 LIST_REMOVE(bucket, ub_link);
 2375                 ZONE_UNLOCK(zone);
 2376                 cache->uc_freebucket = bucket;
 2377                 goto zfree_start;
 2378         }
 2379         /* We are no longer associated with this CPU. */
 2380         critical_exit();
 2381 
 2382         /* And the zone.. */
 2383         ZONE_UNLOCK(zone);
 2384 
 2385 #ifdef UMA_DEBUG_ALLOC
 2386         printf("uma_zfree: Allocating new free bucket.\n");
 2387 #endif
 2388         bflags = M_NOWAIT;
 2389 
 2390         if (keg->uk_flags & UMA_ZFLAG_CACHEONLY)
 2391                 bflags |= M_NOVM;
 2392         bucket = bucket_alloc(zone->uz_count, bflags);
 2393         if (bucket) {
 2394                 ZONE_LOCK(zone);
 2395                 LIST_INSERT_HEAD(&zone->uz_free_bucket,
 2396                     bucket, ub_link);
 2397                 ZONE_UNLOCK(zone);
 2398                 goto zfree_restart;
 2399         }
 2400 
 2401         /*
 2402          * If nothing else caught this, we'll just do an internal free.
 2403          */
 2404 zfree_internal:
 2405         uma_zfree_internal(zone, item, udata, SKIP_DTOR, ZFREE_STATFREE);
 2406 
 2407         return;
 2408 }
 2409 
 2410 /*
 2411  * Frees an item to an INTERNAL zone or allocates a free bucket
 2412  *
 2413  * Arguments:
 2414  *      zone   The zone to free to
 2415  *      item   The item we're freeing
 2416  *      udata  User supplied data for the dtor
 2417  *      skip   Skip dtors and finis
 2418  */
 2419 static void
 2420 uma_zfree_internal(uma_zone_t zone, void *item, void *udata,
 2421     enum zfreeskip skip, int flags)
 2422 {
 2423         uma_slab_t slab;
 2424         uma_slabrefcnt_t slabref;
 2425         uma_keg_t keg;
 2426         u_int8_t *mem;
 2427         u_int8_t freei;
 2428 
 2429         keg = zone->uz_keg;
 2430 
 2431         if (skip < SKIP_DTOR && zone->uz_dtor)
 2432                 zone->uz_dtor(item, keg->uk_size, udata);
 2433         if (skip < SKIP_FINI && zone->uz_fini)
 2434                 zone->uz_fini(item, keg->uk_size);
 2435 
 2436         ZONE_LOCK(zone);
 2437 
 2438         if (flags & ZFREE_STATFAIL)
 2439                 zone->uz_fails++;
 2440         if (flags & ZFREE_STATFREE)
 2441                 zone->uz_frees++;
 2442 
 2443         if (!(keg->uk_flags & UMA_ZONE_MALLOC)) {
 2444                 mem = (u_int8_t *)((unsigned long)item & (~UMA_SLAB_MASK));
 2445                 if (keg->uk_flags & UMA_ZONE_HASH)
 2446                         slab = hash_sfind(&keg->uk_hash, mem);
 2447                 else {
 2448                         mem += keg->uk_pgoff;
 2449                         slab = (uma_slab_t)mem;
 2450                 }
 2451         } else {
 2452                 slab = (uma_slab_t)udata;
 2453         }
 2454 
 2455         /* Do we need to remove from any lists? */
 2456         if (slab->us_freecount+1 == keg->uk_ipers) {
 2457                 LIST_REMOVE(slab, us_link);
 2458                 LIST_INSERT_HEAD(&keg->uk_free_slab, slab, us_link);
 2459         } else if (slab->us_freecount == 0) {
 2460                 LIST_REMOVE(slab, us_link);
 2461                 LIST_INSERT_HEAD(&keg->uk_part_slab, slab, us_link);
 2462         }
 2463 
 2464         /* Slab management stuff */
 2465         freei = ((unsigned long)item - (unsigned long)slab->us_data)
 2466                 / keg->uk_rsize;
 2467 
 2468 #ifdef INVARIANTS
 2469         if (!skip)
 2470                 uma_dbg_free(zone, slab, item);
 2471 #endif
 2472 
 2473         if (keg->uk_flags & UMA_ZONE_REFCNT) {
 2474                 slabref = (uma_slabrefcnt_t)slab;
 2475                 slabref->us_freelist[freei].us_item = slab->us_firstfree;
 2476         } else {
 2477                 slab->us_freelist[freei].us_item = slab->us_firstfree;
 2478         }
 2479         slab->us_firstfree = freei;
 2480         slab->us_freecount++;
 2481 
 2482         /* Zone statistics */
 2483         keg->uk_free++;
 2484 
 2485         if (keg->uk_flags & UMA_ZFLAG_FULL) {
 2486                 if (keg->uk_pages < keg->uk_maxpages)
 2487                         keg->uk_flags &= ~UMA_ZFLAG_FULL;
 2488 
 2489                 /* 
 2490                  * We can handle one more allocation. Since we're clearing ZFLAG_FULL,
 2491                  * wake up all procs blocked on pages. This should be uncommon, so 
 2492                  * keeping this simple for now (rather than adding count of blocked 
 2493                  * threads etc).
 2494                  */
 2495                 wakeup(keg);
 2496         }
 2497 
 2498         ZONE_UNLOCK(zone);
 2499 }
 2500 
 2501 /* See uma.h */
 2502 void
 2503 uma_zone_set_max(uma_zone_t zone, int nitems)
 2504 {
 2505         uma_keg_t keg;
 2506 
 2507         keg = zone->uz_keg;
 2508         ZONE_LOCK(zone);
 2509         if (keg->uk_ppera > 1)
 2510                 keg->uk_maxpages = nitems * keg->uk_ppera;
 2511         else
 2512                 keg->uk_maxpages = nitems / keg->uk_ipers;
 2513 
 2514         if (keg->uk_maxpages * keg->uk_ipers < nitems)
 2515                 keg->uk_maxpages++;
 2516 
 2517         ZONE_UNLOCK(zone);
 2518 }
 2519 
 2520 /* See uma.h */
 2521 void
 2522 uma_zone_set_init(uma_zone_t zone, uma_init uminit)
 2523 {
 2524         ZONE_LOCK(zone);
 2525         KASSERT(zone->uz_keg->uk_pages == 0,
 2526             ("uma_zone_set_init on non-empty keg"));
 2527         zone->uz_keg->uk_init = uminit;
 2528         ZONE_UNLOCK(zone);
 2529 }
 2530 
 2531 /* See uma.h */
 2532 void
 2533 uma_zone_set_fini(uma_zone_t zone, uma_fini fini)
 2534 {
 2535         ZONE_LOCK(zone);
 2536         KASSERT(zone->uz_keg->uk_pages == 0,
 2537             ("uma_zone_set_fini on non-empty keg"));
 2538         zone->uz_keg->uk_fini = fini;
 2539         ZONE_UNLOCK(zone);
 2540 }
 2541 
 2542 /* See uma.h */
 2543 void
 2544 uma_zone_set_zinit(uma_zone_t zone, uma_init zinit)
 2545 {
 2546         ZONE_LOCK(zone);
 2547         KASSERT(zone->uz_keg->uk_pages == 0,
 2548             ("uma_zone_set_zinit on non-empty keg"));
 2549         zone->uz_init = zinit;
 2550         ZONE_UNLOCK(zone);
 2551 }
 2552 
 2553 /* See uma.h */
 2554 void
 2555 uma_zone_set_zfini(uma_zone_t zone, uma_fini zfini)
 2556 {
 2557         ZONE_LOCK(zone);
 2558         KASSERT(zone->uz_keg->uk_pages == 0,
 2559             ("uma_zone_set_zfini on non-empty keg"));
 2560         zone->uz_fini = zfini;
 2561         ZONE_UNLOCK(zone);
 2562 }
 2563 
 2564 /* See uma.h */
 2565 /* XXX uk_freef is not actually used with the zone locked */
 2566 void
 2567 uma_zone_set_freef(uma_zone_t zone, uma_free freef)
 2568 {
 2569         ZONE_LOCK(zone);
 2570         zone->uz_keg->uk_freef = freef;
 2571         ZONE_UNLOCK(zone);
 2572 }
 2573 
 2574 /* See uma.h */
 2575 /* XXX uk_allocf is not actually used with the zone locked */
 2576 void
 2577 uma_zone_set_allocf(uma_zone_t zone, uma_alloc allocf)
 2578 {
 2579         ZONE_LOCK(zone);
 2580         zone->uz_keg->uk_flags |= UMA_ZFLAG_PRIVALLOC;
 2581         zone->uz_keg->uk_allocf = allocf;
 2582         ZONE_UNLOCK(zone);
 2583 }
 2584 
 2585 /* See uma.h */
 2586 int
 2587 uma_zone_set_obj(uma_zone_t zone, struct vm_object *obj, int count)
 2588 {
 2589         uma_keg_t keg;
 2590         vm_offset_t kva;
 2591         int pages;
 2592 
 2593         keg = zone->uz_keg;
 2594         pages = count / keg->uk_ipers;
 2595 
 2596         if (pages * keg->uk_ipers < count)
 2597                 pages++;
 2598 
 2599         kva = kmem_alloc_nofault(kernel_map, pages * UMA_SLAB_SIZE);
 2600 
 2601         if (kva == 0)
 2602                 return (0);
 2603         if (obj == NULL) {
 2604                 obj = vm_object_allocate(OBJT_DEFAULT,
 2605                     pages);
 2606         } else {
 2607                 VM_OBJECT_LOCK_INIT(obj, "uma object");
 2608                 _vm_object_allocate(OBJT_DEFAULT,
 2609                     pages, obj);
 2610         }
 2611         ZONE_LOCK(zone);
 2612         keg->uk_kva = kva;
 2613         keg->uk_obj = obj;
 2614         keg->uk_maxpages = pages;
 2615         keg->uk_allocf = obj_alloc;
 2616         keg->uk_flags |= UMA_ZONE_NOFREE | UMA_ZFLAG_PRIVALLOC;
 2617         ZONE_UNLOCK(zone);
 2618         return (1);
 2619 }
 2620 
 2621 /* See uma.h */
 2622 void
 2623 uma_prealloc(uma_zone_t zone, int items)
 2624 {
 2625         int slabs;
 2626         uma_slab_t slab;
 2627         uma_keg_t keg;
 2628 
 2629         keg = zone->uz_keg;
 2630         ZONE_LOCK(zone);
 2631         slabs = items / keg->uk_ipers;
 2632         if (slabs * keg->uk_ipers < items)
 2633                 slabs++;
 2634         while (slabs > 0) {
 2635                 slab = slab_zalloc(zone, M_WAITOK);
 2636                 LIST_INSERT_HEAD(&keg->uk_free_slab, slab, us_link);
 2637                 slabs--;
 2638         }
 2639         ZONE_UNLOCK(zone);
 2640 }
 2641 
 2642 /* See uma.h */
 2643 u_int32_t *
 2644 uma_find_refcnt(uma_zone_t zone, void *item)
 2645 {
 2646         uma_slabrefcnt_t slabref;
 2647         uma_keg_t keg;
 2648         u_int32_t *refcnt;
 2649         int idx;
 2650 
 2651         keg = zone->uz_keg;
 2652         slabref = (uma_slabrefcnt_t)vtoslab((vm_offset_t)item &
 2653             (~UMA_SLAB_MASK));
 2654         KASSERT(slabref != NULL && slabref->us_keg->uk_flags & UMA_ZONE_REFCNT,
 2655             ("uma_find_refcnt(): zone possibly not UMA_ZONE_REFCNT"));
 2656         idx = ((unsigned long)item - (unsigned long)slabref->us_data)
 2657             / keg->uk_rsize;
 2658         refcnt = &slabref->us_freelist[idx].us_refcnt;
 2659         return refcnt;
 2660 }
 2661 
 2662 /* See uma.h */
 2663 void
 2664 uma_reclaim(void)
 2665 {
 2666 #ifdef UMA_DEBUG
 2667         printf("UMA: vm asked us to release pages!\n");
 2668 #endif
 2669         bucket_enable();
 2670         zone_foreach(zone_drain);
 2671         /*
 2672          * Some slabs may have been freed but this zone will be visited early
 2673          * we visit again so that we can free pages that are empty once other
 2674          * zones are drained.  We have to do the same for buckets.
 2675          */
 2676         zone_drain(slabzone);
 2677         zone_drain(slabrefzone);
 2678         bucket_zone_drain();
 2679 }
 2680 
 2681 /* See uma.h */
 2682 int
 2683 uma_zone_exhausted(uma_zone_t zone)
 2684 {
 2685         int full;
 2686 
 2687         ZONE_LOCK(zone);
 2688         full = (zone->uz_keg->uk_flags & UMA_ZFLAG_FULL);
 2689         ZONE_UNLOCK(zone);
 2690         return (full);  
 2691 }
 2692 
 2693 int
 2694 uma_zone_exhausted_nolock(uma_zone_t zone)
 2695 {
 2696         return (zone->uz_keg->uk_flags & UMA_ZFLAG_FULL);
 2697 }
 2698 
 2699 void *
 2700 uma_large_malloc(int size, int wait)
 2701 {
 2702         void *mem;
 2703         uma_slab_t slab;
 2704         u_int8_t flags;
 2705 
 2706         slab = uma_zalloc_internal(slabzone, NULL, wait);
 2707         if (slab == NULL)
 2708                 return (NULL);
 2709         mem = page_alloc(NULL, size, &flags, wait);
 2710         if (mem) {
 2711                 vsetslab((vm_offset_t)mem, slab);
 2712                 slab->us_data = mem;
 2713                 slab->us_flags = flags | UMA_SLAB_MALLOC;
 2714                 slab->us_size = size;
 2715         } else {
 2716                 uma_zfree_internal(slabzone, slab, NULL, SKIP_NONE,
 2717                     ZFREE_STATFAIL | ZFREE_STATFREE);
 2718         }
 2719 
 2720         return (mem);
 2721 }
 2722 
 2723 void
 2724 uma_large_free(uma_slab_t slab)
 2725 {
 2726         vsetobj((vm_offset_t)slab->us_data, kmem_object);
 2727         page_free(slab->us_data, slab->us_size, slab->us_flags);
 2728         uma_zfree_internal(slabzone, slab, NULL, SKIP_NONE, ZFREE_STATFREE);
 2729 }
 2730 
 2731 void
 2732 uma_print_stats(void)
 2733 {
 2734         zone_foreach(uma_print_zone);
 2735 }
 2736 
 2737 static void
 2738 slab_print(uma_slab_t slab)
 2739 {
 2740         printf("slab: keg %p, data %p, freecount %d, firstfree %d\n",
 2741                 slab->us_keg, slab->us_data, slab->us_freecount,
 2742                 slab->us_firstfree);
 2743 }
 2744 
 2745 static void
 2746 cache_print(uma_cache_t cache)
 2747 {
 2748         printf("alloc: %p(%d), free: %p(%d)\n",
 2749                 cache->uc_allocbucket,
 2750                 cache->uc_allocbucket?cache->uc_allocbucket->ub_cnt:0,
 2751                 cache->uc_freebucket,
 2752                 cache->uc_freebucket?cache->uc_freebucket->ub_cnt:0);
 2753 }
 2754 
 2755 void
 2756 uma_print_zone(uma_zone_t zone)
 2757 {
 2758         uma_cache_t cache;
 2759         uma_keg_t keg;
 2760         uma_slab_t slab;
 2761         int i;
 2762 
 2763         keg = zone->uz_keg;
 2764         printf("%s(%p) size %d(%d) flags %d ipers %d ppera %d out %d free %d\n",
 2765             zone->uz_name, zone, keg->uk_size, keg->uk_rsize, keg->uk_flags,
 2766             keg->uk_ipers, keg->uk_ppera,
 2767             (keg->uk_ipers * keg->uk_pages) - keg->uk_free, keg->uk_free);
 2768         printf("Part slabs:\n");
 2769         LIST_FOREACH(slab, &keg->uk_part_slab, us_link)
 2770                 slab_print(slab);
 2771         printf("Free slabs:\n");
 2772         LIST_FOREACH(slab, &keg->uk_free_slab, us_link)
 2773                 slab_print(slab);
 2774         printf("Full slabs:\n");
 2775         LIST_FOREACH(slab, &keg->uk_full_slab, us_link)
 2776                 slab_print(slab);
 2777         for (i = 0; i <= mp_maxid; i++) {
 2778                 if (CPU_ABSENT(i))
 2779                         continue;
 2780                 cache = &zone->uz_cpu[i];
 2781                 printf("CPU %d Cache:\n", i);
 2782                 cache_print(cache);
 2783         }
 2784 }
 2785 
 2786 #ifdef DDB
 2787 /*
 2788  * Generate statistics across both the zone and its per-cpu cache's.  Return
 2789  * desired statistics if the pointer is non-NULL for that statistic.
 2790  *
 2791  * Note: does not update the zone statistics, as it can't safely clear the
 2792  * per-CPU cache statistic.
 2793  *
 2794  * XXXRW: Following the uc_allocbucket and uc_freebucket pointers here isn't
 2795  * safe from off-CPU; we should modify the caches to track this information
 2796  * directly so that we don't have to.
 2797  */
 2798 static void
 2799 uma_zone_sumstat(uma_zone_t z, int *cachefreep, u_int64_t *allocsp,
 2800     u_int64_t *freesp)
 2801 {
 2802         uma_cache_t cache;
 2803         u_int64_t allocs, frees;
 2804         int cachefree, cpu;
 2805 
 2806         allocs = frees = 0;
 2807         cachefree = 0;
 2808         for (cpu = 0; cpu <= mp_maxid; cpu++) {
 2809                 if (CPU_ABSENT(cpu))
 2810                         continue;
 2811                 cache = &z->uz_cpu[cpu];
 2812                 if (cache->uc_allocbucket != NULL)
 2813                         cachefree += cache->uc_allocbucket->ub_cnt;
 2814                 if (cache->uc_freebucket != NULL)
 2815                         cachefree += cache->uc_freebucket->ub_cnt;
 2816                 allocs += cache->uc_allocs;
 2817                 frees += cache->uc_frees;
 2818         }
 2819         allocs += z->uz_allocs;
 2820         frees += z->uz_frees;
 2821         if (cachefreep != NULL)
 2822                 *cachefreep = cachefree;
 2823         if (allocsp != NULL)
 2824                 *allocsp = allocs;
 2825         if (freesp != NULL)
 2826                 *freesp = frees;
 2827 }
 2828 #endif /* DDB */
 2829 
 2830 static int
 2831 sysctl_vm_zone_count(SYSCTL_HANDLER_ARGS)
 2832 {
 2833         uma_keg_t kz;
 2834         uma_zone_t z;
 2835         int count;
 2836 
 2837         count = 0;
 2838         mtx_lock(&uma_mtx);
 2839         LIST_FOREACH(kz, &uma_kegs, uk_link) {
 2840                 LIST_FOREACH(z, &kz->uk_zones, uz_link)
 2841                         count++;
 2842         }
 2843         mtx_unlock(&uma_mtx);
 2844         return (sysctl_handle_int(oidp, &count, 0, req));
 2845 }
 2846 
 2847 static int
 2848 sysctl_vm_zone_stats(SYSCTL_HANDLER_ARGS)
 2849 {
 2850         struct uma_stream_header ush;
 2851         struct uma_type_header uth;
 2852         struct uma_percpu_stat ups;
 2853         uma_bucket_t bucket;
 2854         struct sbuf sbuf;
 2855         uma_cache_t cache;
 2856         uma_keg_t kz;
 2857         uma_zone_t z;
 2858         char *buffer;
 2859         int buflen, count, error, i;
 2860 
 2861         mtx_lock(&uma_mtx);
 2862 restart:
 2863         mtx_assert(&uma_mtx, MA_OWNED);
 2864         count = 0;
 2865         LIST_FOREACH(kz, &uma_kegs, uk_link) {
 2866                 LIST_FOREACH(z, &kz->uk_zones, uz_link)
 2867                         count++;
 2868         }
 2869         mtx_unlock(&uma_mtx);
 2870 
 2871         buflen = sizeof(ush) + count * (sizeof(uth) + sizeof(ups) *
 2872             (mp_maxid + 1)) + 1;
 2873         buffer = malloc(buflen, M_TEMP, M_WAITOK | M_ZERO);
 2874 
 2875         mtx_lock(&uma_mtx);
 2876         i = 0;
 2877         LIST_FOREACH(kz, &uma_kegs, uk_link) {
 2878                 LIST_FOREACH(z, &kz->uk_zones, uz_link)
 2879                         i++;
 2880         }
 2881         if (i > count) {
 2882                 free(buffer, M_TEMP);
 2883                 goto restart;
 2884         }
 2885         count =  i;
 2886 
 2887         sbuf_new(&sbuf, buffer, buflen, SBUF_FIXEDLEN);
 2888 
 2889         /*
 2890          * Insert stream header.
 2891          */
 2892         bzero(&ush, sizeof(ush));
 2893         ush.ush_version = UMA_STREAM_VERSION;
 2894         ush.ush_maxcpus = (mp_maxid + 1);
 2895         ush.ush_count = count;
 2896         if (sbuf_bcat(&sbuf, &ush, sizeof(ush)) < 0) {
 2897                 mtx_unlock(&uma_mtx);
 2898                 error = ENOMEM;
 2899                 goto out;
 2900         }
 2901 
 2902         LIST_FOREACH(kz, &uma_kegs, uk_link) {
 2903                 LIST_FOREACH(z, &kz->uk_zones, uz_link) {
 2904                         bzero(&uth, sizeof(uth));
 2905                         ZONE_LOCK(z);
 2906                         strlcpy(uth.uth_name, z->uz_name, UTH_MAX_NAME);
 2907                         uth.uth_align = kz->uk_align;
 2908                         uth.uth_pages = kz->uk_pages;
 2909                         uth.uth_keg_free = kz->uk_free;
 2910                         uth.uth_size = kz->uk_size;
 2911                         uth.uth_rsize = kz->uk_rsize;
 2912                         uth.uth_maxpages = kz->uk_maxpages;
 2913                         if (kz->uk_ppera > 1)
 2914                                 uth.uth_limit = kz->uk_maxpages /
 2915                                     kz->uk_ppera;
 2916                         else
 2917                                 uth.uth_limit = kz->uk_maxpages *
 2918                                     kz->uk_ipers;
 2919 
 2920                         /*
 2921                          * A zone is secondary is it is not the first entry
 2922                          * on the keg's zone list.
 2923                          */
 2924                         if ((kz->uk_flags & UMA_ZONE_SECONDARY) &&
 2925                             (LIST_FIRST(&kz->uk_zones) != z))
 2926                                 uth.uth_zone_flags = UTH_ZONE_SECONDARY;
 2927 
 2928                         LIST_FOREACH(bucket, &z->uz_full_bucket, ub_link)
 2929                                 uth.uth_zone_free += bucket->ub_cnt;
 2930                         uth.uth_allocs = z->uz_allocs;
 2931                         uth.uth_frees = z->uz_frees;
 2932                         uth.uth_fails = z->uz_fails;
 2933                         if (sbuf_bcat(&sbuf, &uth, sizeof(uth)) < 0) {
 2934                                 ZONE_UNLOCK(z);
 2935                                 mtx_unlock(&uma_mtx);
 2936                                 error = ENOMEM;
 2937                                 goto out;
 2938                         }
 2939                         /*
 2940                          * While it is not normally safe to access the cache
 2941                          * bucket pointers while not on the CPU that owns the
 2942                          * cache, we only allow the pointers to be exchanged
 2943                          * without the zone lock held, not invalidated, so
 2944                          * accept the possible race associated with bucket
 2945                          * exchange during monitoring.
 2946                          */
 2947                         for (i = 0; i < (mp_maxid + 1); i++) {
 2948                                 bzero(&ups, sizeof(ups));
 2949                                 if (kz->uk_flags & UMA_ZFLAG_INTERNAL)
 2950                                         goto skip;
 2951                                 if (CPU_ABSENT(i))
 2952                                         goto skip;
 2953                                 cache = &z->uz_cpu[i];
 2954                                 if (cache->uc_allocbucket != NULL)
 2955                                         ups.ups_cache_free +=
 2956                                             cache->uc_allocbucket->ub_cnt;
 2957                                 if (cache->uc_freebucket != NULL)
 2958                                         ups.ups_cache_free +=
 2959                                             cache->uc_freebucket->ub_cnt;
 2960                                 ups.ups_allocs = cache->uc_allocs;
 2961                                 ups.ups_frees = cache->uc_frees;
 2962 skip:
 2963                                 if (sbuf_bcat(&sbuf, &ups, sizeof(ups)) < 0) {
 2964                                         ZONE_UNLOCK(z);
 2965                                         mtx_unlock(&uma_mtx);
 2966                                         error = ENOMEM;
 2967                                         goto out;
 2968                                 }
 2969                         }
 2970                         ZONE_UNLOCK(z);
 2971                 }
 2972         }
 2973         mtx_unlock(&uma_mtx);
 2974         sbuf_finish(&sbuf);
 2975         error = SYSCTL_OUT(req, sbuf_data(&sbuf), sbuf_len(&sbuf));
 2976 out:
 2977         free(buffer, M_TEMP);
 2978         return (error);
 2979 }
 2980 
 2981 #ifdef DDB
 2982 DB_SHOW_COMMAND(uma, db_show_uma)
 2983 {
 2984         u_int64_t allocs, frees;
 2985         uma_bucket_t bucket;
 2986         uma_keg_t kz;
 2987         uma_zone_t z;
 2988         int cachefree;
 2989 
 2990         db_printf("%18s %8s %8s %8s %12s\n", "Zone", "Size", "Used", "Free",
 2991             "Requests");
 2992         LIST_FOREACH(kz, &uma_kegs, uk_link) {
 2993                 LIST_FOREACH(z, &kz->uk_zones, uz_link) {
 2994                         if (kz->uk_flags & UMA_ZFLAG_INTERNAL) {
 2995                                 allocs = z->uz_allocs;
 2996                                 frees = z->uz_frees;
 2997                                 cachefree = 0;
 2998                         } else
 2999                                 uma_zone_sumstat(z, &cachefree, &allocs,
 3000                                     &frees);
 3001                         if (!((kz->uk_flags & UMA_ZONE_SECONDARY) &&
 3002                             (LIST_FIRST(&kz->uk_zones) != z)))
 3003                                 cachefree += kz->uk_free;
 3004                         LIST_FOREACH(bucket, &z->uz_full_bucket, ub_link)
 3005                                 cachefree += bucket->ub_cnt;
 3006                         db_printf("%18s %8ju %8jd %8d %12ju\n", z->uz_name,
 3007                             (uintmax_t)kz->uk_size,
 3008                             (intmax_t)(allocs - frees), cachefree,
 3009                             (uintmax_t)allocs);
 3010                 }
 3011         }
 3012 }
 3013 #endif

Cache object: b5e72b81544facd96162fc58dc9ab05a


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.