usr/src/uts/common/os/kmem.c
author David Valin <David.Valin@Sun.COM>
Thu, 08 Apr 2010 07:11:19 -0700
changeset 12093 fa0c0f5bf466
parent 11178 d671c0911ce4
child 12681 2d92cdff89ce
permissions -rw-r--r--
6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     1
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     2
 * CDDL HEADER START
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     3
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
2208
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
     5
 * Common Development and Distribution License (the "License").
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
     6
 * You may not use this file except in compliance with the License.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     7
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    11
 * and limitations under the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    12
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    18
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    19
 * CDDL HEADER END
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    20
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    21
/*
12093
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
    22
 * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    23
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    24
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    25
/*
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    26
 * Kernel memory allocator, as described in the following two papers and a
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    27
 * statement about the consolidator:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
 * Jeff Bonwick,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    30
 * The Slab Allocator: An Object-Caching Kernel Memory Allocator.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    31
 * Proceedings of the Summer 1994 Usenix Conference.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
 * Available as /shared/sac/PSARC/1994/028/materials/kmem.pdf.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
 * Jeff Bonwick and Jonathan Adams,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
 * Magazines and vmem: Extending the Slab Allocator to Many CPUs and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
 * Arbitrary Resources.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
 * Proceedings of the 2001 Usenix Conference.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
 * Available as /shared/sac/PSARC/2000/550/materials/vmem.pdf.
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    39
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    40
 * kmem Slab Consolidator Big Theory Statement:
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    41
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    42
 * 1. Motivation
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    43
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    44
 * As stated in Bonwick94, slabs provide the following advantages over other
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    45
 * allocation structures in terms of memory fragmentation:
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    46
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    47
 *  - Internal fragmentation (per-buffer wasted space) is minimal.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    48
 *  - Severe external fragmentation (unused buffers on the free list) is
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    49
 *    unlikely.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    50
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    51
 * Segregating objects by size eliminates one source of external fragmentation,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    52
 * and according to Bonwick:
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    53
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    54
 *   The other reason that slabs reduce external fragmentation is that all
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    55
 *   objects in a slab are of the same type, so they have the same lifetime
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    56
 *   distribution. The resulting segregation of short-lived and long-lived
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    57
 *   objects at slab granularity reduces the likelihood of an entire page being
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    58
 *   held hostage due to a single long-lived allocation [Barrett93, Hanson90].
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    59
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    60
 * While unlikely, severe external fragmentation remains possible. Clients that
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    61
 * allocate both short- and long-lived objects from the same cache cannot
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    62
 * anticipate the distribution of long-lived objects within the allocator's slab
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    63
 * implementation. Even a small percentage of long-lived objects distributed
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    64
 * randomly across many slabs can lead to a worst case scenario where the client
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    65
 * frees the majority of its objects and the system gets back almost none of the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    66
 * slabs. Despite the client doing what it reasonably can to help the system
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    67
 * reclaim memory, the allocator cannot shake free enough slabs because of
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    68
 * lonely allocations stubbornly hanging on. Although the allocator is in a
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    69
 * position to diagnose the fragmentation, there is nothing that the allocator
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    70
 * by itself can do about it. It only takes a single allocated object to prevent
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    71
 * an entire slab from being reclaimed, and any object handed out by
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    72
 * kmem_cache_alloc() is by definition in the client's control. Conversely,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    73
 * although the client is in a position to move a long-lived object, it has no
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    74
 * way of knowing if the object is causing fragmentation, and if so, where to
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    75
 * move it. A solution necessarily requires further cooperation between the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    76
 * allocator and the client.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    77
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    78
 * 2. Move Callback
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    79
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    80
 * The kmem slab consolidator therefore adds a move callback to the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    81
 * allocator/client interface, improving worst-case external fragmentation in
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    82
 * kmem caches that supply a function to move objects from one memory location
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    83
 * to another. In a situation of low memory kmem attempts to consolidate all of
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    84
 * a cache's slabs at once; otherwise it works slowly to bring external
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    85
 * fragmentation within the 1/8 limit guaranteed for internal fragmentation,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    86
 * thereby helping to avoid a low memory situation in the future.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    87
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    88
 * The callback has the following signature:
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    89
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    90
 *   kmem_cbrc_t move(void *old, void *new, size_t size, void *user_arg)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    91
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    92
 * It supplies the kmem client with two addresses: the allocated object that
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    93
 * kmem wants to move and a buffer selected by kmem for the client to use as the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    94
 * copy destination. The callback is kmem's way of saying "Please get off of
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    95
 * this buffer and use this one instead." kmem knows where it wants to move the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    96
 * object in order to best reduce fragmentation. All the client needs to know
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    97
 * about the second argument (void *new) is that it is an allocated, constructed
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    98
 * object ready to take the contents of the old object. When the move function
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
    99
 * is called, the system is likely to be low on memory, and the new object
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   100
 * spares the client from having to worry about allocating memory for the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   101
 * requested move. The third argument supplies the size of the object, in case a
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   102
 * single move function handles multiple caches whose objects differ only in
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   103
 * size (such as zio_buf_512, zio_buf_1024, etc). Finally, the same optional
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   104
 * user argument passed to the constructor, destructor, and reclaim functions is
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   105
 * also passed to the move callback.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   106
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   107
 * 2.1 Setting the Move Callback
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   108
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   109
 * The client sets the move callback after creating the cache and before
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   110
 * allocating from it:
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   111
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   112
 *	object_cache = kmem_cache_create(...);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   113
 *      kmem_cache_set_move(object_cache, object_move);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   114
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   115
 * 2.2 Move Callback Return Values
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   116
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   117
 * Only the client knows about its own data and when is a good time to move it.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   118
 * The client is cooperating with kmem to return unused memory to the system,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   119
 * and kmem respectfully accepts this help at the client's convenience. When
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   120
 * asked to move an object, the client can respond with any of the following:
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   121
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   122
 *   typedef enum kmem_cbrc {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   123
 *           KMEM_CBRC_YES,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   124
 *           KMEM_CBRC_NO,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   125
 *           KMEM_CBRC_LATER,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   126
 *           KMEM_CBRC_DONT_NEED,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   127
 *           KMEM_CBRC_DONT_KNOW
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   128
 *   } kmem_cbrc_t;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   129
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   130
 * The client must not explicitly kmem_cache_free() either of the objects passed
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   131
 * to the callback, since kmem wants to free them directly to the slab layer
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   132
 * (bypassing the per-CPU magazine layer). The response tells kmem which of the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   133
 * objects to free:
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   134
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   135
 *       YES: (Did it) The client moved the object, so kmem frees the old one.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   136
 *        NO: (Never) The client refused, so kmem frees the new object (the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   137
 *            unused copy destination). kmem also marks the slab of the old
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   138
 *            object so as not to bother the client with further callbacks for
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   139
 *            that object as long as the slab remains on the partial slab list.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   140
 *            (The system won't be getting the slab back as long as the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   141
 *            immovable object holds it hostage, so there's no point in moving
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   142
 *            any of its objects.)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   143
 *     LATER: The client is using the object and cannot move it now, so kmem
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   144
 *            frees the new object (the unused copy destination). kmem still
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   145
 *            attempts to move other objects off the slab, since it expects to
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   146
 *            succeed in clearing the slab in a later callback. The client
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   147
 *            should use LATER instead of NO if the object is likely to become
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   148
 *            movable very soon.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   149
 * DONT_NEED: The client no longer needs the object, so kmem frees the old along
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   150
 *            with the new object (the unused copy destination). This response
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   151
 *            is the client's opportunity to be a model citizen and give back as
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   152
 *            much as it can.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   153
 * DONT_KNOW: The client does not know about the object because
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   154
 *            a) the client has just allocated the object and not yet put it
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   155
 *               wherever it expects to find known objects
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   156
 *            b) the client has removed the object from wherever it expects to
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   157
 *               find known objects and is about to free it, or
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   158
 *            c) the client has freed the object.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   159
 *            In all these cases (a, b, and c) kmem frees the new object (the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   160
 *            unused copy destination) and searches for the old object in the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   161
 *            magazine layer. If found, the object is removed from the magazine
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   162
 *            layer and freed to the slab layer so it will no longer hold the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   163
 *            slab hostage.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   164
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   165
 * 2.3 Object States
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   166
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   167
 * Neither kmem nor the client can be assumed to know the object's whereabouts
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   168
 * at the time of the callback. An object belonging to a kmem cache may be in
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   169
 * any of the following states:
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   170
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   171
 * 1. Uninitialized on the slab
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   172
 * 2. Allocated from the slab but not constructed (still uninitialized)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   173
 * 3. Allocated from the slab, constructed, but not yet ready for business
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   174
 *    (not in a valid state for the move callback)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   175
 * 4. In use (valid and known to the client)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   176
 * 5. About to be freed (no longer in a valid state for the move callback)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   177
 * 6. Freed to a magazine (still constructed)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   178
 * 7. Allocated from a magazine, not yet ready for business (not in a valid
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   179
 *    state for the move callback), and about to return to state #4
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   180
 * 8. Deconstructed on a magazine that is about to be freed
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   181
 * 9. Freed to the slab
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   182
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   183
 * Since the move callback may be called at any time while the object is in any
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   184
 * of the above states (except state #1), the client needs a safe way to
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   185
 * determine whether or not it knows about the object. Specifically, the client
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   186
 * needs to know whether or not the object is in state #4, the only state in
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   187
 * which a move is valid. If the object is in any other state, the client should
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   188
 * immediately return KMEM_CBRC_DONT_KNOW, since it is unsafe to access any of
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   189
 * the object's fields.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   190
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   191
 * Note that although an object may be in state #4 when kmem initiates the move
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   192
 * request, the object may no longer be in that state by the time kmem actually
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   193
 * calls the move function. Not only does the client free objects
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   194
 * asynchronously, kmem itself puts move requests on a queue where thay are
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   195
 * pending until kmem processes them from another context. Also, objects freed
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   196
 * to a magazine appear allocated from the point of view of the slab layer, so
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   197
 * kmem may even initiate requests for objects in a state other than state #4.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   198
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   199
 * 2.3.1 Magazine Layer
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   200
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   201
 * An important insight revealed by the states listed above is that the magazine
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   202
 * layer is populated only by kmem_cache_free(). Magazines of constructed
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   203
 * objects are never populated directly from the slab layer (which contains raw,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   204
 * unconstructed objects). Whenever an allocation request cannot be satisfied
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   205
 * from the magazine layer, the magazines are bypassed and the request is
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   206
 * satisfied from the slab layer (creating a new slab if necessary). kmem calls
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   207
 * the object constructor only when allocating from the slab layer, and only in
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   208
 * response to kmem_cache_alloc() or to prepare the destination buffer passed in
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   209
 * the move callback. kmem does not preconstruct objects in anticipation of
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   210
 * kmem_cache_alloc().
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   211
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   212
 * 2.3.2 Object Constructor and Destructor
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   213
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   214
 * If the client supplies a destructor, it must be valid to call the destructor
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   215
 * on a newly created object (immediately after the constructor).
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   216
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   217
 * 2.4 Recognizing Known Objects
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   218
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   219
 * There is a simple test to determine safely whether or not the client knows
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   220
 * about a given object in the move callback. It relies on the fact that kmem
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   221
 * guarantees that the object of the move callback has only been touched by the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   222
 * client itself or else by kmem. kmem does this by ensuring that none of the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   223
 * cache's slabs are freed to the virtual memory (VM) subsystem while a move
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   224
 * callback is pending. When the last object on a slab is freed, if there is a
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   225
 * pending move, kmem puts the slab on a per-cache dead list and defers freeing
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   226
 * slabs on that list until all pending callbacks are completed. That way,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   227
 * clients can be certain that the object of a move callback is in one of the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   228
 * states listed above, making it possible to distinguish known objects (in
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   229
 * state #4) using the two low order bits of any pointer member (with the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   230
 * exception of 'char *' or 'short *' which may not be 4-byte aligned on some
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   231
 * platforms).
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   232
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   233
 * The test works as long as the client always transitions objects from state #4
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   234
 * (known, in use) to state #5 (about to be freed, invalid) by setting the low
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   235
 * order bit of the client-designated pointer member. Since kmem only writes
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   236
 * invalid memory patterns, such as 0xbaddcafe to uninitialized memory and
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   237
 * 0xdeadbeef to freed memory, any scribbling on the object done by kmem is
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   238
 * guaranteed to set at least one of the two low order bits. Therefore, given an
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   239
 * object with a back pointer to a 'container_t *o_container', the client can
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   240
 * test
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   241
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   242
 *      container_t *container = object->o_container;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   243
 *      if ((uintptr_t)container & 0x3) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   244
 *              return (KMEM_CBRC_DONT_KNOW);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   245
 *      }
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   246
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   247
 * Typically, an object will have a pointer to some structure with a list or
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   248
 * hash where objects from the cache are kept while in use. Assuming that the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   249
 * client has some way of knowing that the container structure is valid and will
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   250
 * not go away during the move, and assuming that the structure includes a lock
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   251
 * to protect whatever collection is used, then the client would continue as
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   252
 * follows:
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   253
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   254
 *	// Ensure that the container structure does not go away.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   255
 *      if (container_hold(container) == 0) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   256
 *              return (KMEM_CBRC_DONT_KNOW);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   257
 *      }
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   258
 *      mutex_enter(&container->c_objects_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   259
 *      if (container != object->o_container) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   260
 *              mutex_exit(&container->c_objects_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   261
 *              container_rele(container);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   262
 *              return (KMEM_CBRC_DONT_KNOW);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   263
 *      }
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   264
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   265
 * At this point the client knows that the object cannot be freed as long as
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   266
 * c_objects_lock is held. Note that after acquiring the lock, the client must
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   267
 * recheck the o_container pointer in case the object was removed just before
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   268
 * acquiring the lock.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   269
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   270
 * When the client is about to free an object, it must first remove that object
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   271
 * from the list, hash, or other structure where it is kept. At that time, to
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   272
 * mark the object so it can be distinguished from the remaining, known objects,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   273
 * the client sets the designated low order bit:
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   274
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   275
 *      mutex_enter(&container->c_objects_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   276
 *      object->o_container = (void *)((uintptr_t)object->o_container | 0x1);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   277
 *      list_remove(&container->c_objects, object);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   278
 *      mutex_exit(&container->c_objects_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   279
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   280
 * In the common case, the object is freed to the magazine layer, where it may
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   281
 * be reused on a subsequent allocation without the overhead of calling the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   282
 * constructor. While in the magazine it appears allocated from the point of
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   283
 * view of the slab layer, making it a candidate for the move callback. Most
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   284
 * objects unrecognized by the client in the move callback fall into this
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   285
 * category and are cheaply distinguished from known objects by the test
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   286
 * described earlier. Since recognition is cheap for the client, and searching
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   287
 * magazines is expensive for kmem, kmem defers searching until the client first
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   288
 * returns KMEM_CBRC_DONT_KNOW. As long as the needed effort is reasonable, kmem
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   289
 * elsewhere does what it can to avoid bothering the client unnecessarily.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   290
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   291
 * Invalidating the designated pointer member before freeing the object marks
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   292
 * the object to be avoided in the callback, and conversely, assigning a valid
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   293
 * value to the designated pointer member after allocating the object makes the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   294
 * object fair game for the callback:
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   295
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   296
 *      ... allocate object ...
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   297
 *      ... set any initial state not set by the constructor ...
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   298
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   299
 *      mutex_enter(&container->c_objects_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   300
 *      list_insert_tail(&container->c_objects, object);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   301
 *      membar_producer();
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   302
 *      object->o_container = container;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   303
 *      mutex_exit(&container->c_objects_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   304
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   305
 * Note that everything else must be valid before setting o_container makes the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   306
 * object fair game for the move callback. The membar_producer() call ensures
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   307
 * that all the object's state is written to memory before setting the pointer
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   308
 * that transitions the object from state #3 or #7 (allocated, constructed, not
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   309
 * yet in use) to state #4 (in use, valid). That's important because the move
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   310
 * function has to check the validity of the pointer before it can safely
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   311
 * acquire the lock protecting the collection where it expects to find known
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   312
 * objects.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   313
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   314
 * This method of distinguishing known objects observes the usual symmetry:
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   315
 * invalidating the designated pointer is the first thing the client does before
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   316
 * freeing the object, and setting the designated pointer is the last thing the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   317
 * client does after allocating the object. Of course, the client is not
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   318
 * required to use this method. Fundamentally, how the client recognizes known
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   319
 * objects is completely up to the client, but this method is recommended as an
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   320
 * efficient and safe way to take advantage of the guarantees made by kmem. If
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   321
 * the entire object is arbitrary data without any markable bits from a suitable
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   322
 * pointer member, then the client must find some other method, such as
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   323
 * searching a hash table of known objects.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   324
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   325
 * 2.5 Preventing Objects From Moving
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   326
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   327
 * Besides a way to distinguish known objects, the other thing that the client
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   328
 * needs is a strategy to ensure that an object will not move while the client
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   329
 * is actively using it. The details of satisfying this requirement tend to be
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   330
 * highly cache-specific. It might seem that the same rules that let a client
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   331
 * remove an object safely should also decide when an object can be moved
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   332
 * safely. However, any object state that makes a removal attempt invalid is
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   333
 * likely to be long-lasting for objects that the client does not expect to
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   334
 * remove. kmem knows nothing about the object state and is equally likely (from
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   335
 * the client's point of view) to request a move for any object in the cache,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   336
 * whether prepared for removal or not. Even a low percentage of objects stuck
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   337
 * in place by unremovability will defeat the consolidator if the stuck objects
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   338
 * are the same long-lived allocations likely to hold slabs hostage.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   339
 * Fundamentally, the consolidator is not aimed at common cases. Severe external
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   340
 * fragmentation is a worst case scenario manifested as sparsely allocated
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   341
 * slabs, by definition a low percentage of the cache's objects. When deciding
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   342
 * what makes an object movable, keep in mind the goal of the consolidator: to
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   343
 * bring worst-case external fragmentation within the limits guaranteed for
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   344
 * internal fragmentation. Removability is a poor criterion if it is likely to
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   345
 * exclude more than an insignificant percentage of objects for long periods of
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   346
 * time.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   347
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   348
 * A tricky general solution exists, and it has the advantage of letting you
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   349
 * move any object at almost any moment, practically eliminating the likelihood
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   350
 * that an object can hold a slab hostage. However, if there is a cache-specific
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   351
 * way to ensure that an object is not actively in use in the vast majority of
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   352
 * cases, a simpler solution that leverages this cache-specific knowledge is
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   353
 * preferred.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   354
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   355
 * 2.5.1 Cache-Specific Solution
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   356
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   357
 * As an example of a cache-specific solution, the ZFS znode cache takes
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   358
 * advantage of the fact that the vast majority of znodes are only being
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   359
 * referenced from the DNLC. (A typical case might be a few hundred in active
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   360
 * use and a hundred thousand in the DNLC.) In the move callback, after the ZFS
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   361
 * client has established that it recognizes the znode and can access its fields
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   362
 * safely (using the method described earlier), it then tests whether the znode
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   363
 * is referenced by anything other than the DNLC. If so, it assumes that the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   364
 * znode may be in active use and is unsafe to move, so it drops its locks and
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   365
 * returns KMEM_CBRC_LATER. The advantage of this strategy is that everywhere
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   366
 * else znodes are used, no change is needed to protect against the possibility
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   367
 * of the znode moving. The disadvantage is that it remains possible for an
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   368
 * application to hold a znode slab hostage with an open file descriptor.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   369
 * However, this case ought to be rare and the consolidator has a way to deal
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   370
 * with it: If the client responds KMEM_CBRC_LATER repeatedly for the same
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   371
 * object, kmem eventually stops believing it and treats the slab as if the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   372
 * client had responded KMEM_CBRC_NO. Having marked the hostage slab, kmem can
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   373
 * then focus on getting it off of the partial slab list by allocating rather
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   374
 * than freeing all of its objects. (Either way of getting a slab off the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   375
 * free list reduces fragmentation.)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   376
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   377
 * 2.5.2 General Solution
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   378
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   379
 * The general solution, on the other hand, requires an explicit hold everywhere
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   380
 * the object is used to prevent it from moving. To keep the client locking
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   381
 * strategy as uncomplicated as possible, kmem guarantees the simplifying
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   382
 * assumption that move callbacks are sequential, even across multiple caches.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   383
 * Internally, a global queue processed by a single thread supports all caches
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   384
 * implementing the callback function. No matter how many caches supply a move
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   385
 * function, the consolidator never moves more than one object at a time, so the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   386
 * client does not have to worry about tricky lock ordering involving several
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   387
 * related objects from different kmem caches.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   388
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   389
 * The general solution implements the explicit hold as a read-write lock, which
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   390
 * allows multiple readers to access an object from the cache simultaneously
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   391
 * while a single writer is excluded from moving it. A single rwlock for the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   392
 * entire cache would lock out all threads from using any of the cache's objects
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   393
 * even though only a single object is being moved, so to reduce contention,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   394
 * the client can fan out the single rwlock into an array of rwlocks hashed by
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   395
 * the object address, making it probable that moving one object will not
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   396
 * prevent other threads from using a different object. The rwlock cannot be a
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   397
 * member of the object itself, because the possibility of the object moving
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   398
 * makes it unsafe to access any of the object's fields until the lock is
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   399
 * acquired.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   400
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   401
 * Assuming a small, fixed number of locks, it's possible that multiple objects
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   402
 * will hash to the same lock. A thread that needs to use multiple objects in
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   403
 * the same function may acquire the same lock multiple times. Since rwlocks are
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   404
 * reentrant for readers, and since there is never more than a single writer at
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   405
 * a time (assuming that the client acquires the lock as a writer only when
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   406
 * moving an object inside the callback), there would seem to be no problem.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   407
 * However, a client locking multiple objects in the same function must handle
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   408
 * one case of potential deadlock: Assume that thread A needs to prevent both
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   409
 * object 1 and object 2 from moving, and thread B, the callback, meanwhile
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   410
 * tries to move object 3. It's possible, if objects 1, 2, and 3 all hash to the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   411
 * same lock, that thread A will acquire the lock for object 1 as a reader
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   412
 * before thread B sets the lock's write-wanted bit, preventing thread A from
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   413
 * reacquiring the lock for object 2 as a reader. Unable to make forward
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   414
 * progress, thread A will never release the lock for object 1, resulting in
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   415
 * deadlock.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   416
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   417
 * There are two ways of avoiding the deadlock just described. The first is to
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   418
 * use rw_tryenter() rather than rw_enter() in the callback function when
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   419
 * attempting to acquire the lock as a writer. If tryenter discovers that the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   420
 * same object (or another object hashed to the same lock) is already in use, it
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   421
 * aborts the callback and returns KMEM_CBRC_LATER. The second way is to use
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   422
 * rprwlock_t (declared in common/fs/zfs/sys/rprwlock.h) instead of rwlock_t,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   423
 * since it allows a thread to acquire the lock as a reader in spite of a
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   424
 * waiting writer. This second approach insists on moving the object now, no
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   425
 * matter how many readers the move function must wait for in order to do so,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   426
 * and could delay the completion of the callback indefinitely (blocking
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   427
 * callbacks to other clients). In practice, a less insistent callback using
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   428
 * rw_tryenter() returns KMEM_CBRC_LATER infrequently enough that there seems
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   429
 * little reason to use anything else.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   430
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   431
 * Avoiding deadlock is not the only problem that an implementation using an
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   432
 * explicit hold needs to solve. Locking the object in the first place (to
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   433
 * prevent it from moving) remains a problem, since the object could move
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   434
 * between the time you obtain a pointer to the object and the time you acquire
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   435
 * the rwlock hashed to that pointer value. Therefore the client needs to
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   436
 * recheck the value of the pointer after acquiring the lock, drop the lock if
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   437
 * the value has changed, and try again. This requires a level of indirection:
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   438
 * something that points to the object rather than the object itself, that the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   439
 * client can access safely while attempting to acquire the lock. (The object
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   440
 * itself cannot be referenced safely because it can move at any time.)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   441
 * The following lock-acquisition function takes whatever is safe to reference
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   442
 * (arg), follows its pointer to the object (using function f), and tries as
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   443
 * often as necessary to acquire the hashed lock and verify that the object
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   444
 * still has not moved:
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   445
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   446
 *      object_t *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   447
 *      object_hold(object_f f, void *arg)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   448
 *      {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   449
 *              object_t *op;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   450
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   451
 *              op = f(arg);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   452
 *              if (op == NULL) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   453
 *                      return (NULL);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   454
 *              }
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   455
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   456
 *              rw_enter(OBJECT_RWLOCK(op), RW_READER);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   457
 *              while (op != f(arg)) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   458
 *                      rw_exit(OBJECT_RWLOCK(op));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   459
 *                      op = f(arg);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   460
 *                      if (op == NULL) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   461
 *                              break;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   462
 *                      }
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   463
 *                      rw_enter(OBJECT_RWLOCK(op), RW_READER);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   464
 *              }
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   465
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   466
 *              return (op);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   467
 *      }
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   468
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   469
 * The OBJECT_RWLOCK macro hashes the object address to obtain the rwlock. The
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   470
 * lock reacquisition loop, while necessary, almost never executes. The function
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   471
 * pointer f (used to obtain the object pointer from arg) has the following type
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   472
 * definition:
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   473
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   474
 *      typedef object_t *(*object_f)(void *arg);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   475
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   476
 * An object_f implementation is likely to be as simple as accessing a structure
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   477
 * member:
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   478
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   479
 *      object_t *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   480
 *      s_object(void *arg)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   481
 *      {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   482
 *              something_t *sp = arg;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   483
 *              return (sp->s_object);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   484
 *      }
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   485
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   486
 * The flexibility of a function pointer allows the path to the object to be
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   487
 * arbitrarily complex and also supports the notion that depending on where you
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   488
 * are using the object, you may need to get it from someplace different.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   489
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   490
 * The function that releases the explicit hold is simpler because it does not
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   491
 * have to worry about the object moving:
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   492
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   493
 *      void
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   494
 *      object_rele(object_t *op)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   495
 *      {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   496
 *              rw_exit(OBJECT_RWLOCK(op));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   497
 *      }
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   498
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   499
 * The caller is spared these details so that obtaining and releasing an
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   500
 * explicit hold feels like a simple mutex_enter()/mutex_exit() pair. The caller
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   501
 * of object_hold() only needs to know that the returned object pointer is valid
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   502
 * if not NULL and that the object will not move until released.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   503
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   504
 * Although object_hold() prevents an object from moving, it does not prevent it
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   505
 * from being freed. The caller must take measures before calling object_hold()
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   506
 * (afterwards is too late) to ensure that the held object cannot be freed. The
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   507
 * caller must do so without accessing the unsafe object reference, so any lock
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   508
 * or reference count used to ensure the continued existence of the object must
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   509
 * live outside the object itself.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   510
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   511
 * Obtaining a new object is a special case where an explicit hold is impossible
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   512
 * for the caller. Any function that returns a newly allocated object (either as
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   513
 * a return value, or as an in-out paramter) must return it already held; after
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   514
 * the caller gets it is too late, since the object cannot be safely accessed
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   515
 * without the level of indirection described earlier. The following
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   516
 * object_alloc() example uses the same code shown earlier to transition a new
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   517
 * object into the state of being recognized (by the client) as a known object.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   518
 * The function must acquire the hold (rw_enter) before that state transition
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   519
 * makes the object movable:
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   520
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   521
 *      static object_t *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   522
 *      object_alloc(container_t *container)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   523
 *      {
7546
b7eb4c89d3a0 6738434 kmem_check_destructor() introduces binary compatibility issue
Tom Erickson <tomee@eng.sun.com>
parents: 6908
diff changeset
   524
 *              object_t *object = kmem_cache_alloc(object_cache, 0);
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   525
 *              ... set any initial state not set by the constructor ...
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   526
 *              rw_enter(OBJECT_RWLOCK(object), RW_READER);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   527
 *              mutex_enter(&container->c_objects_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   528
 *              list_insert_tail(&container->c_objects, object);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   529
 *              membar_producer();
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   530
 *              object->o_container = container;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   531
 *              mutex_exit(&container->c_objects_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   532
 *              return (object);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   533
 *      }
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   534
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   535
 * Functions that implicitly acquire an object hold (any function that calls
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   536
 * object_alloc() to supply an object for the caller) need to be carefully noted
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   537
 * so that the matching object_rele() is not neglected. Otherwise, leaked holds
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   538
 * prevent all objects hashed to the affected rwlocks from ever being moved.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   539
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   540
 * The pointer to a held object can be hashed to the holding rwlock even after
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   541
 * the object has been freed. Although it is possible to release the hold
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   542
 * after freeing the object, you may decide to release the hold implicitly in
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   543
 * whatever function frees the object, so as to release the hold as soon as
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   544
 * possible, and for the sake of symmetry with the function that implicitly
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   545
 * acquires the hold when it allocates the object. Here, object_free() releases
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   546
 * the hold acquired by object_alloc(). Its implicit object_rele() forms a
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   547
 * matching pair with object_hold():
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   548
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   549
 *      void
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   550
 *      object_free(object_t *object)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   551
 *      {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   552
 *              container_t *container;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   553
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   554
 *              ASSERT(object_held(object));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   555
 *              container = object->o_container;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   556
 *              mutex_enter(&container->c_objects_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   557
 *              object->o_container =
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   558
 *                  (void *)((uintptr_t)object->o_container | 0x1);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   559
 *              list_remove(&container->c_objects, object);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   560
 *              mutex_exit(&container->c_objects_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   561
 *              object_rele(object);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   562
 *              kmem_cache_free(object_cache, object);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   563
 *      }
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   564
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   565
 * Note that object_free() cannot safely accept an object pointer as an argument
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   566
 * unless the object is already held. Any function that calls object_free()
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   567
 * needs to be carefully noted since it similarly forms a matching pair with
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   568
 * object_hold().
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   569
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   570
 * To complete the picture, the following callback function implements the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   571
 * general solution by moving objects only if they are currently unheld:
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   572
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   573
 *      static kmem_cbrc_t
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   574
 *      object_move(void *buf, void *newbuf, size_t size, void *arg)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   575
 *      {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   576
 *              object_t *op = buf, *np = newbuf;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   577
 *              container_t *container;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   578
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   579
 *              container = op->o_container;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   580
 *              if ((uintptr_t)container & 0x3) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   581
 *                      return (KMEM_CBRC_DONT_KNOW);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   582
 *              }
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   583
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   584
 *	        // Ensure that the container structure does not go away.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   585
 *              if (container_hold(container) == 0) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   586
 *                      return (KMEM_CBRC_DONT_KNOW);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   587
 *              }
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   588
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   589
 *              mutex_enter(&container->c_objects_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   590
 *              if (container != op->o_container) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   591
 *                      mutex_exit(&container->c_objects_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   592
 *                      container_rele(container);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   593
 *                      return (KMEM_CBRC_DONT_KNOW);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   594
 *              }
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   595
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   596
 *              if (rw_tryenter(OBJECT_RWLOCK(op), RW_WRITER) == 0) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   597
 *                      mutex_exit(&container->c_objects_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   598
 *                      container_rele(container);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   599
 *                      return (KMEM_CBRC_LATER);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   600
 *              }
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   601
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   602
 *              object_move_impl(op, np); // critical section
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   603
 *              rw_exit(OBJECT_RWLOCK(op));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   604
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   605
 *              op->o_container = (void *)((uintptr_t)op->o_container | 0x1);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   606
 *              list_link_replace(&op->o_link_node, &np->o_link_node);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   607
 *              mutex_exit(&container->c_objects_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   608
 *              container_rele(container);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   609
 *              return (KMEM_CBRC_YES);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   610
 *      }
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   611
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   612
 * Note that object_move() must invalidate the designated o_container pointer of
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   613
 * the old object in the same way that object_free() does, since kmem will free
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   614
 * the object in response to the KMEM_CBRC_YES return value.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   615
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   616
 * The lock order in object_move() differs from object_alloc(), which locks
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   617
 * OBJECT_RWLOCK first and &container->c_objects_lock second, but as long as the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   618
 * callback uses rw_tryenter() (preventing the deadlock described earlier), it's
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   619
 * not a problem. Holding the lock on the object list in the example above
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   620
 * through the entire callback not only prevents the object from going away, it
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   621
 * also allows you to lock the list elsewhere and know that none of its elements
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   622
 * will move during iteration.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   623
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   624
 * Adding an explicit hold everywhere an object from the cache is used is tricky
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   625
 * and involves much more change to client code than a cache-specific solution
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   626
 * that leverages existing state to decide whether or not an object is
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   627
 * movable. However, this approach has the advantage that no object remains
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   628
 * immovable for any significant length of time, making it extremely unlikely
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   629
 * that long-lived allocations can continue holding slabs hostage; and it works
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   630
 * for any cache.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   631
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   632
 * 3. Consolidator Implementation
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   633
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   634
 * Once the client supplies a move function that a) recognizes known objects and
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   635
 * b) avoids moving objects that are actively in use, the remaining work is up
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   636
 * to the consolidator to decide which objects to move and when to issue
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   637
 * callbacks.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   638
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   639
 * The consolidator relies on the fact that a cache's slabs are ordered by
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   640
 * usage. Each slab has a fixed number of objects. Depending on the slab's
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   641
 * "color" (the offset of the first object from the beginning of the slab;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   642
 * offsets are staggered to mitigate false sharing of cache lines) it is either
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   643
 * the maximum number of objects per slab determined at cache creation time or
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   644
 * else the number closest to the maximum that fits within the space remaining
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   645
 * after the initial offset. A completely allocated slab may contribute some
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   646
 * internal fragmentation (per-slab overhead) but no external fragmentation, so
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   647
 * it is of no interest to the consolidator. At the other extreme, slabs whose
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   648
 * objects have all been freed to the slab are released to the virtual memory
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   649
 * (VM) subsystem (objects freed to magazines are still allocated as far as the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   650
 * slab is concerned). External fragmentation exists when there are slabs
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   651
 * somewhere between these extremes. A partial slab has at least one but not all
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   652
 * of its objects allocated. The more partial slabs, and the fewer allocated
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   653
 * objects on each of them, the higher the fragmentation. Hence the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   654
 * consolidator's overall strategy is to reduce the number of partial slabs by
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   655
 * moving allocated objects from the least allocated slabs to the most allocated
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   656
 * slabs.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   657
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   658
 * Partial slabs are kept in an AVL tree ordered by usage. Completely allocated
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   659
 * slabs are kept separately in an unordered list. Since the majority of slabs
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   660
 * tend to be completely allocated (a typical unfragmented cache may have
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   661
 * thousands of complete slabs and only a single partial slab), separating
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   662
 * complete slabs improves the efficiency of partial slab ordering, since the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   663
 * complete slabs do not affect the depth or balance of the AVL tree. This
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   664
 * ordered sequence of partial slabs acts as a "free list" supplying objects for
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   665
 * allocation requests.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   666
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   667
 * Objects are always allocated from the first partial slab in the free list,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   668
 * where the allocation is most likely to eliminate a partial slab (by
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   669
 * completely allocating it). Conversely, when a single object from a completely
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   670
 * allocated slab is freed to the slab, that slab is added to the front of the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   671
 * free list. Since most free list activity involves highly allocated slabs
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   672
 * coming and going at the front of the list, slabs tend naturally toward the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   673
 * ideal order: highly allocated at the front, sparsely allocated at the back.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   674
 * Slabs with few allocated objects are likely to become completely free if they
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   675
 * keep a safe distance away from the front of the free list. Slab misorders
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   676
 * interfere with the natural tendency of slabs to become completely free or
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   677
 * completely allocated. For example, a slab with a single allocated object
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   678
 * needs only a single free to escape the cache; its natural desire is
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   679
 * frustrated when it finds itself at the front of the list where a second
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   680
 * allocation happens just before the free could have released it. Another slab
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   681
 * with all but one object allocated might have supplied the buffer instead, so
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   682
 * that both (as opposed to neither) of the slabs would have been taken off the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   683
 * free list.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   684
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   685
 * Although slabs tend naturally toward the ideal order, misorders allowed by a
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   686
 * simple list implementation defeat the consolidator's strategy of merging
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   687
 * least- and most-allocated slabs. Without an AVL tree to guarantee order, kmem
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   688
 * needs another way to fix misorders to optimize its callback strategy. One
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   689
 * approach is to periodically scan a limited number of slabs, advancing a
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   690
 * marker to hold the current scan position, and to move extreme misorders to
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   691
 * the front or back of the free list and to the front or back of the current
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   692
 * scan range. By making consecutive scan ranges overlap by one slab, the least
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   693
 * allocated slab in the current range can be carried along from the end of one
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   694
 * scan to the start of the next.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   695
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   696
 * Maintaining partial slabs in an AVL tree relieves kmem of this additional
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   697
 * task, however. Since most of the cache's activity is in the magazine layer,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   698
 * and allocations from the slab layer represent only a startup cost, the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   699
 * overhead of maintaining a balanced tree is not a significant concern compared
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   700
 * to the opportunity of reducing complexity by eliminating the partial slab
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   701
 * scanner just described. The overhead of an AVL tree is minimized by
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   702
 * maintaining only partial slabs in the tree and keeping completely allocated
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   703
 * slabs separately in a list. To avoid increasing the size of the slab
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   704
 * structure the AVL linkage pointers are reused for the slab's list linkage,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   705
 * since the slab will always be either partial or complete, never stored both
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   706
 * ways at the same time. To further minimize the overhead of the AVL tree the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   707
 * compare function that orders partial slabs by usage divides the range of
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   708
 * allocated object counts into bins such that counts within the same bin are
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   709
 * considered equal. Binning partial slabs makes it less likely that allocating
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   710
 * or freeing a single object will change the slab's order, requiring a tree
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   711
 * reinsertion (an avl_remove() followed by an avl_add(), both potentially
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   712
 * requiring some rebalancing of the tree). Allocation counts closest to
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   713
 * completely free and completely allocated are left unbinned (finely sorted) to
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   714
 * better support the consolidator's strategy of merging slabs at either
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   715
 * extreme.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   716
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   717
 * 3.1 Assessing Fragmentation and Selecting Candidate Slabs
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   718
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   719
 * The consolidator piggybacks on the kmem maintenance thread and is called on
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   720
 * the same interval as kmem_cache_update(), once per cache every fifteen
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   721
 * seconds. kmem maintains a running count of unallocated objects in the slab
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   722
 * layer (cache_bufslab). The consolidator checks whether that number exceeds
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   723
 * 12.5% (1/8) of the total objects in the cache (cache_buftotal), and whether
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   724
 * there is a significant number of slabs in the cache (arbitrarily a minimum
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   725
 * 101 total slabs). Unused objects that have fallen out of the magazine layer's
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   726
 * working set are included in the assessment, and magazines in the depot are
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   727
 * reaped if those objects would lift cache_bufslab above the fragmentation
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   728
 * threshold. Once the consolidator decides that a cache is fragmented, it looks
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   729
 * for a candidate slab to reclaim, starting at the end of the partial slab free
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   730
 * list and scanning backwards. At first the consolidator is choosy: only a slab
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   731
 * with fewer than 12.5% (1/8) of its objects allocated qualifies (or else a
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   732
 * single allocated object, regardless of percentage). If there is difficulty
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   733
 * finding a candidate slab, kmem raises the allocation threshold incrementally,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   734
 * up to a maximum 87.5% (7/8), so that eventually the consolidator will reduce
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   735
 * external fragmentation (unused objects on the free list) below 12.5% (1/8),
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   736
 * even in the worst case of every slab in the cache being almost 7/8 allocated.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   737
 * The threshold can also be lowered incrementally when candidate slabs are easy
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   738
 * to find, and the threshold is reset to the minimum 1/8 as soon as the cache
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   739
 * is no longer fragmented.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   740
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   741
 * 3.2 Generating Callbacks
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   742
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   743
 * Once an eligible slab is chosen, a callback is generated for every allocated
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   744
 * object on the slab, in the hope that the client will move everything off the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   745
 * slab and make it reclaimable. Objects selected as move destinations are
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   746
 * chosen from slabs at the front of the free list. Assuming slabs in the ideal
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   747
 * order (most allocated at the front, least allocated at the back) and a
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   748
 * cooperative client, the consolidator will succeed in removing slabs from both
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   749
 * ends of the free list, completely allocating on the one hand and completely
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   750
 * freeing on the other. Objects selected as move destinations are allocated in
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   751
 * the kmem maintenance thread where move requests are enqueued. A separate
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   752
 * callback thread removes pending callbacks from the queue and calls the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   753
 * client. The separate thread ensures that client code (the move function) does
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   754
 * not interfere with internal kmem maintenance tasks. A map of pending
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   755
 * callbacks keyed by object address (the object to be moved) is checked to
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   756
 * ensure that duplicate callbacks are not generated for the same object.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   757
 * Allocating the move destination (the object to move to) prevents subsequent
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   758
 * callbacks from selecting the same destination as an earlier pending callback.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   759
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   760
 * Move requests can also be generated by kmem_cache_reap() when the system is
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   761
 * desperate for memory and by kmem_cache_move_notify(), called by the client to
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   762
 * notify kmem that a move refused earlier with KMEM_CBRC_LATER is now possible.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   763
 * The map of pending callbacks is protected by the same lock that protects the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   764
 * slab layer.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   765
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   766
 * When the system is desperate for memory, kmem does not bother to determine
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   767
 * whether or not the cache exceeds the fragmentation threshold, but tries to
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   768
 * consolidate as many slabs as possible. Normally, the consolidator chews
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   769
 * slowly, one sparsely allocated slab at a time during each maintenance
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   770
 * interval that the cache is fragmented. When desperate, the consolidator
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   771
 * starts at the last partial slab and enqueues callbacks for every allocated
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   772
 * object on every partial slab, working backwards until it reaches the first
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   773
 * partial slab. The first partial slab, meanwhile, advances in pace with the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   774
 * consolidator as allocations to supply move destinations for the enqueued
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   775
 * callbacks use up the highly allocated slabs at the front of the free list.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   776
 * Ideally, the overgrown free list collapses like an accordion, starting at
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   777
 * both ends and ending at the center with a single partial slab.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   778
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   779
 * 3.3 Client Responses
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   780
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   781
 * When the client returns KMEM_CBRC_NO in response to the move callback, kmem
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   782
 * marks the slab that supplied the stuck object non-reclaimable and moves it to
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   783
 * front of the free list. The slab remains marked as long as it remains on the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   784
 * free list, and it appears more allocated to the partial slab compare function
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   785
 * than any unmarked slab, no matter how many of its objects are allocated.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   786
 * Since even one immovable object ties up the entire slab, the goal is to
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   787
 * completely allocate any slab that cannot be completely freed. kmem does not
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   788
 * bother generating callbacks to move objects from a marked slab unless the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   789
 * system is desperate.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   790
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   791
 * When the client responds KMEM_CBRC_LATER, kmem increments a count for the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   792
 * slab. If the client responds LATER too many times, kmem disbelieves and
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   793
 * treats the response as a NO. The count is cleared when the slab is taken off
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   794
 * the partial slab list or when the client moves one of the slab's objects.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   795
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   796
 * 4. Observability
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   797
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   798
 * A kmem cache's external fragmentation is best observed with 'mdb -k' using
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   799
 * the ::kmem_slabs dcmd. For a complete description of the command, enter
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   800
 * '::help kmem_slabs' at the mdb prompt.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   801
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   802
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   803
#include <sys/kmem_impl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   804
#include <sys/vmem_impl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   805
#include <sys/param.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   806
#include <sys/sysmacros.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   807
#include <sys/vm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   808
#include <sys/proc.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   809
#include <sys/tuneable.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   810
#include <sys/systm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   811
#include <sys/cmn_err.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   812
#include <sys/debug.h>
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   813
#include <sys/sdt.h>
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   814
#include <sys/mutex.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   815
#include <sys/bitmap.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   816
#include <sys/atomic.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   817
#include <sys/kobj.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   818
#include <sys/disp.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   819
#include <vm/seg_kmem.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   820
#include <sys/log.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   821
#include <sys/callb.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   822
#include <sys/taskq.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   823
#include <sys/modctl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   824
#include <sys/reboot.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   825
#include <sys/id32.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   826
#include <sys/zone.h>
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3290
diff changeset
   827
#include <sys/netstack.h>
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   828
#ifdef	DEBUG
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   829
#include <sys/random.h>
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   830
#endif
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   831
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   832
extern void streams_msg_init(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   833
extern int segkp_fromheap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   834
extern void segkp_cache_free(void);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   835
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   836
struct kmem_cache_kstat {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   837
	kstat_named_t	kmc_buf_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   838
	kstat_named_t	kmc_align;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   839
	kstat_named_t	kmc_chunk_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   840
	kstat_named_t	kmc_slab_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   841
	kstat_named_t	kmc_alloc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   842
	kstat_named_t	kmc_alloc_fail;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   843
	kstat_named_t	kmc_free;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   844
	kstat_named_t	kmc_depot_alloc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   845
	kstat_named_t	kmc_depot_free;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   846
	kstat_named_t	kmc_depot_contention;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   847
	kstat_named_t	kmc_slab_alloc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   848
	kstat_named_t	kmc_slab_free;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   849
	kstat_named_t	kmc_buf_constructed;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   850
	kstat_named_t	kmc_buf_avail;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   851
	kstat_named_t	kmc_buf_inuse;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   852
	kstat_named_t	kmc_buf_total;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   853
	kstat_named_t	kmc_buf_max;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   854
	kstat_named_t	kmc_slab_create;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   855
	kstat_named_t	kmc_slab_destroy;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   856
	kstat_named_t	kmc_vmem_source;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   857
	kstat_named_t	kmc_hash_size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   858
	kstat_named_t	kmc_hash_lookup_depth;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   859
	kstat_named_t	kmc_hash_rescale;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   860
	kstat_named_t	kmc_full_magazines;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   861
	kstat_named_t	kmc_empty_magazines;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   862
	kstat_named_t	kmc_magazine_size;
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
   863
	kstat_named_t	kmc_reap; /* number of kmem_cache_reap() calls */
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
   864
	kstat_named_t	kmc_defrag; /* attempts to defrag all partial slabs */
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
   865
	kstat_named_t	kmc_scan; /* attempts to defrag one partial slab */
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
   866
	kstat_named_t	kmc_move_callbacks; /* sum of yes, no, later, dn, dk */
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   867
	kstat_named_t	kmc_move_yes;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   868
	kstat_named_t	kmc_move_no;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   869
	kstat_named_t	kmc_move_later;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   870
	kstat_named_t	kmc_move_dont_need;
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
   871
	kstat_named_t	kmc_move_dont_know; /* obj unrecognized by client ... */
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
   872
	kstat_named_t	kmc_move_hunt_found; /* ... but found in mag layer */
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
   873
	kstat_named_t	kmc_move_slabs_freed; /* slabs freed by consolidator */
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
   874
	kstat_named_t	kmc_move_reclaimable; /* buffers, if consolidator ran */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   875
} kmem_cache_kstat = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   876
	{ "buf_size",		KSTAT_DATA_UINT64 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   877
	{ "align",		KSTAT_DATA_UINT64 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   878
	{ "chunk_size",		KSTAT_DATA_UINT64 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   879
	{ "slab_size",		KSTAT_DATA_UINT64 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   880
	{ "alloc",		KSTAT_DATA_UINT64 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   881
	{ "alloc_fail",		KSTAT_DATA_UINT64 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   882
	{ "free",		KSTAT_DATA_UINT64 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   883
	{ "depot_alloc",	KSTAT_DATA_UINT64 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   884
	{ "depot_free",		KSTAT_DATA_UINT64 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   885
	{ "depot_contention",	KSTAT_DATA_UINT64 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   886
	{ "slab_alloc",		KSTAT_DATA_UINT64 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   887
	{ "slab_free",		KSTAT_DATA_UINT64 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   888
	{ "buf_constructed",	KSTAT_DATA_UINT64 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   889
	{ "buf_avail",		KSTAT_DATA_UINT64 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   890
	{ "buf_inuse",		KSTAT_DATA_UINT64 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   891
	{ "buf_total",		KSTAT_DATA_UINT64 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   892
	{ "buf_max",		KSTAT_DATA_UINT64 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   893
	{ "slab_create",	KSTAT_DATA_UINT64 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   894
	{ "slab_destroy",	KSTAT_DATA_UINT64 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   895
	{ "vmem_source",	KSTAT_DATA_UINT64 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   896
	{ "hash_size",		KSTAT_DATA_UINT64 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   897
	{ "hash_lookup_depth",	KSTAT_DATA_UINT64 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   898
	{ "hash_rescale",	KSTAT_DATA_UINT64 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   899
	{ "full_magazines",	KSTAT_DATA_UINT64 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   900
	{ "empty_magazines",	KSTAT_DATA_UINT64 },
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   901
	{ "magazine_size",	KSTAT_DATA_UINT64 },
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
   902
	{ "reap",		KSTAT_DATA_UINT64 },
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
   903
	{ "defrag",		KSTAT_DATA_UINT64 },
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
   904
	{ "scan",		KSTAT_DATA_UINT64 },
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   905
	{ "move_callbacks",	KSTAT_DATA_UINT64 },
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   906
	{ "move_yes",		KSTAT_DATA_UINT64 },
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   907
	{ "move_no",		KSTAT_DATA_UINT64 },
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   908
	{ "move_later",		KSTAT_DATA_UINT64 },
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   909
	{ "move_dont_need",	KSTAT_DATA_UINT64 },
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   910
	{ "move_dont_know",	KSTAT_DATA_UINT64 },
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
   911
	{ "move_hunt_found",	KSTAT_DATA_UINT64 },
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
   912
	{ "move_slabs_freed",	KSTAT_DATA_UINT64 },
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
   913
	{ "move_reclaimable",	KSTAT_DATA_UINT64 },
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   914
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   915
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   916
static kmutex_t kmem_cache_kstat_lock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   917
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   918
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   919
 * The default set of caches to back kmem_alloc().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   920
 * These sizes should be reevaluated periodically.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   921
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   922
 * We want allocations that are multiples of the coherency granularity
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   923
 * (64 bytes) to be satisfied from a cache which is a multiple of 64
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   924
 * bytes, so that it will be 64-byte aligned.  For all multiples of 64,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   925
 * the next kmem_cache_size greater than or equal to it must be a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   926
 * multiple of 64.
9367
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
   927
 *
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
   928
 * We split the table into two sections:  size <= 4k and size > 4k.  This
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
   929
 * saves a lot of space and cache footprint in our cache tables.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   930
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   931
static const int kmem_alloc_sizes[] = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   932
	1 * 8,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   933
	2 * 8,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   934
	3 * 8,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   935
	4 * 8,		5 * 8,		6 * 8,		7 * 8,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   936
	4 * 16,		5 * 16,		6 * 16,		7 * 16,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   937
	4 * 32,		5 * 32,		6 * 32,		7 * 32,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   938
	4 * 64,		5 * 64,		6 * 64,		7 * 64,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   939
	4 * 128,	5 * 128,	6 * 128,	7 * 128,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   940
	P2ALIGN(8192 / 7, 64),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   941
	P2ALIGN(8192 / 6, 64),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   942
	P2ALIGN(8192 / 5, 64),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   943
	P2ALIGN(8192 / 4, 64),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   944
	P2ALIGN(8192 / 3, 64),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   945
	P2ALIGN(8192 / 2, 64),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   946
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   947
9367
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
   948
static const int kmem_big_alloc_sizes[] = {
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
   949
	2 * 4096,	3 * 4096,
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
   950
	2 * 8192,	3 * 8192,
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
   951
	4 * 8192,	5 * 8192,	6 * 8192,	7 * 8192,
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
   952
	8 * 8192,	9 * 8192,	10 * 8192,	11 * 8192,
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
   953
	12 * 8192,	13 * 8192,	14 * 8192,	15 * 8192,
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
   954
	16 * 8192
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
   955
};
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
   956
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
   957
#define	KMEM_MAXBUF		4096
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
   958
#define	KMEM_BIG_MAXBUF_32BIT	32768
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
   959
#define	KMEM_BIG_MAXBUF		131072
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
   960
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
   961
#define	KMEM_BIG_MULTIPLE	4096	/* big_alloc_sizes must be a multiple */
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
   962
#define	KMEM_BIG_SHIFT		12	/* lg(KMEM_BIG_MULTIPLE) */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   963
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   964
static kmem_cache_t *kmem_alloc_table[KMEM_MAXBUF >> KMEM_ALIGN_SHIFT];
9367
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
   965
static kmem_cache_t *kmem_big_alloc_table[KMEM_BIG_MAXBUF >> KMEM_BIG_SHIFT];
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
   966
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
   967
#define	KMEM_ALLOC_TABLE_MAX	(KMEM_MAXBUF >> KMEM_ALIGN_SHIFT)
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
   968
static size_t kmem_big_alloc_table_max = 0;	/* # of filled elements */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   969
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   970
static kmem_magtype_t kmem_magtype[] = {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   971
	{ 1,	8,	3200,	65536	},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   972
	{ 3,	16,	256,	32768	},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   973
	{ 7,	32,	64,	16384	},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   974
	{ 15,	64,	0,	8192	},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   975
	{ 31,	64,	0,	4096	},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   976
	{ 47,	64,	0,	2048	},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   977
	{ 63,	64,	0,	1024	},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   978
	{ 95,	64,	0,	512	},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   979
	{ 143,	64,	0,	0	},
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   980
};
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   981
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   982
static uint32_t kmem_reaping;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   983
static uint32_t kmem_reaping_idspace;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   984
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   985
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   986
 * kmem tunables
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   987
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   988
clock_t kmem_reap_interval;	/* cache reaping rate [15 * HZ ticks] */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   989
int kmem_depot_contention = 3;	/* max failed tryenters per real interval */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   990
pgcnt_t kmem_reapahead = 0;	/* start reaping N pages before pageout */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   991
int kmem_panic = 1;		/* whether to panic on error */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   992
int kmem_logging = 1;		/* kmem_log_enter() override */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   993
uint32_t kmem_mtbf = 0;		/* mean time between failures [default: off] */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   994
size_t kmem_transaction_log_size; /* transaction log size [2% of memory] */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   995
size_t kmem_content_log_size;	/* content log size [2% of memory] */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   996
size_t kmem_failure_log_size;	/* failure log [4 pages per CPU] */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   997
size_t kmem_slab_log_size;	/* slab create log [4 pages per CPU] */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   998
size_t kmem_content_maxsave = 256; /* KMF_CONTENTS max bytes to log */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   999
size_t kmem_lite_minsize = 0;	/* minimum buffer size for KMF_LITE */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1000
size_t kmem_lite_maxalign = 1024; /* maximum buffer alignment for KMF_LITE */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1001
int kmem_lite_pcs = 4;		/* number of PCs to store in KMF_LITE mode */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1002
size_t kmem_maxverify;		/* maximum bytes to inspect in debug routines */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1003
size_t kmem_minfirewall;	/* hardware-enforced redzone threshold */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1004
9367
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  1005
#ifdef _LP64
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  1006
size_t	kmem_max_cached = KMEM_BIG_MAXBUF;	/* maximum kmem_alloc cache */
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  1007
#else
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  1008
size_t	kmem_max_cached = KMEM_BIG_MAXBUF_32BIT; /* maximum kmem_alloc cache */
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  1009
#endif
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  1010
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1011
#ifdef DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1012
int kmem_flags = KMF_AUDIT | KMF_DEADBEEF | KMF_REDZONE | KMF_CONTENTS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1013
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1014
int kmem_flags = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1015
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1016
int kmem_ready;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1017
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1018
static kmem_cache_t	*kmem_slab_cache;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1019
static kmem_cache_t	*kmem_bufctl_cache;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1020
static kmem_cache_t	*kmem_bufctl_audit_cache;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1021
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1022
static kmutex_t		kmem_cache_lock;	/* inter-cache linkage only */
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1023
static list_t		kmem_caches;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1024
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1025
static taskq_t		*kmem_taskq;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1026
static kmutex_t		kmem_flags_lock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1027
static vmem_t		*kmem_metadata_arena;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1028
static vmem_t		*kmem_msb_arena;	/* arena for metadata caches */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1029
static vmem_t		*kmem_cache_arena;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1030
static vmem_t		*kmem_hash_arena;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1031
static vmem_t		*kmem_log_arena;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1032
static vmem_t		*kmem_oversize_arena;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1033
static vmem_t		*kmem_va_arena;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1034
static vmem_t		*kmem_default_arena;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1035
static vmem_t		*kmem_firewall_va_arena;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1036
static vmem_t		*kmem_firewall_arena;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1037
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1038
/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1039
 * Define KMEM_STATS to turn on statistic gathering. By default, it is only
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1040
 * turned on when DEBUG is also defined.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1041
 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1042
#ifdef	DEBUG
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1043
#define	KMEM_STATS
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1044
#endif	/* DEBUG */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1045
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1046
#ifdef	KMEM_STATS
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1047
#define	KMEM_STAT_ADD(stat)			((stat)++)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1048
#define	KMEM_STAT_COND_ADD(cond, stat)		((void) (!(cond) || (stat)++))
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1049
#else
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1050
#define	KMEM_STAT_ADD(stat)			/* nothing */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1051
#define	KMEM_STAT_COND_ADD(cond, stat)		/* nothing */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1052
#endif	/* KMEM_STATS */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1053
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1054
/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1055
 * kmem slab consolidator thresholds (tunables)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1056
 */
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  1057
size_t kmem_frag_minslabs = 101;	/* minimum total slabs */
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  1058
size_t kmem_frag_numer = 1;		/* free buffers (numerator) */
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  1059
size_t kmem_frag_denom = KMEM_VOID_FRACTION; /* buffers (denominator) */
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1060
/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1061
 * Maximum number of slabs from which to move buffers during a single
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1062
 * maintenance interval while the system is not low on memory.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1063
 */
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  1064
size_t kmem_reclaim_max_slabs = 1;
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1065
/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1066
 * Number of slabs to scan backwards from the end of the partial slab list
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1067
 * when searching for buffers to relocate.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1068
 */
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  1069
size_t kmem_reclaim_scan_range = 12;
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1070
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1071
#ifdef	KMEM_STATS
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1072
static struct {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1073
	uint64_t kms_callbacks;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1074
	uint64_t kms_yes;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1075
	uint64_t kms_no;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1076
	uint64_t kms_later;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1077
	uint64_t kms_dont_need;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1078
	uint64_t kms_dont_know;
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  1079
	uint64_t kms_hunt_found_mag;
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1080
	uint64_t kms_hunt_found_slab;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1081
	uint64_t kms_hunt_alloc_fail;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1082
	uint64_t kms_hunt_lucky;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1083
	uint64_t kms_notify;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1084
	uint64_t kms_notify_callbacks;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1085
	uint64_t kms_disbelief;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1086
	uint64_t kms_already_pending;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1087
	uint64_t kms_callback_alloc_fail;
6908
f5c1c68a07ca 6712962 mutex_destroy: bad mutex at zfs_znode_cache_destructor
tomee
parents: 6819
diff changeset
  1088
	uint64_t kms_callback_taskq_fail;
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  1089
	uint64_t kms_endscan_slab_dead;
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1090
	uint64_t kms_endscan_slab_destroyed;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1091
	uint64_t kms_endscan_nomem;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1092
	uint64_t kms_endscan_refcnt_changed;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1093
	uint64_t kms_endscan_nomove_changed;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1094
	uint64_t kms_endscan_freelist;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1095
	uint64_t kms_avl_update;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1096
	uint64_t kms_avl_noupdate;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1097
	uint64_t kms_no_longer_reclaimable;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1098
	uint64_t kms_notify_no_longer_reclaimable;
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  1099
	uint64_t kms_notify_slab_dead;
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  1100
	uint64_t kms_notify_slab_destroyed;
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1101
	uint64_t kms_alloc_fail;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1102
	uint64_t kms_constructor_fail;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1103
	uint64_t kms_dead_slabs_freed;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1104
	uint64_t kms_defrags;
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  1105
	uint64_t kms_scans;
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1106
	uint64_t kms_scan_depot_ws_reaps;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1107
	uint64_t kms_debug_reaps;
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  1108
	uint64_t kms_debug_scans;
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1109
} kmem_move_stats;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1110
#endif	/* KMEM_STATS */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1111
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1112
/* consolidator knobs */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1113
static boolean_t kmem_move_noreap;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1114
static boolean_t kmem_move_blocked;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1115
static boolean_t kmem_move_fulltilt;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1116
static boolean_t kmem_move_any_partial;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1117
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1118
#ifdef	DEBUG
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1119
/*
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  1120
 * kmem consolidator debug tunables:
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1121
 * Ensure code coverage by occasionally running the consolidator even when the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1122
 * caches are not fragmented (they may never be). These intervals are mean time
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1123
 * in cache maintenance intervals (kmem_cache_update).
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1124
 */
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  1125
uint32_t kmem_mtb_move = 60;	/* defrag 1 slab (~15min) */
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  1126
uint32_t kmem_mtb_reap = 1800;	/* defrag all slabs (~7.5hrs) */
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1127
#endif	/* DEBUG */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1128
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1129
static kmem_cache_t	*kmem_defrag_cache;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1130
static kmem_cache_t	*kmem_move_cache;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1131
static taskq_t		*kmem_move_taskq;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1132
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1133
static void kmem_cache_scan(kmem_cache_t *);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1134
static void kmem_cache_defrag(kmem_cache_t *);
12093
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1135
static void kmem_slab_prefill(kmem_cache_t *, kmem_slab_t *);
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1136
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1137
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1138
kmem_log_header_t	*kmem_transaction_log;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1139
kmem_log_header_t	*kmem_content_log;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1140
kmem_log_header_t	*kmem_failure_log;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1141
kmem_log_header_t	*kmem_slab_log;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1142
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1143
static int		kmem_lite_count; /* # of PCs in kmem_buftag_lite_t */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1144
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1145
#define	KMEM_BUFTAG_LITE_ENTER(bt, count, caller)			\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1146
	if ((count) > 0) {						\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1147
		pc_t *_s = ((kmem_buftag_lite_t *)(bt))->bt_history;	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1148
		pc_t *_e;						\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1149
		/* memmove() the old entries down one notch */		\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1150
		for (_e = &_s[(count) - 1]; _e > _s; _e--)		\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1151
			*_e = *(_e - 1);				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1152
		*_s = (uintptr_t)(caller);				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1153
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1154
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1155
#define	KMERR_MODIFIED	0	/* buffer modified while on freelist */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1156
#define	KMERR_REDZONE	1	/* redzone violation (write past end of buf) */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1157
#define	KMERR_DUPFREE	2	/* freed a buffer twice */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1158
#define	KMERR_BADADDR	3	/* freed a bad (unallocated) address */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1159
#define	KMERR_BADBUFTAG	4	/* buftag corrupted */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1160
#define	KMERR_BADBUFCTL	5	/* bufctl corrupted */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1161
#define	KMERR_BADCACHE	6	/* freed a buffer to the wrong cache */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1162
#define	KMERR_BADSIZE	7	/* alloc size != free size */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1163
#define	KMERR_BADBASE	8	/* buffer base address wrong */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1164
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1165
struct {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1166
	hrtime_t	kmp_timestamp;	/* timestamp of panic */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1167
	int		kmp_error;	/* type of kmem error */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1168
	void		*kmp_buffer;	/* buffer that induced panic */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1169
	void		*kmp_realbuf;	/* real start address for buffer */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1170
	kmem_cache_t	*kmp_cache;	/* buffer's cache according to client */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1171
	kmem_cache_t	*kmp_realcache;	/* actual cache containing buffer */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1172
	kmem_slab_t	*kmp_slab;	/* slab accoring to kmem_findslab() */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1173
	kmem_bufctl_t	*kmp_bufctl;	/* bufctl */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1174
} kmem_panic_info;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1175
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1176
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1177
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1178
copy_pattern(uint64_t pattern, void *buf_arg, size_t size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1179
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1180
	uint64_t *bufend = (uint64_t *)((char *)buf_arg + size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1181
	uint64_t *buf = buf_arg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1182
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1183
	while (buf < bufend)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1184
		*buf++ = pattern;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1185
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1186
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1187
static void *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1188
verify_pattern(uint64_t pattern, void *buf_arg, size_t size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1189
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1190
	uint64_t *bufend = (uint64_t *)((char *)buf_arg + size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1191
	uint64_t *buf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1192
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1193
	for (buf = buf_arg; buf < bufend; buf++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1194
		if (*buf != pattern)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1195
			return (buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1196
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1197
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1198
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1199
static void *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1200
verify_and_copy_pattern(uint64_t old, uint64_t new, void *buf_arg, size_t size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1201
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1202
	uint64_t *bufend = (uint64_t *)((char *)buf_arg + size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1203
	uint64_t *buf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1204
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1205
	for (buf = buf_arg; buf < bufend; buf++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1206
		if (*buf != old) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1207
			copy_pattern(old, buf_arg,
6306
ecac2262dc70 6675361 kmem_cache_kstat_update() is hot on large servers
tomee
parents: 3448
diff changeset
  1208
			    (char *)buf - (char *)buf_arg);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1209
			return (buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1210
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1211
		*buf = new;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1212
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1213
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1214
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1215
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1216
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1217
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1218
kmem_cache_applyall(void (*func)(kmem_cache_t *), taskq_t *tq, int tqflag)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1219
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1220
	kmem_cache_t *cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1221
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1222
	mutex_enter(&kmem_cache_lock);
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1223
	for (cp = list_head(&kmem_caches); cp != NULL;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1224
	    cp = list_next(&kmem_caches, cp))
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1225
		if (tq != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1226
			(void) taskq_dispatch(tq, (task_func_t *)func, cp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1227
			    tqflag);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1228
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1229
			func(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1230
	mutex_exit(&kmem_cache_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1231
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1232
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1233
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1234
kmem_cache_applyall_id(void (*func)(kmem_cache_t *), taskq_t *tq, int tqflag)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1235
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1236
	kmem_cache_t *cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1237
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1238
	mutex_enter(&kmem_cache_lock);
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1239
	for (cp = list_head(&kmem_caches); cp != NULL;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1240
	    cp = list_next(&kmem_caches, cp)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1241
		if (!(cp->cache_cflags & KMC_IDENTIFIER))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1242
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1243
		if (tq != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1244
			(void) taskq_dispatch(tq, (task_func_t *)func, cp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1245
			    tqflag);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1246
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1247
			func(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1248
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1249
	mutex_exit(&kmem_cache_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1250
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1251
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1252
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1253
 * Debugging support.  Given a buffer address, find its slab.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1254
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1255
static kmem_slab_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1256
kmem_findslab(kmem_cache_t *cp, void *buf)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1257
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1258
	kmem_slab_t *sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1259
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1260
	mutex_enter(&cp->cache_lock);
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1261
	for (sp = list_head(&cp->cache_complete_slabs); sp != NULL;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1262
	    sp = list_next(&cp->cache_complete_slabs, sp)) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1263
		if (KMEM_SLAB_MEMBER(sp, buf)) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1264
			mutex_exit(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1265
			return (sp);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1266
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1267
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1268
	for (sp = avl_first(&cp->cache_partial_slabs); sp != NULL;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1269
	    sp = AVL_NEXT(&cp->cache_partial_slabs, sp)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1270
		if (KMEM_SLAB_MEMBER(sp, buf)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1271
			mutex_exit(&cp->cache_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1272
			return (sp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1273
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1274
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1275
	mutex_exit(&cp->cache_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1276
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1277
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1278
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1279
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1280
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1281
kmem_error(int error, kmem_cache_t *cparg, void *bufarg)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1282
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1283
	kmem_buftag_t *btp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1284
	kmem_bufctl_t *bcp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1285
	kmem_cache_t *cp = cparg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1286
	kmem_slab_t *sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1287
	uint64_t *off;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1288
	void *buf = bufarg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1289
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1290
	kmem_logging = 0;	/* stop logging when a bad thing happens */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1291
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1292
	kmem_panic_info.kmp_timestamp = gethrtime();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1293
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1294
	sp = kmem_findslab(cp, buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1295
	if (sp == NULL) {
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1296
		for (cp = list_tail(&kmem_caches); cp != NULL;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1297
		    cp = list_prev(&kmem_caches, cp)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1298
			if ((sp = kmem_findslab(cp, buf)) != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1299
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1300
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1301
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1302
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1303
	if (sp == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1304
		cp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1305
		error = KMERR_BADADDR;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1306
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1307
		if (cp != cparg)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1308
			error = KMERR_BADCACHE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1309
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1310
			buf = (char *)bufarg - ((uintptr_t)bufarg -
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1311
			    (uintptr_t)sp->slab_base) % cp->cache_chunksize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1312
		if (buf != bufarg)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1313
			error = KMERR_BADBASE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1314
		if (cp->cache_flags & KMF_BUFTAG)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1315
			btp = KMEM_BUFTAG(cp, buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1316
		if (cp->cache_flags & KMF_HASH) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1317
			mutex_enter(&cp->cache_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1318
			for (bcp = *KMEM_HASH(cp, buf); bcp; bcp = bcp->bc_next)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1319
				if (bcp->bc_addr == buf)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1320
					break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1321
			mutex_exit(&cp->cache_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1322
			if (bcp == NULL && btp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1323
				bcp = btp->bt_bufctl;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1324
			if (kmem_findslab(cp->cache_bufctl_cache, bcp) ==
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1325
			    NULL || P2PHASE((uintptr_t)bcp, KMEM_ALIGN) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1326
			    bcp->bc_addr != buf) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1327
				error = KMERR_BADBUFCTL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1328
				bcp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1329
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1330
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1331
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1332
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1333
	kmem_panic_info.kmp_error = error;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1334
	kmem_panic_info.kmp_buffer = bufarg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1335
	kmem_panic_info.kmp_realbuf = buf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1336
	kmem_panic_info.kmp_cache = cparg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1337
	kmem_panic_info.kmp_realcache = cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1338
	kmem_panic_info.kmp_slab = sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1339
	kmem_panic_info.kmp_bufctl = bcp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1340
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1341
	printf("kernel memory allocator: ");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1342
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1343
	switch (error) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1344
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1345
	case KMERR_MODIFIED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1346
		printf("buffer modified after being freed\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1347
		off = verify_pattern(KMEM_FREE_PATTERN, buf, cp->cache_verify);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1348
		if (off == NULL)	/* shouldn't happen */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1349
			off = buf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1350
		printf("modification occurred at offset 0x%lx "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1351
		    "(0x%llx replaced by 0x%llx)\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1352
		    (uintptr_t)off - (uintptr_t)buf,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1353
		    (longlong_t)KMEM_FREE_PATTERN, (longlong_t)*off);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1354
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1355
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1356
	case KMERR_REDZONE:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1357
		printf("redzone violation: write past end of buffer\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1358
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1359
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1360
	case KMERR_BADADDR:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1361
		printf("invalid free: buffer not in cache\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1362
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1363
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1364
	case KMERR_DUPFREE:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1365
		printf("duplicate free: buffer freed twice\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1366
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1367
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1368
	case KMERR_BADBUFTAG:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1369
		printf("boundary tag corrupted\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1370
		printf("bcp ^ bxstat = %lx, should be %lx\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1371
		    (intptr_t)btp->bt_bufctl ^ btp->bt_bxstat,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1372
		    KMEM_BUFTAG_FREE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1373
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1374
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1375
	case KMERR_BADBUFCTL:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1376
		printf("bufctl corrupted\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1377
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1378
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1379
	case KMERR_BADCACHE:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1380
		printf("buffer freed to wrong cache\n");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1381
		printf("buffer was allocated from %s,\n", cp->cache_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1382
		printf("caller attempting free to %s.\n", cparg->cache_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1383
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1384
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1385
	case KMERR_BADSIZE:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1386
		printf("bad free: free size (%u) != alloc size (%u)\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1387
		    KMEM_SIZE_DECODE(((uint32_t *)btp)[0]),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1388
		    KMEM_SIZE_DECODE(((uint32_t *)btp)[1]));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1389
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1390
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1391
	case KMERR_BADBASE:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1392
		printf("bad free: free address (%p) != alloc address (%p)\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1393
		    bufarg, buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1394
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1395
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1396
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1397
	printf("buffer=%p  bufctl=%p  cache: %s\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1398
	    bufarg, (void *)bcp, cparg->cache_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1399
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1400
	if (bcp != NULL && (cp->cache_flags & KMF_AUDIT) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1401
	    error != KMERR_BADBUFCTL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1402
		int d;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1403
		timestruc_t ts;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1404
		kmem_bufctl_audit_t *bcap = (kmem_bufctl_audit_t *)bcp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1405
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1406
		hrt2ts(kmem_panic_info.kmp_timestamp - bcap->bc_timestamp, &ts);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1407
		printf("previous transaction on buffer %p:\n", buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1408
		printf("thread=%p  time=T-%ld.%09ld  slab=%p  cache: %s\n",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1409
		    (void *)bcap->bc_thread, ts.tv_sec, ts.tv_nsec,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1410
		    (void *)sp, cp->cache_name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1411
		for (d = 0; d < MIN(bcap->bc_depth, KMEM_STACK_DEPTH); d++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1412
			ulong_t off;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1413
			char *sym = kobj_getsymname(bcap->bc_stack[d], &off);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1414
			printf("%s+%lx\n", sym ? sym : "?", off);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1415
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1416
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1417
	if (kmem_panic > 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1418
		panic("kernel heap corruption detected");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1419
	if (kmem_panic == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1420
		debug_enter(NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1421
	kmem_logging = 1;	/* resume logging */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1422
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1423
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1424
static kmem_log_header_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1425
kmem_log_init(size_t logsize)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1426
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1427
	kmem_log_header_t *lhp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1428
	int nchunks = 4 * max_ncpus;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1429
	size_t lhsize = (size_t)&((kmem_log_header_t *)0)->lh_cpu[max_ncpus];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1430
	int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1431
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1432
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1433
	 * Make sure that lhp->lh_cpu[] is nicely aligned
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1434
	 * to prevent false sharing of cache lines.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1435
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1436
	lhsize = P2ROUNDUP(lhsize, KMEM_ALIGN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1437
	lhp = vmem_xalloc(kmem_log_arena, lhsize, 64, P2NPHASE(lhsize, 64), 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1438
	    NULL, NULL, VM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1439
	bzero(lhp, lhsize);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1440
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1441
	mutex_init(&lhp->lh_lock, NULL, MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1442
	lhp->lh_nchunks = nchunks;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1443
	lhp->lh_chunksize = P2ROUNDUP(logsize / nchunks + 1, PAGESIZE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1444
	lhp->lh_base = vmem_alloc(kmem_log_arena,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1445
	    lhp->lh_chunksize * nchunks, VM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1446
	lhp->lh_free = vmem_alloc(kmem_log_arena,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1447
	    nchunks * sizeof (int), VM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1448
	bzero(lhp->lh_base, lhp->lh_chunksize * nchunks);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1449
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1450
	for (i = 0; i < max_ncpus; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1451
		kmem_cpu_log_header_t *clhp = &lhp->lh_cpu[i];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1452
		mutex_init(&clhp->clh_lock, NULL, MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1453
		clhp->clh_chunk = i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1454
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1455
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1456
	for (i = max_ncpus; i < nchunks; i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1457
		lhp->lh_free[i] = i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1458
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1459
	lhp->lh_head = max_ncpus;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1460
	lhp->lh_tail = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1461
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1462
	return (lhp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1463
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1464
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1465
static void *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1466
kmem_log_enter(kmem_log_header_t *lhp, void *data, size_t size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1467
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1468
	void *logspace;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1469
	kmem_cpu_log_header_t *clhp = &lhp->lh_cpu[CPU->cpu_seqid];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1470
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1471
	if (lhp == NULL || kmem_logging == 0 || panicstr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1472
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1473
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1474
	mutex_enter(&clhp->clh_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1475
	clhp->clh_hits++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1476
	if (size > clhp->clh_avail) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1477
		mutex_enter(&lhp->lh_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1478
		lhp->lh_hits++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1479
		lhp->lh_free[lhp->lh_tail] = clhp->clh_chunk;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1480
		lhp->lh_tail = (lhp->lh_tail + 1) % lhp->lh_nchunks;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1481
		clhp->clh_chunk = lhp->lh_free[lhp->lh_head];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1482
		lhp->lh_head = (lhp->lh_head + 1) % lhp->lh_nchunks;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1483
		clhp->clh_current = lhp->lh_base +
6306
ecac2262dc70 6675361 kmem_cache_kstat_update() is hot on large servers
tomee
parents: 3448
diff changeset
  1484
		    clhp->clh_chunk * lhp->lh_chunksize;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1485
		clhp->clh_avail = lhp->lh_chunksize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1486
		if (size > lhp->lh_chunksize)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1487
			size = lhp->lh_chunksize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1488
		mutex_exit(&lhp->lh_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1489
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1490
	logspace = clhp->clh_current;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1491
	clhp->clh_current += size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1492
	clhp->clh_avail -= size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1493
	bcopy(data, logspace, size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1494
	mutex_exit(&clhp->clh_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1495
	return (logspace);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1496
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1497
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1498
#define	KMEM_AUDIT(lp, cp, bcp)						\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1499
{									\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1500
	kmem_bufctl_audit_t *_bcp = (kmem_bufctl_audit_t *)(bcp);	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1501
	_bcp->bc_timestamp = gethrtime();				\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1502
	_bcp->bc_thread = curthread;					\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1503
	_bcp->bc_depth = getpcstack(_bcp->bc_stack, KMEM_STACK_DEPTH);	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1504
	_bcp->bc_lastlog = kmem_log_enter((lp), _bcp, sizeof (*_bcp));	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1505
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1506
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1507
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1508
kmem_log_event(kmem_log_header_t *lp, kmem_cache_t *cp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1509
	kmem_slab_t *sp, void *addr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1510
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1511
	kmem_bufctl_audit_t bca;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1512
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1513
	bzero(&bca, sizeof (kmem_bufctl_audit_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1514
	bca.bc_addr = addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1515
	bca.bc_slab = sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1516
	bca.bc_cache = cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1517
	KMEM_AUDIT(lp, cp, &bca);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1518
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1519
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1520
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1521
 * Create a new slab for cache cp.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1522
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1523
static kmem_slab_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1524
kmem_slab_create(kmem_cache_t *cp, int kmflag)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1525
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1526
	size_t slabsize = cp->cache_slabsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1527
	size_t chunksize = cp->cache_chunksize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1528
	int cache_flags = cp->cache_flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1529
	size_t color, chunks;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1530
	char *buf, *slab;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1531
	kmem_slab_t *sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1532
	kmem_bufctl_t *bcp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1533
	vmem_t *vmp = cp->cache_arena;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1534
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1535
	ASSERT(MUTEX_NOT_HELD(&cp->cache_lock));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1536
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1537
	color = cp->cache_color + cp->cache_align;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1538
	if (color > cp->cache_maxcolor)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1539
		color = cp->cache_mincolor;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1540
	cp->cache_color = color;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1541
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1542
	slab = vmem_alloc(vmp, slabsize, kmflag & KM_VMFLAGS);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1543
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1544
	if (slab == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1545
		goto vmem_alloc_failure;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1546
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1547
	ASSERT(P2PHASE((uintptr_t)slab, vmp->vm_quantum) == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1548
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1549
	/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1550
	 * Reverify what was already checked in kmem_cache_set_move(), since the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1551
	 * consolidator depends (for correctness) on slabs being initialized
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1552
	 * with the 0xbaddcafe memory pattern (setting a low order bit usable by
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1553
	 * clients to distinguish uninitialized memory from known objects).
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1554
	 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1555
	ASSERT((cp->cache_move == NULL) || !(cp->cache_cflags & KMC_NOTOUCH));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1556
	if (!(cp->cache_cflags & KMC_NOTOUCH))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1557
		copy_pattern(KMEM_UNINITIALIZED_PATTERN, slab, slabsize);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1558
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1559
	if (cache_flags & KMF_HASH) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1560
		if ((sp = kmem_cache_alloc(kmem_slab_cache, kmflag)) == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1561
			goto slab_alloc_failure;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1562
		chunks = (slabsize - color) / chunksize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1563
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1564
		sp = KMEM_SLAB(cp, slab);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1565
		chunks = (slabsize - sizeof (kmem_slab_t) - color) / chunksize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1566
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1567
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1568
	sp->slab_cache	= cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1569
	sp->slab_head	= NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1570
	sp->slab_refcnt	= 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1571
	sp->slab_base	= buf = slab + color;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1572
	sp->slab_chunks	= chunks;
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1573
	sp->slab_stuck_offset = (uint32_t)-1;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1574
	sp->slab_later_count = 0;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1575
	sp->slab_flags = 0;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1576
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1577
	ASSERT(chunks > 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1578
	while (chunks-- != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1579
		if (cache_flags & KMF_HASH) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1580
			bcp = kmem_cache_alloc(cp->cache_bufctl_cache, kmflag);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1581
			if (bcp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1582
				goto bufctl_alloc_failure;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1583
			if (cache_flags & KMF_AUDIT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1584
				kmem_bufctl_audit_t *bcap =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1585
				    (kmem_bufctl_audit_t *)bcp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1586
				bzero(bcap, sizeof (kmem_bufctl_audit_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1587
				bcap->bc_cache = cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1588
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1589
			bcp->bc_addr = buf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1590
			bcp->bc_slab = sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1591
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1592
			bcp = KMEM_BUFCTL(cp, buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1593
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1594
		if (cache_flags & KMF_BUFTAG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1595
			kmem_buftag_t *btp = KMEM_BUFTAG(cp, buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1596
			btp->bt_redzone = KMEM_REDZONE_PATTERN;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1597
			btp->bt_bufctl = bcp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1598
			btp->bt_bxstat = (intptr_t)bcp ^ KMEM_BUFTAG_FREE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1599
			if (cache_flags & KMF_DEADBEEF) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1600
				copy_pattern(KMEM_FREE_PATTERN, buf,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1601
				    cp->cache_verify);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1602
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1603
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1604
		bcp->bc_next = sp->slab_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1605
		sp->slab_head = bcp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1606
		buf += chunksize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1607
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1608
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1609
	kmem_log_event(kmem_slab_log, cp, sp, slab);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1610
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1611
	return (sp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1612
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1613
bufctl_alloc_failure:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1614
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1615
	while ((bcp = sp->slab_head) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1616
		sp->slab_head = bcp->bc_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1617
		kmem_cache_free(cp->cache_bufctl_cache, bcp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1618
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1619
	kmem_cache_free(kmem_slab_cache, sp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1620
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1621
slab_alloc_failure:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1622
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1623
	vmem_free(vmp, slab, slabsize);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1624
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1625
vmem_alloc_failure:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1626
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1627
	kmem_log_event(kmem_failure_log, cp, NULL, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1628
	atomic_add_64(&cp->cache_alloc_fail, 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1629
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1630
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1631
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1632
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1633
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1634
 * Destroy a slab.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1635
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1636
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1637
kmem_slab_destroy(kmem_cache_t *cp, kmem_slab_t *sp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1638
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1639
	vmem_t *vmp = cp->cache_arena;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1640
	void *slab = (void *)P2ALIGN((uintptr_t)sp->slab_base, vmp->vm_quantum);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1641
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1642
	ASSERT(MUTEX_NOT_HELD(&cp->cache_lock));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1643
	ASSERT(sp->slab_refcnt == 0);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1644
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1645
	if (cp->cache_flags & KMF_HASH) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1646
		kmem_bufctl_t *bcp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1647
		while ((bcp = sp->slab_head) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1648
			sp->slab_head = bcp->bc_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1649
			kmem_cache_free(cp->cache_bufctl_cache, bcp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1650
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1651
		kmem_cache_free(kmem_slab_cache, sp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1652
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1653
	vmem_free(vmp, slab, cp->cache_slabsize);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1654
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1655
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1656
static void *
12093
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1657
kmem_slab_alloc_impl(kmem_cache_t *cp, kmem_slab_t *sp, boolean_t prefill)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1658
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1659
	kmem_bufctl_t *bcp, **hash_bucket;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1660
	void *buf;
12093
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1661
	boolean_t new_slab = (sp->slab_refcnt == 0);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1662
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1663
	ASSERT(MUTEX_HELD(&cp->cache_lock));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1664
	/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1665
	 * kmem_slab_alloc() drops cache_lock when it creates a new slab, so we
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1666
	 * can't ASSERT(avl_is_empty(&cp->cache_partial_slabs)) here when the
12093
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1667
	 * slab is newly created.
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1668
	 */
12093
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1669
	ASSERT(new_slab || (KMEM_SLAB_IS_PARTIAL(sp) &&
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1670
	    (sp == avl_first(&cp->cache_partial_slabs))));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1671
	ASSERT(sp->slab_cache == cp);
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1672
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1673
	cp->cache_slab_alloc++;
6306
ecac2262dc70 6675361 kmem_cache_kstat_update() is hot on large servers
tomee
parents: 3448
diff changeset
  1674
	cp->cache_bufslab--;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1675
	sp->slab_refcnt++;
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1676
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1677
	bcp = sp->slab_head;
12093
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1678
	sp->slab_head = bcp->bc_next;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1679
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1680
	if (cp->cache_flags & KMF_HASH) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1681
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1682
		 * Add buffer to allocated-address hash table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1683
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1684
		buf = bcp->bc_addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1685
		hash_bucket = KMEM_HASH(cp, buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1686
		bcp->bc_next = *hash_bucket;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1687
		*hash_bucket = bcp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1688
		if ((cp->cache_flags & (KMF_AUDIT | KMF_BUFTAG)) == KMF_AUDIT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1689
			KMEM_AUDIT(kmem_transaction_log, cp, bcp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1690
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1691
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1692
		buf = KMEM_BUF(cp, bcp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1693
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1694
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1695
	ASSERT(KMEM_SLAB_MEMBER(sp, buf));
12093
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1696
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1697
	if (sp->slab_head == NULL) {
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1698
		ASSERT(KMEM_SLAB_IS_ALL_USED(sp));
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1699
		if (new_slab) {
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1700
			ASSERT(sp->slab_chunks == 1);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1701
		} else {
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1702
			ASSERT(sp->slab_chunks > 1); /* the slab was partial */
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1703
			avl_remove(&cp->cache_partial_slabs, sp);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1704
			sp->slab_later_count = 0; /* clear history */
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1705
			sp->slab_flags &= ~KMEM_SLAB_NOMOVE;
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1706
			sp->slab_stuck_offset = (uint32_t)-1;
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1707
		}
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1708
		list_insert_head(&cp->cache_complete_slabs, sp);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1709
		cp->cache_complete_slab_count++;
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1710
		return (buf);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1711
	}
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1712
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1713
	ASSERT(KMEM_SLAB_IS_PARTIAL(sp));
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1714
	/*
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1715
	 * Peek to see if the magazine layer is enabled before
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1716
	 * we prefill.  We're not holding the cpu cache lock,
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1717
	 * so the peek could be wrong, but there's no harm in it.
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1718
	 */
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1719
	if (new_slab && prefill && (cp->cache_flags & KMF_PREFILL) &&
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1720
	    (KMEM_CPU_CACHE(cp)->cc_magsize != 0))  {
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1721
		kmem_slab_prefill(cp, sp);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1722
		return (buf);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1723
	}
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1724
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1725
	if (new_slab) {
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1726
		avl_add(&cp->cache_partial_slabs, sp);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1727
		return (buf);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1728
	}
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1729
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1730
	/*
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1731
	 * The slab is now more allocated than it was, so the
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1732
	 * order remains unchanged.
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1733
	 */
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1734
	ASSERT(!avl_update(&cp->cache_partial_slabs, sp));
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1735
	return (buf);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1736
}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1737
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1738
/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1739
 * Allocate a raw (unconstructed) buffer from cp's slab layer.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1740
 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1741
static void *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1742
kmem_slab_alloc(kmem_cache_t *cp, int kmflag)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1743
{
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1744
	kmem_slab_t *sp;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1745
	void *buf;
7546
b7eb4c89d3a0 6738434 kmem_check_destructor() introduces binary compatibility issue
Tom Erickson <tomee@eng.sun.com>
parents: 6908
diff changeset
  1746
	boolean_t test_destructor;
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1747
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1748
	mutex_enter(&cp->cache_lock);
7546
b7eb4c89d3a0 6738434 kmem_check_destructor() introduces binary compatibility issue
Tom Erickson <tomee@eng.sun.com>
parents: 6908
diff changeset
  1749
	test_destructor = (cp->cache_slab_alloc == 0);
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1750
	sp = avl_first(&cp->cache_partial_slabs);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1751
	if (sp == NULL) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1752
		ASSERT(cp->cache_bufslab == 0);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1753
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1754
		/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1755
		 * The freelist is empty.  Create a new slab.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1756
		 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1757
		mutex_exit(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1758
		if ((sp = kmem_slab_create(cp, kmflag)) == NULL) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1759
			return (NULL);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1760
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1761
		mutex_enter(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1762
		cp->cache_slab_create++;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1763
		if ((cp->cache_buftotal += sp->slab_chunks) > cp->cache_bufmax)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1764
			cp->cache_bufmax = cp->cache_buftotal;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1765
		cp->cache_bufslab += sp->slab_chunks;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1766
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1767
12093
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  1768
	buf = kmem_slab_alloc_impl(cp, sp, B_TRUE);
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1769
	ASSERT((cp->cache_slab_create - cp->cache_slab_destroy) ==
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1770
	    (cp->cache_complete_slab_count +
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1771
	    avl_numnodes(&cp->cache_partial_slabs) +
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1772
	    (cp->cache_defrag == NULL ? 0 : cp->cache_defrag->kmd_deadcount)));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1773
	mutex_exit(&cp->cache_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1774
7546
b7eb4c89d3a0 6738434 kmem_check_destructor() introduces binary compatibility issue
Tom Erickson <tomee@eng.sun.com>
parents: 6908
diff changeset
  1775
	if (test_destructor && cp->cache_destructor != NULL) {
b7eb4c89d3a0 6738434 kmem_check_destructor() introduces binary compatibility issue
Tom Erickson <tomee@eng.sun.com>
parents: 6908
diff changeset
  1776
		/*
b7eb4c89d3a0 6738434 kmem_check_destructor() introduces binary compatibility issue
Tom Erickson <tomee@eng.sun.com>
parents: 6908
diff changeset
  1777
		 * On the first kmem_slab_alloc(), assert that it is valid to
b7eb4c89d3a0 6738434 kmem_check_destructor() introduces binary compatibility issue
Tom Erickson <tomee@eng.sun.com>
parents: 6908
diff changeset
  1778
		 * call the destructor on a newly constructed object without any
b7eb4c89d3a0 6738434 kmem_check_destructor() introduces binary compatibility issue
Tom Erickson <tomee@eng.sun.com>
parents: 6908
diff changeset
  1779
		 * client involvement.
b7eb4c89d3a0 6738434 kmem_check_destructor() introduces binary compatibility issue
Tom Erickson <tomee@eng.sun.com>
parents: 6908
diff changeset
  1780
		 */
b7eb4c89d3a0 6738434 kmem_check_destructor() introduces binary compatibility issue
Tom Erickson <tomee@eng.sun.com>
parents: 6908
diff changeset
  1781
		if ((cp->cache_constructor == NULL) ||
b7eb4c89d3a0 6738434 kmem_check_destructor() introduces binary compatibility issue
Tom Erickson <tomee@eng.sun.com>
parents: 6908
diff changeset
  1782
		    cp->cache_constructor(buf, cp->cache_private,
b7eb4c89d3a0 6738434 kmem_check_destructor() introduces binary compatibility issue
Tom Erickson <tomee@eng.sun.com>
parents: 6908
diff changeset
  1783
		    kmflag) == 0) {
b7eb4c89d3a0 6738434 kmem_check_destructor() introduces binary compatibility issue
Tom Erickson <tomee@eng.sun.com>
parents: 6908
diff changeset
  1784
			cp->cache_destructor(buf, cp->cache_private);
b7eb4c89d3a0 6738434 kmem_check_destructor() introduces binary compatibility issue
Tom Erickson <tomee@eng.sun.com>
parents: 6908
diff changeset
  1785
		}
b7eb4c89d3a0 6738434 kmem_check_destructor() introduces binary compatibility issue
Tom Erickson <tomee@eng.sun.com>
parents: 6908
diff changeset
  1786
		copy_pattern(KMEM_UNINITIALIZED_PATTERN, buf,
b7eb4c89d3a0 6738434 kmem_check_destructor() introduces binary compatibility issue
Tom Erickson <tomee@eng.sun.com>
parents: 6908
diff changeset
  1787
		    cp->cache_bufsize);
b7eb4c89d3a0 6738434 kmem_check_destructor() introduces binary compatibility issue
Tom Erickson <tomee@eng.sun.com>
parents: 6908
diff changeset
  1788
		if (cp->cache_flags & KMF_DEADBEEF) {
b7eb4c89d3a0 6738434 kmem_check_destructor() introduces binary compatibility issue
Tom Erickson <tomee@eng.sun.com>
parents: 6908
diff changeset
  1789
			copy_pattern(KMEM_FREE_PATTERN, buf, cp->cache_verify);
b7eb4c89d3a0 6738434 kmem_check_destructor() introduces binary compatibility issue
Tom Erickson <tomee@eng.sun.com>
parents: 6908
diff changeset
  1790
		}
b7eb4c89d3a0 6738434 kmem_check_destructor() introduces binary compatibility issue
Tom Erickson <tomee@eng.sun.com>
parents: 6908
diff changeset
  1791
	}
b7eb4c89d3a0 6738434 kmem_check_destructor() introduces binary compatibility issue
Tom Erickson <tomee@eng.sun.com>
parents: 6908
diff changeset
  1792
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1793
	return (buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1794
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1795
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1796
static void kmem_slab_move_yes(kmem_cache_t *, kmem_slab_t *, void *);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1797
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1798
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1799
 * Free a raw (unconstructed) buffer to cp's slab layer.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1800
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1801
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1802
kmem_slab_free(kmem_cache_t *cp, void *buf)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1803
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1804
	kmem_slab_t *sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1805
	kmem_bufctl_t *bcp, **prev_bcpp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1806
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1807
	ASSERT(buf != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1808
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1809
	mutex_enter(&cp->cache_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1810
	cp->cache_slab_free++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1811
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1812
	if (cp->cache_flags & KMF_HASH) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1813
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1814
		 * Look up buffer in allocated-address hash table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1815
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1816
		prev_bcpp = KMEM_HASH(cp, buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1817
		while ((bcp = *prev_bcpp) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1818
			if (bcp->bc_addr == buf) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1819
				*prev_bcpp = bcp->bc_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1820
				sp = bcp->bc_slab;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1821
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1822
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1823
			cp->cache_lookup_depth++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1824
			prev_bcpp = &bcp->bc_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1825
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1826
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1827
		bcp = KMEM_BUFCTL(cp, buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1828
		sp = KMEM_SLAB(cp, buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1829
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1830
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1831
	if (bcp == NULL || sp->slab_cache != cp || !KMEM_SLAB_MEMBER(sp, buf)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1832
		mutex_exit(&cp->cache_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1833
		kmem_error(KMERR_BADADDR, cp, buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1834
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1835
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1836
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1837
	if (KMEM_SLAB_OFFSET(sp, buf) == sp->slab_stuck_offset) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1838
		/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1839
		 * If this is the buffer that prevented the consolidator from
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1840
		 * clearing the slab, we can reset the slab flags now that the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1841
		 * buffer is freed. (It makes sense to do this in
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1842
		 * kmem_cache_free(), where the client gives up ownership of the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1843
		 * buffer, but on the hot path the test is too expensive.)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1844
		 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1845
		kmem_slab_move_yes(cp, sp, buf);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1846
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1847
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1848
	if ((cp->cache_flags & (KMF_AUDIT | KMF_BUFTAG)) == KMF_AUDIT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1849
		if (cp->cache_flags & KMF_CONTENTS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1850
			((kmem_bufctl_audit_t *)bcp)->bc_contents =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1851
			    kmem_log_enter(kmem_content_log, buf,
6306
ecac2262dc70 6675361 kmem_cache_kstat_update() is hot on large servers
tomee
parents: 3448
diff changeset
  1852
			    cp->cache_contents);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1853
		KMEM_AUDIT(kmem_transaction_log, cp, bcp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1854
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1855
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1856
	bcp->bc_next = sp->slab_head;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1857
	sp->slab_head = bcp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1858
6306
ecac2262dc70 6675361 kmem_cache_kstat_update() is hot on large servers
tomee
parents: 3448
diff changeset
  1859
	cp->cache_bufslab++;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1860
	ASSERT(sp->slab_refcnt >= 1);
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1861
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1862
	if (--sp->slab_refcnt == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1863
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1864
		 * There are no outstanding allocations from this slab,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1865
		 * so we can reclaim the memory.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1866
		 */
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1867
		if (sp->slab_chunks == 1) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1868
			list_remove(&cp->cache_complete_slabs, sp);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1869
			cp->cache_complete_slab_count--;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1870
		} else {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1871
			avl_remove(&cp->cache_partial_slabs, sp);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1872
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1873
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1874
		cp->cache_buftotal -= sp->slab_chunks;
6306
ecac2262dc70 6675361 kmem_cache_kstat_update() is hot on large servers
tomee
parents: 3448
diff changeset
  1875
		cp->cache_bufslab -= sp->slab_chunks;
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1876
		/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1877
		 * Defer releasing the slab to the virtual memory subsystem
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1878
		 * while there is a pending move callback, since we guarantee
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1879
		 * that buffers passed to the move callback have only been
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1880
		 * touched by kmem or by the client itself. Since the memory
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1881
		 * patterns baddcafe (uninitialized) and deadbeef (freed) both
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1882
		 * set at least one of the two lowest order bits, the client can
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1883
		 * test those bits in the move callback to determine whether or
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1884
		 * not it knows about the buffer (assuming that the client also
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1885
		 * sets one of those low order bits whenever it frees a buffer).
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1886
		 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1887
		if (cp->cache_defrag == NULL ||
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1888
		    (avl_is_empty(&cp->cache_defrag->kmd_moves_pending) &&
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1889
		    !(sp->slab_flags & KMEM_SLAB_MOVE_PENDING))) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1890
			cp->cache_slab_destroy++;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1891
			mutex_exit(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1892
			kmem_slab_destroy(cp, sp);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1893
		} else {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1894
			list_t *deadlist = &cp->cache_defrag->kmd_deadlist;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1895
			/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1896
			 * Slabs are inserted at both ends of the deadlist to
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1897
			 * distinguish between slabs freed while move callbacks
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1898
			 * are pending (list head) and a slab freed while the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1899
			 * lock is dropped in kmem_move_buffers() (list tail) so
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1900
			 * that in both cases slab_destroy() is called from the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1901
			 * right context.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1902
			 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1903
			if (sp->slab_flags & KMEM_SLAB_MOVE_PENDING) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1904
				list_insert_tail(deadlist, sp);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1905
			} else {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1906
				list_insert_head(deadlist, sp);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1907
			}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1908
			cp->cache_defrag->kmd_deadcount++;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1909
			mutex_exit(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1910
		}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1911
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1912
	}
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1913
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1914
	if (bcp->bc_next == NULL) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1915
		/* Transition the slab from completely allocated to partial. */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1916
		ASSERT(sp->slab_refcnt == (sp->slab_chunks - 1));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1917
		ASSERT(sp->slab_chunks > 1);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1918
		list_remove(&cp->cache_complete_slabs, sp);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1919
		cp->cache_complete_slab_count--;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1920
		avl_add(&cp->cache_partial_slabs, sp);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1921
	} else {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1922
#ifdef	DEBUG
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1923
		if (avl_update_gt(&cp->cache_partial_slabs, sp)) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1924
			KMEM_STAT_ADD(kmem_move_stats.kms_avl_update);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1925
		} else {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1926
			KMEM_STAT_ADD(kmem_move_stats.kms_avl_noupdate);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1927
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1928
#else
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1929
		(void) avl_update_gt(&cp->cache_partial_slabs, sp);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1930
#endif
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1931
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1932
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1933
	ASSERT((cp->cache_slab_create - cp->cache_slab_destroy) ==
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1934
	    (cp->cache_complete_slab_count +
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1935
	    avl_numnodes(&cp->cache_partial_slabs) +
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1936
	    (cp->cache_defrag == NULL ? 0 : cp->cache_defrag->kmd_deadcount)));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1937
	mutex_exit(&cp->cache_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1938
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1939
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1940
/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1941
 * Return -1 if kmem_error, 1 if constructor fails, 0 if successful.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  1942
 */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1943
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1944
kmem_cache_alloc_debug(kmem_cache_t *cp, void *buf, int kmflag, int construct,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1945
    caddr_t caller)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1946
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1947
	kmem_buftag_t *btp = KMEM_BUFTAG(cp, buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1948
	kmem_bufctl_audit_t *bcp = (kmem_bufctl_audit_t *)btp->bt_bufctl;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1949
	uint32_t mtbf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1950
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1951
	if (btp->bt_bxstat != ((intptr_t)bcp ^ KMEM_BUFTAG_FREE)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1952
		kmem_error(KMERR_BADBUFTAG, cp, buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1953
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1954
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1955
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1956
	btp->bt_bxstat = (intptr_t)bcp ^ KMEM_BUFTAG_ALLOC;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1957
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1958
	if ((cp->cache_flags & KMF_HASH) && bcp->bc_addr != buf) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1959
		kmem_error(KMERR_BADBUFCTL, cp, buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1960
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1961
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1962
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1963
	if (cp->cache_flags & KMF_DEADBEEF) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1964
		if (!construct && (cp->cache_flags & KMF_LITE)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1965
			if (*(uint64_t *)buf != KMEM_FREE_PATTERN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1966
				kmem_error(KMERR_MODIFIED, cp, buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1967
				return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1968
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1969
			if (cp->cache_constructor != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1970
				*(uint64_t *)buf = btp->bt_redzone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1971
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1972
				*(uint64_t *)buf = KMEM_UNINITIALIZED_PATTERN;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1973
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1974
			construct = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1975
			if (verify_and_copy_pattern(KMEM_FREE_PATTERN,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1976
			    KMEM_UNINITIALIZED_PATTERN, buf,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1977
			    cp->cache_verify)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1978
				kmem_error(KMERR_MODIFIED, cp, buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1979
				return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1980
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1981
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1982
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1983
	btp->bt_redzone = KMEM_REDZONE_PATTERN;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1984
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1985
	if ((mtbf = kmem_mtbf | cp->cache_mtbf) != 0 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1986
	    gethrtime() % mtbf == 0 &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1987
	    (kmflag & (KM_NOSLEEP | KM_PANIC)) == KM_NOSLEEP) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1988
		kmem_log_event(kmem_failure_log, cp, NULL, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1989
		if (!construct && cp->cache_destructor != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1990
			cp->cache_destructor(buf, cp->cache_private);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1991
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1992
		mtbf = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1993
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1994
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1995
	if (mtbf || (construct && cp->cache_constructor != NULL &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1996
	    cp->cache_constructor(buf, cp->cache_private, kmflag) != 0)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1997
		atomic_add_64(&cp->cache_alloc_fail, 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1998
		btp->bt_bxstat = (intptr_t)bcp ^ KMEM_BUFTAG_FREE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1999
		if (cp->cache_flags & KMF_DEADBEEF)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2000
			copy_pattern(KMEM_FREE_PATTERN, buf, cp->cache_verify);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2001
		kmem_slab_free(cp, buf);
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2002
		return (1);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2003
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2004
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2005
	if (cp->cache_flags & KMF_AUDIT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2006
		KMEM_AUDIT(kmem_transaction_log, cp, bcp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2007
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2008
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2009
	if ((cp->cache_flags & KMF_LITE) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2010
	    !(cp->cache_cflags & KMC_KMEM_ALLOC)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2011
		KMEM_BUFTAG_LITE_ENTER(btp, kmem_lite_count, caller);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2012
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2013
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2014
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2015
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2016
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2017
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2018
kmem_cache_free_debug(kmem_cache_t *cp, void *buf, caddr_t caller)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2019
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2020
	kmem_buftag_t *btp = KMEM_BUFTAG(cp, buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2021
	kmem_bufctl_audit_t *bcp = (kmem_bufctl_audit_t *)btp->bt_bufctl;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2022
	kmem_slab_t *sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2023
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2024
	if (btp->bt_bxstat != ((intptr_t)bcp ^ KMEM_BUFTAG_ALLOC)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2025
		if (btp->bt_bxstat == ((intptr_t)bcp ^ KMEM_BUFTAG_FREE)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2026
			kmem_error(KMERR_DUPFREE, cp, buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2027
			return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2028
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2029
		sp = kmem_findslab(cp, buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2030
		if (sp == NULL || sp->slab_cache != cp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2031
			kmem_error(KMERR_BADADDR, cp, buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2032
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2033
			kmem_error(KMERR_REDZONE, cp, buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2034
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2035
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2036
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2037
	btp->bt_bxstat = (intptr_t)bcp ^ KMEM_BUFTAG_FREE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2038
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2039
	if ((cp->cache_flags & KMF_HASH) && bcp->bc_addr != buf) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2040
		kmem_error(KMERR_BADBUFCTL, cp, buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2041
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2042
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2043
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2044
	if (btp->bt_redzone != KMEM_REDZONE_PATTERN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2045
		kmem_error(KMERR_REDZONE, cp, buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2046
		return (-1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2047
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2048
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2049
	if (cp->cache_flags & KMF_AUDIT) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2050
		if (cp->cache_flags & KMF_CONTENTS)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2051
			bcp->bc_contents = kmem_log_enter(kmem_content_log,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2052
			    buf, cp->cache_contents);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2053
		KMEM_AUDIT(kmem_transaction_log, cp, bcp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2054
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2055
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2056
	if ((cp->cache_flags & KMF_LITE) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2057
	    !(cp->cache_cflags & KMC_KMEM_ALLOC)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2058
		KMEM_BUFTAG_LITE_ENTER(btp, kmem_lite_count, caller);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2059
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2060
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2061
	if (cp->cache_flags & KMF_DEADBEEF) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2062
		if (cp->cache_flags & KMF_LITE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2063
			btp->bt_redzone = *(uint64_t *)buf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2064
		else if (cp->cache_destructor != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2065
			cp->cache_destructor(buf, cp->cache_private);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2066
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2067
		copy_pattern(KMEM_FREE_PATTERN, buf, cp->cache_verify);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2068
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2069
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2070
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2071
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2072
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2073
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2074
 * Free each object in magazine mp to cp's slab layer, and free mp itself.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2075
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2076
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2077
kmem_magazine_destroy(kmem_cache_t *cp, kmem_magazine_t *mp, int nrounds)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2078
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2079
	int round;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2080
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2081
	ASSERT(!list_link_active(&cp->cache_link) ||
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2082
	    taskq_member(kmem_taskq, curthread));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2083
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2084
	for (round = 0; round < nrounds; round++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2085
		void *buf = mp->mag_round[round];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2086
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2087
		if (cp->cache_flags & KMF_DEADBEEF) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2088
			if (verify_pattern(KMEM_FREE_PATTERN, buf,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2089
			    cp->cache_verify) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2090
				kmem_error(KMERR_MODIFIED, cp, buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2091
				continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2092
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2093
			if ((cp->cache_flags & KMF_LITE) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2094
			    cp->cache_destructor != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2095
				kmem_buftag_t *btp = KMEM_BUFTAG(cp, buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2096
				*(uint64_t *)buf = btp->bt_redzone;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2097
				cp->cache_destructor(buf, cp->cache_private);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2098
				*(uint64_t *)buf = KMEM_FREE_PATTERN;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2099
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2100
		} else if (cp->cache_destructor != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2101
			cp->cache_destructor(buf, cp->cache_private);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2102
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2103
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2104
		kmem_slab_free(cp, buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2105
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2106
	ASSERT(KMEM_MAGAZINE_VALID(cp, mp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2107
	kmem_cache_free(cp->cache_magtype->mt_cache, mp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2108
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2109
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2110
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2111
 * Allocate a magazine from the depot.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2112
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2113
static kmem_magazine_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2114
kmem_depot_alloc(kmem_cache_t *cp, kmem_maglist_t *mlp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2115
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2116
	kmem_magazine_t *mp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2117
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2118
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2119
	 * If we can't get the depot lock without contention,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2120
	 * update our contention count.  We use the depot
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2121
	 * contention rate to determine whether we need to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2122
	 * increase the magazine size for better scalability.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2123
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2124
	if (!mutex_tryenter(&cp->cache_depot_lock)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2125
		mutex_enter(&cp->cache_depot_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2126
		cp->cache_depot_contention++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2127
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2128
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2129
	if ((mp = mlp->ml_list) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2130
		ASSERT(KMEM_MAGAZINE_VALID(cp, mp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2131
		mlp->ml_list = mp->mag_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2132
		if (--mlp->ml_total < mlp->ml_min)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2133
			mlp->ml_min = mlp->ml_total;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2134
		mlp->ml_alloc++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2135
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2136
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2137
	mutex_exit(&cp->cache_depot_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2138
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2139
	return (mp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2140
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2141
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2142
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2143
 * Free a magazine to the depot.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2144
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2145
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2146
kmem_depot_free(kmem_cache_t *cp, kmem_maglist_t *mlp, kmem_magazine_t *mp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2147
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2148
	mutex_enter(&cp->cache_depot_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2149
	ASSERT(KMEM_MAGAZINE_VALID(cp, mp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2150
	mp->mag_next = mlp->ml_list;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2151
	mlp->ml_list = mp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2152
	mlp->ml_total++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2153
	mutex_exit(&cp->cache_depot_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2154
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2155
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2156
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2157
 * Update the working set statistics for cp's depot.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2158
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2159
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2160
kmem_depot_ws_update(kmem_cache_t *cp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2161
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2162
	mutex_enter(&cp->cache_depot_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2163
	cp->cache_full.ml_reaplimit = cp->cache_full.ml_min;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2164
	cp->cache_full.ml_min = cp->cache_full.ml_total;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2165
	cp->cache_empty.ml_reaplimit = cp->cache_empty.ml_min;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2166
	cp->cache_empty.ml_min = cp->cache_empty.ml_total;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2167
	mutex_exit(&cp->cache_depot_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2168
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2169
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2170
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2171
 * Reap all magazines that have fallen out of the depot's working set.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2172
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2173
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2174
kmem_depot_ws_reap(kmem_cache_t *cp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2175
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2176
	long reap;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2177
	kmem_magazine_t *mp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2178
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2179
	ASSERT(!list_link_active(&cp->cache_link) ||
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2180
	    taskq_member(kmem_taskq, curthread));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2181
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2182
	reap = MIN(cp->cache_full.ml_reaplimit, cp->cache_full.ml_min);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2183
	while (reap-- && (mp = kmem_depot_alloc(cp, &cp->cache_full)) != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2184
		kmem_magazine_destroy(cp, mp, cp->cache_magtype->mt_magsize);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2185
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2186
	reap = MIN(cp->cache_empty.ml_reaplimit, cp->cache_empty.ml_min);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2187
	while (reap-- && (mp = kmem_depot_alloc(cp, &cp->cache_empty)) != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2188
		kmem_magazine_destroy(cp, mp, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2189
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2190
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2191
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2192
kmem_cpu_reload(kmem_cpu_cache_t *ccp, kmem_magazine_t *mp, int rounds)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2193
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2194
	ASSERT((ccp->cc_loaded == NULL && ccp->cc_rounds == -1) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2195
	    (ccp->cc_loaded && ccp->cc_rounds + rounds == ccp->cc_magsize));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2196
	ASSERT(ccp->cc_magsize > 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2197
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2198
	ccp->cc_ploaded = ccp->cc_loaded;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2199
	ccp->cc_prounds = ccp->cc_rounds;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2200
	ccp->cc_loaded = mp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2201
	ccp->cc_rounds = rounds;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2202
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2203
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2204
/*
11178
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2205
 * Intercept kmem alloc/free calls during crash dump in order to avoid
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2206
 * changing kmem state while memory is being saved to the dump device.
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2207
 * Otherwise, ::kmem_verify will report "corrupt buffers".  Note that
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2208
 * there are no locks because only one CPU calls kmem during a crash
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2209
 * dump. To enable this feature, first create the associated vmem
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2210
 * arena with VMC_DUMPSAFE.
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2211
 */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2212
static void *kmem_dump_start;	/* start of pre-reserved heap */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2213
static void *kmem_dump_end;	/* end of heap area */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2214
static void *kmem_dump_curr;	/* current free heap pointer */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2215
static size_t kmem_dump_size;	/* size of heap area */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2216
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2217
/* append to each buf created in the pre-reserved heap */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2218
typedef struct kmem_dumpctl {
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2219
	void	*kdc_next;	/* cache dump free list linkage */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2220
} kmem_dumpctl_t;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2221
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2222
#define	KMEM_DUMPCTL(cp, buf)	\
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2223
	((kmem_dumpctl_t *)P2ROUNDUP((uintptr_t)(buf) + (cp)->cache_bufsize, \
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2224
	    sizeof (void *)))
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2225
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2226
/* Keep some simple stats. */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2227
#define	KMEM_DUMP_LOGS	(100)
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2228
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2229
typedef struct kmem_dump_log {
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2230
	kmem_cache_t	*kdl_cache;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2231
	uint_t		kdl_allocs;		/* # of dump allocations */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2232
	uint_t		kdl_frees;		/* # of dump frees */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2233
	uint_t		kdl_alloc_fails;	/* # of allocation failures */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2234
	uint_t		kdl_free_nondump;	/* # of non-dump frees */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2235
	uint_t		kdl_unsafe;		/* cache was used, but unsafe */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2236
} kmem_dump_log_t;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2237
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2238
static kmem_dump_log_t *kmem_dump_log;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2239
static int kmem_dump_log_idx;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2240
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2241
#define	KDI_LOG(cp, stat) {						\
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2242
	kmem_dump_log_t *kdl;						\
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2243
	if ((kdl = (kmem_dump_log_t *)((cp)->cache_dumplog)) != NULL) {	\
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2244
		kdl->stat++;						\
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2245
	} else if (kmem_dump_log_idx < KMEM_DUMP_LOGS) {		\
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2246
		kdl = &kmem_dump_log[kmem_dump_log_idx++];		\
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2247
		kdl->stat++;						\
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2248
		kdl->kdl_cache = (cp);					\
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2249
		(cp)->cache_dumplog = kdl;				\
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2250
	}								\
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2251
}
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2252
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2253
/* set non zero for full report */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2254
uint_t kmem_dump_verbose = 0;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2255
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2256
/* stats for overize heap */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2257
uint_t kmem_dump_oversize_allocs = 0;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2258
uint_t kmem_dump_oversize_max = 0;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2259
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2260
static void
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2261
kmem_dumppr(char **pp, char *e, const char *format, ...)
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2262
{
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2263
	char *p = *pp;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2264
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2265
	if (p < e) {
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2266
		int n;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2267
		va_list ap;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2268
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2269
		va_start(ap, format);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2270
		n = vsnprintf(p, e - p, format, ap);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2271
		va_end(ap);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2272
		*pp = p + n;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2273
	}
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2274
}
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2275
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2276
/*
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2277
 * Called when dumpadm(1M) configures dump parameters.
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2278
 */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2279
void
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2280
kmem_dump_init(size_t size)
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2281
{
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2282
	if (kmem_dump_start != NULL)
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2283
		kmem_free(kmem_dump_start, kmem_dump_size);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2284
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2285
	if (kmem_dump_log == NULL)
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2286
		kmem_dump_log = (kmem_dump_log_t *)kmem_zalloc(KMEM_DUMP_LOGS *
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2287
		    sizeof (kmem_dump_log_t), KM_SLEEP);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2288
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2289
	kmem_dump_start = kmem_alloc(size, KM_SLEEP);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2290
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2291
	if (kmem_dump_start != NULL) {
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2292
		kmem_dump_size = size;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2293
		kmem_dump_curr = kmem_dump_start;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2294
		kmem_dump_end = (void *)((char *)kmem_dump_start + size);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2295
		copy_pattern(KMEM_UNINITIALIZED_PATTERN, kmem_dump_start, size);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2296
	} else {
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2297
		kmem_dump_size = 0;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2298
		kmem_dump_curr = NULL;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2299
		kmem_dump_end = NULL;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2300
	}
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2301
}
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2302
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2303
/*
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2304
 * Set flag for each kmem_cache_t if is safe to use alternate dump
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2305
 * memory. Called just before panic crash dump starts. Set the flag
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2306
 * for the calling CPU.
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2307
 */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2308
void
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2309
kmem_dump_begin(void)
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2310
{
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2311
	ASSERT(panicstr != NULL);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2312
	if (kmem_dump_start != NULL) {
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2313
		kmem_cache_t *cp;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2314
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2315
		for (cp = list_head(&kmem_caches); cp != NULL;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2316
		    cp = list_next(&kmem_caches, cp)) {
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2317
			kmem_cpu_cache_t *ccp = KMEM_CPU_CACHE(cp);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2318
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2319
			if (cp->cache_arena->vm_cflags & VMC_DUMPSAFE) {
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2320
				cp->cache_flags |= KMF_DUMPDIVERT;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2321
				ccp->cc_flags |= KMF_DUMPDIVERT;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2322
				ccp->cc_dump_rounds = ccp->cc_rounds;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2323
				ccp->cc_dump_prounds = ccp->cc_prounds;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2324
				ccp->cc_rounds = ccp->cc_prounds = -1;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2325
			} else {
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2326
				cp->cache_flags |= KMF_DUMPUNSAFE;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2327
				ccp->cc_flags |= KMF_DUMPUNSAFE;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2328
			}
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2329
		}
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2330
	}
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2331
}
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2332
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2333
/*
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2334
 * finished dump intercept
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2335
 * print any warnings on the console
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2336
 * return verbose information to dumpsys() in the given buffer
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2337
 */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2338
size_t
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2339
kmem_dump_finish(char *buf, size_t size)
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2340
{
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2341
	int kdi_idx;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2342
	int kdi_end = kmem_dump_log_idx;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2343
	int percent = 0;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2344
	int header = 0;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2345
	int warn = 0;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2346
	size_t used;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2347
	kmem_cache_t *cp;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2348
	kmem_dump_log_t *kdl;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2349
	char *e = buf + size;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2350
	char *p = buf;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2351
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2352
	if (kmem_dump_size == 0 || kmem_dump_verbose == 0)
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2353
		return (0);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2354
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2355
	used = (char *)kmem_dump_curr - (char *)kmem_dump_start;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2356
	percent = (used * 100) / kmem_dump_size;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2357
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2358
	kmem_dumppr(&p, e, "%% heap used,%d\n", percent);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2359
	kmem_dumppr(&p, e, "used bytes,%ld\n", used);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2360
	kmem_dumppr(&p, e, "heap size,%ld\n", kmem_dump_size);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2361
	kmem_dumppr(&p, e, "Oversize allocs,%d\n",
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2362
	    kmem_dump_oversize_allocs);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2363
	kmem_dumppr(&p, e, "Oversize max size,%ld\n",
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2364
	    kmem_dump_oversize_max);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2365
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2366
	for (kdi_idx = 0; kdi_idx < kdi_end; kdi_idx++) {
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2367
		kdl = &kmem_dump_log[kdi_idx];
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2368
		cp = kdl->kdl_cache;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2369
		if (cp == NULL)
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2370
			break;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2371
		if (kdl->kdl_alloc_fails)
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2372
			++warn;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2373
		if (header == 0) {
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2374
			kmem_dumppr(&p, e,
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2375
			    "Cache Name,Allocs,Frees,Alloc Fails,"
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2376
			    "Nondump Frees,Unsafe Allocs/Frees\n");
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2377
			header = 1;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2378
		}
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2379
		kmem_dumppr(&p, e, "%s,%d,%d,%d,%d,%d\n",
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2380
		    cp->cache_name, kdl->kdl_allocs, kdl->kdl_frees,
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2381
		    kdl->kdl_alloc_fails, kdl->kdl_free_nondump,
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2382
		    kdl->kdl_unsafe);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2383
	}
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2384
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2385
	/* return buffer size used */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2386
	if (p < e)
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2387
		bzero(p, e - p);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2388
	return (p - buf);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2389
}
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2390
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2391
/*
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2392
 * Allocate a constructed object from alternate dump memory.
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2393
 */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2394
void *
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2395
kmem_cache_alloc_dump(kmem_cache_t *cp, int kmflag)
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2396
{
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2397
	void *buf;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2398
	void *curr;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2399
	char *bufend;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2400
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2401
	/* return a constructed object */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2402
	if ((buf = cp->cache_dumpfreelist) != NULL) {
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2403
		cp->cache_dumpfreelist = KMEM_DUMPCTL(cp, buf)->kdc_next;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2404
		KDI_LOG(cp, kdl_allocs);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2405
		return (buf);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2406
	}
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2407
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2408
	/* create a new constructed object */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2409
	curr = kmem_dump_curr;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2410
	buf = (void *)P2ROUNDUP((uintptr_t)curr, cp->cache_align);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2411
	bufend = (char *)KMEM_DUMPCTL(cp, buf) + sizeof (kmem_dumpctl_t);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2412
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2413
	/* hat layer objects cannot cross a page boundary */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2414
	if (cp->cache_align < PAGESIZE) {
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2415
		char *page = (char *)P2ROUNDUP((uintptr_t)buf, PAGESIZE);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2416
		if (bufend > page) {
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2417
			bufend += page - (char *)buf;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2418
			buf = (void *)page;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2419
		}
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2420
	}
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2421
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2422
	/* fall back to normal alloc if reserved area is used up */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2423
	if (bufend > (char *)kmem_dump_end) {
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2424
		kmem_dump_curr = kmem_dump_end;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2425
		KDI_LOG(cp, kdl_alloc_fails);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2426
		return (NULL);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2427
	}
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2428
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2429
	/*
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2430
	 * Must advance curr pointer before calling a constructor that
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2431
	 * may also allocate memory.
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2432
	 */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2433
	kmem_dump_curr = bufend;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2434
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2435
	/* run constructor */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2436
	if (cp->cache_constructor != NULL &&
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2437
	    cp->cache_constructor(buf, cp->cache_private, kmflag)
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2438
	    != 0) {
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2439
#ifdef DEBUG
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2440
		printf("name='%s' cache=0x%p: kmem cache constructor failed\n",
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2441
		    cp->cache_name, (void *)cp);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2442
#endif
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2443
		/* reset curr pointer iff no allocs were done */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2444
		if (kmem_dump_curr == bufend)
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2445
			kmem_dump_curr = curr;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2446
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2447
		/* fall back to normal alloc if the constructor fails */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2448
		KDI_LOG(cp, kdl_alloc_fails);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2449
		return (NULL);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2450
	}
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2451
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2452
	KDI_LOG(cp, kdl_allocs);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2453
	return (buf);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2454
}
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2455
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2456
/*
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2457
 * Free a constructed object in alternate dump memory.
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2458
 */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2459
int
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2460
kmem_cache_free_dump(kmem_cache_t *cp, void *buf)
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2461
{
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2462
	/* save constructed buffers for next time */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2463
	if ((char *)buf >= (char *)kmem_dump_start &&
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2464
	    (char *)buf < (char *)kmem_dump_end) {
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2465
		KMEM_DUMPCTL(cp, buf)->kdc_next = cp->cache_dumpfreelist;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2466
		cp->cache_dumpfreelist = buf;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2467
		KDI_LOG(cp, kdl_frees);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2468
		return (0);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2469
	}
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2470
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2471
	/* count all non-dump buf frees */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2472
	KDI_LOG(cp, kdl_free_nondump);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2473
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2474
	/* just drop buffers that were allocated before dump started */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2475
	if (kmem_dump_curr < kmem_dump_end)
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2476
		return (0);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2477
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2478
	/* fall back to normal free if reserved area is used up */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2479
	return (1);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2480
}
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2481
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2482
/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2483
 * Allocate a constructed object from cache cp.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2484
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2485
void *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2486
kmem_cache_alloc(kmem_cache_t *cp, int kmflag)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2487
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2488
	kmem_cpu_cache_t *ccp = KMEM_CPU_CACHE(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2489
	kmem_magazine_t *fmp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2490
	void *buf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2491
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2492
	mutex_enter(&ccp->cc_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2493
	for (;;) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2494
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2495
		 * If there's an object available in the current CPU's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2496
		 * loaded magazine, just take it and return.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2497
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2498
		if (ccp->cc_rounds > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2499
			buf = ccp->cc_loaded->mag_round[--ccp->cc_rounds];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2500
			ccp->cc_alloc++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2501
			mutex_exit(&ccp->cc_lock);
11178
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2502
			if (ccp->cc_flags & (KMF_BUFTAG | KMF_DUMPUNSAFE)) {
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2503
				if (ccp->cc_flags & KMF_DUMPUNSAFE) {
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2504
					ASSERT(!(ccp->cc_flags &
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2505
					    KMF_DUMPDIVERT));
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2506
					KDI_LOG(cp, kdl_unsafe);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2507
				}
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2508
				if ((ccp->cc_flags & KMF_BUFTAG) &&
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2509
				    kmem_cache_alloc_debug(cp, buf, kmflag, 0,
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2510
				    caller()) != 0) {
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2511
					if (kmflag & KM_NOSLEEP)
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2512
						return (NULL);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2513
					mutex_enter(&ccp->cc_lock);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2514
					continue;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2515
				}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2516
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2517
			return (buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2518
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2519
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2520
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2521
		 * The loaded magazine is empty.  If the previously loaded
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2522
		 * magazine was full, exchange them and try again.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2523
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2524
		if (ccp->cc_prounds > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2525
			kmem_cpu_reload(ccp, ccp->cc_ploaded, ccp->cc_prounds);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2526
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2527
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2528
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2529
		/*
11178
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2530
		 * Return an alternate buffer at dump time to preserve
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2531
		 * the heap.
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2532
		 */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2533
		if (ccp->cc_flags & (KMF_DUMPDIVERT | KMF_DUMPUNSAFE)) {
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2534
			if (ccp->cc_flags & KMF_DUMPUNSAFE) {
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2535
				ASSERT(!(ccp->cc_flags & KMF_DUMPDIVERT));
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2536
				/* log it so that we can warn about it */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2537
				KDI_LOG(cp, kdl_unsafe);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2538
			} else {
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2539
				if ((buf = kmem_cache_alloc_dump(cp, kmflag)) !=
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2540
				    NULL) {
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2541
					mutex_exit(&ccp->cc_lock);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2542
					return (buf);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2543
				}
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2544
				break;		/* fall back to slab layer */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2545
			}
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2546
		}
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2547
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2548
		/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2549
		 * If the magazine layer is disabled, break out now.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2550
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2551
		if (ccp->cc_magsize == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2552
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2553
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2554
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2555
		 * Try to get a full magazine from the depot.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2556
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2557
		fmp = kmem_depot_alloc(cp, &cp->cache_full);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2558
		if (fmp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2559
			if (ccp->cc_ploaded != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2560
				kmem_depot_free(cp, &cp->cache_empty,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2561
				    ccp->cc_ploaded);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2562
			kmem_cpu_reload(ccp, fmp, ccp->cc_magsize);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2563
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2564
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2565
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2566
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2567
		 * There are no full magazines in the depot,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2568
		 * so fall through to the slab layer.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2569
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2570
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2571
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2572
	mutex_exit(&ccp->cc_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2573
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2574
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2575
	 * We couldn't allocate a constructed object from the magazine layer,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2576
	 * so get a raw buffer from the slab layer and apply its constructor.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2577
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2578
	buf = kmem_slab_alloc(cp, kmflag);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2579
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2580
	if (buf == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2581
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2582
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2583
	if (cp->cache_flags & KMF_BUFTAG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2584
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2585
		 * Make kmem_cache_alloc_debug() apply the constructor for us.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2586
		 */
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2587
		int rc = kmem_cache_alloc_debug(cp, buf, kmflag, 1, caller());
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2588
		if (rc != 0) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2589
			if (kmflag & KM_NOSLEEP)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2590
				return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2591
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2592
			 * kmem_cache_alloc_debug() detected corruption
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2593
			 * but didn't panic (kmem_panic <= 0). We should not be
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2594
			 * here because the constructor failed (indicated by a
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2595
			 * return code of 1). Try again.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2596
			 */
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2597
			ASSERT(rc == -1);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2598
			return (kmem_cache_alloc(cp, kmflag));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2599
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2600
		return (buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2601
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2602
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2603
	if (cp->cache_constructor != NULL &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2604
	    cp->cache_constructor(buf, cp->cache_private, kmflag) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2605
		atomic_add_64(&cp->cache_alloc_fail, 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2606
		kmem_slab_free(cp, buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2607
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2608
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2609
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2610
	return (buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2611
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2612
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2613
/*
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2614
 * The freed argument tells whether or not kmem_cache_free_debug() has already
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2615
 * been called so that we can avoid the duplicate free error. For example, a
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2616
 * buffer on a magazine has already been freed by the client but is still
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2617
 * constructed.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2618
 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2619
static void
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2620
kmem_slab_free_constructed(kmem_cache_t *cp, void *buf, boolean_t freed)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2621
{
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2622
	if (!freed && (cp->cache_flags & KMF_BUFTAG))
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2623
		if (kmem_cache_free_debug(cp, buf, caller()) == -1)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2624
			return;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2625
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2626
	/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2627
	 * Note that if KMF_DEADBEEF is in effect and KMF_LITE is not,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2628
	 * kmem_cache_free_debug() will have already applied the destructor.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2629
	 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2630
	if ((cp->cache_flags & (KMF_DEADBEEF | KMF_LITE)) != KMF_DEADBEEF &&
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2631
	    cp->cache_destructor != NULL) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2632
		if (cp->cache_flags & KMF_DEADBEEF) {	/* KMF_LITE implied */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2633
			kmem_buftag_t *btp = KMEM_BUFTAG(cp, buf);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2634
			*(uint64_t *)buf = btp->bt_redzone;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2635
			cp->cache_destructor(buf, cp->cache_private);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2636
			*(uint64_t *)buf = KMEM_FREE_PATTERN;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2637
		} else {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2638
			cp->cache_destructor(buf, cp->cache_private);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2639
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2640
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2641
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2642
	kmem_slab_free(cp, buf);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2643
}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2644
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2645
/*
12093
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2646
 * Used when there's no room to free a buffer to the per-CPU cache.
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2647
 * Drops and re-acquires &ccp->cc_lock, and returns non-zero if the
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2648
 * caller should try freeing to the per-CPU cache again.
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2649
 * Note that we don't directly install the magazine in the cpu cache,
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2650
 * since its state may have changed wildly while the lock was dropped.
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2651
 */
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2652
static int
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2653
kmem_cpucache_magazine_alloc(kmem_cpu_cache_t *ccp, kmem_cache_t *cp)
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2654
{
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2655
	kmem_magazine_t *emp;
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2656
	kmem_magtype_t *mtp;
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2657
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2658
	ASSERT(MUTEX_HELD(&ccp->cc_lock));
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2659
	ASSERT(((uint_t)ccp->cc_rounds == ccp->cc_magsize ||
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2660
	    ((uint_t)ccp->cc_rounds == -1)) &&
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2661
	    ((uint_t)ccp->cc_prounds == ccp->cc_magsize ||
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2662
	    ((uint_t)ccp->cc_prounds == -1)));
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2663
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2664
	emp = kmem_depot_alloc(cp, &cp->cache_empty);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2665
	if (emp != NULL) {
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2666
		if (ccp->cc_ploaded != NULL)
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2667
			kmem_depot_free(cp, &cp->cache_full,
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2668
			    ccp->cc_ploaded);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2669
		kmem_cpu_reload(ccp, emp, 0);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2670
		return (1);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2671
	}
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2672
	/*
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2673
	 * There are no empty magazines in the depot,
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2674
	 * so try to allocate a new one.  We must drop all locks
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2675
	 * across kmem_cache_alloc() because lower layers may
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2676
	 * attempt to allocate from this cache.
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2677
	 */
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2678
	mtp = cp->cache_magtype;
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2679
	mutex_exit(&ccp->cc_lock);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2680
	emp = kmem_cache_alloc(mtp->mt_cache, KM_NOSLEEP);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2681
	mutex_enter(&ccp->cc_lock);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2682
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2683
	if (emp != NULL) {
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2684
		/*
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2685
		 * We successfully allocated an empty magazine.
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2686
		 * However, we had to drop ccp->cc_lock to do it,
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2687
		 * so the cache's magazine size may have changed.
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2688
		 * If so, free the magazine and try again.
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2689
		 */
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2690
		if (ccp->cc_magsize != mtp->mt_magsize) {
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2691
			mutex_exit(&ccp->cc_lock);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2692
			kmem_cache_free(mtp->mt_cache, emp);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2693
			mutex_enter(&ccp->cc_lock);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2694
			return (1);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2695
		}
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2696
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2697
		/*
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2698
		 * We got a magazine of the right size.  Add it to
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2699
		 * the depot and try the whole dance again.
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2700
		 */
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2701
		kmem_depot_free(cp, &cp->cache_empty, emp);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2702
		return (1);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2703
	}
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2704
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2705
	/*
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2706
	 * We couldn't allocate an empty magazine,
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2707
	 * so fall through to the slab layer.
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2708
	 */
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2709
	return (0);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2710
}
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2711
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2712
/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2713
 * Free a constructed object to cache cp.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2714
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2715
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2716
kmem_cache_free(kmem_cache_t *cp, void *buf)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2717
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2718
	kmem_cpu_cache_t *ccp = KMEM_CPU_CACHE(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2719
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2720
	/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2721
	 * The client must not free either of the buffers passed to the move
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2722
	 * callback function.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2723
	 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2724
	ASSERT(cp->cache_defrag == NULL ||
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2725
	    cp->cache_defrag->kmd_thread != curthread ||
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2726
	    (buf != cp->cache_defrag->kmd_from_buf &&
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2727
	    buf != cp->cache_defrag->kmd_to_buf));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  2728
11178
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2729
	if (ccp->cc_flags & (KMF_BUFTAG | KMF_DUMPDIVERT | KMF_DUMPUNSAFE)) {
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2730
		if (ccp->cc_flags & KMF_DUMPUNSAFE) {
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2731
			ASSERT(!(ccp->cc_flags & KMF_DUMPDIVERT));
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2732
			/* log it so that we can warn about it */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2733
			KDI_LOG(cp, kdl_unsafe);
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2734
		} else if (KMEM_DUMPCC(ccp) && !kmem_cache_free_dump(cp, buf)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2735
			return;
11178
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2736
		}
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2737
		if (ccp->cc_flags & KMF_BUFTAG) {
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2738
			if (kmem_cache_free_debug(cp, buf, caller()) == -1)
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2739
				return;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2740
		}
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2741
	}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2742
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2743
	mutex_enter(&ccp->cc_lock);
12093
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2744
	/*
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2745
	 * Any changes to this logic should be reflected in kmem_slab_prefill()
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2746
	 */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2747
	for (;;) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2748
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2749
		 * If there's a slot available in the current CPU's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2750
		 * loaded magazine, just put the object there and return.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2751
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2752
		if ((uint_t)ccp->cc_rounds < ccp->cc_magsize) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2753
			ccp->cc_loaded->mag_round[ccp->cc_rounds++] = buf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2754
			ccp->cc_free++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2755
			mutex_exit(&ccp->cc_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2756
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2757
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2758
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2759
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2760
		 * The loaded magazine is full.  If the previously loaded
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2761
		 * magazine was empty, exchange them and try again.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2762
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2763
		if (ccp->cc_prounds == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2764
			kmem_cpu_reload(ccp, ccp->cc_ploaded, ccp->cc_prounds);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2765
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2766
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2767
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2768
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2769
		 * If the magazine layer is disabled, break out now.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2770
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2771
		if (ccp->cc_magsize == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2772
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2773
12093
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2774
		if (!kmem_cpucache_magazine_alloc(ccp, cp)) {
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2775
			/*
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2776
			 * We couldn't free our constructed object to the
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2777
			 * magazine layer, so apply its destructor and free it
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2778
			 * to the slab layer.
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2779
			 */
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2780
			break;
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2781
		}
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2782
	}
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2783
	mutex_exit(&ccp->cc_lock);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2784
	kmem_slab_free_constructed(cp, buf, B_TRUE);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2785
}
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2786
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2787
static void
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2788
kmem_slab_prefill(kmem_cache_t *cp, kmem_slab_t *sp)
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2789
{
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2790
	kmem_cpu_cache_t *ccp = KMEM_CPU_CACHE(cp);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2791
	int cache_flags = cp->cache_flags;
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2792
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2793
	kmem_bufctl_t *next, *head;
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2794
	size_t nbufs;
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2795
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2796
	/*
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2797
	 * Completely allocate the newly created slab and put the pre-allocated
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2798
	 * buffers in magazines. Any of the buffers that cannot be put in
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2799
	 * magazines must be returned to the slab.
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2800
	 */
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2801
	ASSERT(MUTEX_HELD(&cp->cache_lock));
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2802
	ASSERT((cache_flags & (KMF_PREFILL|KMF_BUFTAG)) == KMF_PREFILL);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2803
	ASSERT(cp->cache_constructor == NULL);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2804
	ASSERT(sp->slab_cache == cp);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2805
	ASSERT(sp->slab_refcnt == 1);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2806
	ASSERT(sp->slab_head != NULL && sp->slab_chunks > sp->slab_refcnt);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2807
	ASSERT(avl_find(&cp->cache_partial_slabs, sp, NULL) == NULL);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2808
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2809
	head = sp->slab_head;
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2810
	nbufs = (sp->slab_chunks - sp->slab_refcnt);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2811
	sp->slab_head = NULL;
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2812
	sp->slab_refcnt += nbufs;
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2813
	cp->cache_bufslab -= nbufs;
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2814
	cp->cache_slab_alloc += nbufs;
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2815
	list_insert_head(&cp->cache_complete_slabs, sp);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2816
	cp->cache_complete_slab_count++;
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2817
	mutex_exit(&cp->cache_lock);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2818
	mutex_enter(&ccp->cc_lock);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2819
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2820
	while (head != NULL) {
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2821
		void *buf = KMEM_BUF(cp, head);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2822
		/*
12093
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2823
		 * If there's a slot available in the current CPU's
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2824
		 * loaded magazine, just put the object there and
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2825
		 * continue.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2826
		 */
12093
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2827
		if ((uint_t)ccp->cc_rounds < ccp->cc_magsize) {
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2828
			ccp->cc_loaded->mag_round[ccp->cc_rounds++] =
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2829
			    buf;
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2830
			ccp->cc_free++;
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2831
			nbufs--;
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2832
			head = head->bc_next;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2833
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2834
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2835
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2836
		/*
12093
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2837
		 * The loaded magazine is full.  If the previously
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2838
		 * loaded magazine was empty, exchange them and try
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2839
		 * again.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2840
		 */
12093
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2841
		if (ccp->cc_prounds == 0) {
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2842
			kmem_cpu_reload(ccp, ccp->cc_ploaded,
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2843
			    ccp->cc_prounds);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2844
			continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2845
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2846
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2847
		/*
12093
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2848
		 * If the magazine layer is disabled, break out now.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2849
		 */
12093
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2850
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2851
		if (ccp->cc_magsize == 0) {
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2852
			break;
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2853
		}
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2854
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2855
		if (!kmem_cpucache_magazine_alloc(ccp, cp))
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2856
			break;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2857
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2858
	mutex_exit(&ccp->cc_lock);
12093
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2859
	if (nbufs != 0) {
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2860
		ASSERT(head != NULL);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2861
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2862
		/*
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2863
		 * If there was a failure, return remaining objects to
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2864
		 * the slab
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2865
		 */
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2866
		while (head != NULL) {
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2867
			ASSERT(nbufs != 0);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2868
			next = head->bc_next;
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2869
			head->bc_next = NULL;
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2870
			kmem_slab_free(cp, KMEM_BUF(cp, head));
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2871
			head = next;
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2872
			nbufs--;
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2873
		}
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2874
	}
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2875
	ASSERT(head == NULL);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2876
	ASSERT(nbufs == 0);
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  2877
	mutex_enter(&cp->cache_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2878
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2879
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2880
void *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2881
kmem_zalloc(size_t size, int kmflag)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2882
{
9367
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2883
	size_t index;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2884
	void *buf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2885
9367
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2886
	if ((index = ((size - 1) >> KMEM_ALIGN_SHIFT)) < KMEM_ALLOC_TABLE_MAX) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2887
		kmem_cache_t *cp = kmem_alloc_table[index];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2888
		buf = kmem_cache_alloc(cp, kmflag);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2889
		if (buf != NULL) {
11178
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2890
			if ((cp->cache_flags & KMF_BUFTAG) && !KMEM_DUMP(cp)) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2891
				kmem_buftag_t *btp = KMEM_BUFTAG(cp, buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2892
				((uint8_t *)buf)[size] = KMEM_REDZONE_BYTE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2893
				((uint32_t *)btp)[1] = KMEM_SIZE_ENCODE(size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2894
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2895
				if (cp->cache_flags & KMF_LITE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2896
					KMEM_BUFTAG_LITE_ENTER(btp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2897
					    kmem_lite_count, caller());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2898
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2899
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2900
			bzero(buf, size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2901
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2902
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2903
		buf = kmem_alloc(size, kmflag);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2904
		if (buf != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2905
			bzero(buf, size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2906
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2907
	return (buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2908
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2909
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2910
void *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2911
kmem_alloc(size_t size, int kmflag)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2912
{
9367
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2913
	size_t index;
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2914
	kmem_cache_t *cp;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2915
	void *buf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2916
9367
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2917
	if ((index = ((size - 1) >> KMEM_ALIGN_SHIFT)) < KMEM_ALLOC_TABLE_MAX) {
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2918
		cp = kmem_alloc_table[index];
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2919
		/* fall through to kmem_cache_alloc() */
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2920
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2921
	} else if ((index = ((size - 1) >> KMEM_BIG_SHIFT)) <
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2922
	    kmem_big_alloc_table_max) {
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2923
		cp = kmem_big_alloc_table[index];
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2924
		/* fall through to kmem_cache_alloc() */
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2925
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2926
	} else {
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2927
		if (size == 0)
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2928
			return (NULL);
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2929
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2930
		buf = vmem_alloc(kmem_oversize_arena, size,
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2931
		    kmflag & KM_VMFLAGS);
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2932
		if (buf == NULL)
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2933
			kmem_log_event(kmem_failure_log, NULL, NULL,
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2934
			    (void *)size);
11178
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2935
		else if (KMEM_DUMP(kmem_slab_cache)) {
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2936
			/* stats for dump intercept */
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2937
			kmem_dump_oversize_allocs++;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2938
			if (size > kmem_dump_oversize_max)
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2939
				kmem_dump_oversize_max = size;
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2940
		}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2941
		return (buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2942
	}
9367
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2943
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2944
	buf = kmem_cache_alloc(cp, kmflag);
11178
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2945
	if ((cp->cache_flags & KMF_BUFTAG) && !KMEM_DUMP(cp) && buf != NULL) {
9367
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2946
		kmem_buftag_t *btp = KMEM_BUFTAG(cp, buf);
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2947
		((uint8_t *)buf)[size] = KMEM_REDZONE_BYTE;
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2948
		((uint32_t *)btp)[1] = KMEM_SIZE_ENCODE(size);
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2949
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2950
		if (cp->cache_flags & KMF_LITE) {
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2951
			KMEM_BUFTAG_LITE_ENTER(btp, kmem_lite_count, caller());
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2952
		}
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2953
	}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2954
	return (buf);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2955
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2956
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2957
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2958
kmem_free(void *buf, size_t size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2959
{
9367
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2960
	size_t index;
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2961
	kmem_cache_t *cp;
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2962
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2963
	if ((index = (size - 1) >> KMEM_ALIGN_SHIFT) < KMEM_ALLOC_TABLE_MAX) {
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2964
		cp = kmem_alloc_table[index];
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2965
		/* fall through to kmem_cache_free() */
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2966
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2967
	} else if ((index = ((size - 1) >> KMEM_BIG_SHIFT)) <
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2968
	    kmem_big_alloc_table_max) {
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2969
		cp = kmem_big_alloc_table[index];
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2970
		/* fall through to kmem_cache_free() */
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2971
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2972
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2973
		if (buf == NULL && size == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2974
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2975
		vmem_free(kmem_oversize_arena, buf, size);
9367
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2976
		return;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  2977
	}
9367
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2978
11178
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  2979
	if ((cp->cache_flags & KMF_BUFTAG) && !KMEM_DUMP(cp)) {
9367
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2980
		kmem_buftag_t *btp = KMEM_BUFTAG(cp, buf);
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2981
		uint32_t *ip = (uint32_t *)btp;
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2982
		if (ip[1] != KMEM_SIZE_ENCODE(size)) {
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2983
			if (*(uint64_t *)buf == KMEM_FREE_PATTERN) {
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2984
				kmem_error(KMERR_DUPFREE, cp, buf);
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2985
				return;
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2986
			}
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2987
			if (KMEM_SIZE_VALID(ip[1])) {
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2988
				ip[0] = KMEM_SIZE_ENCODE(size);
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2989
				kmem_error(KMERR_BADSIZE, cp, buf);
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2990
			} else {
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2991
				kmem_error(KMERR_REDZONE, cp, buf);
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2992
			}
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2993
			return;
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2994
		}
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2995
		if (((uint8_t *)buf)[size] != KMEM_REDZONE_BYTE) {
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2996
			kmem_error(KMERR_REDZONE, cp, buf);
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2997
			return;
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2998
		}
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  2999
		btp->bt_redzone = KMEM_REDZONE_PATTERN;
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  3000
		if (cp->cache_flags & KMF_LITE) {
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  3001
			KMEM_BUFTAG_LITE_ENTER(btp, kmem_lite_count,
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  3002
			    caller());
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  3003
		}
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  3004
	}
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  3005
	kmem_cache_free(cp, buf);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3006
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3007
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3008
void *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3009
kmem_firewall_va_alloc(vmem_t *vmp, size_t size, int vmflag)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3010
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3011
	size_t realsize = size + vmp->vm_quantum;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3012
	void *addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3013
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3014
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3015
	 * Annoying edge case: if 'size' is just shy of ULONG_MAX, adding
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3016
	 * vm_quantum will cause integer wraparound.  Check for this, and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3017
	 * blow off the firewall page in this case.  Note that such a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3018
	 * giant allocation (the entire kernel address space) can never
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3019
	 * be satisfied, so it will either fail immediately (VM_NOSLEEP)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3020
	 * or sleep forever (VM_SLEEP).  Thus, there is no need for a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3021
	 * corresponding check in kmem_firewall_va_free().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3022
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3023
	if (realsize < size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3024
		realsize = size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3025
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3026
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3027
	 * While boot still owns resource management, make sure that this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3028
	 * redzone virtual address allocation is properly accounted for in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3029
	 * OBPs "virtual-memory" "available" lists because we're
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3030
	 * effectively claiming them for a red zone.  If we don't do this,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3031
	 * the available lists become too fragmented and too large for the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3032
	 * current boot/kernel memory list interface.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3033
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3034
	addr = vmem_alloc(vmp, realsize, vmflag | VM_NEXTFIT);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3035
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3036
	if (addr != NULL && kvseg.s_base == NULL && realsize != size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3037
		(void) boot_virt_alloc((char *)addr + size, vmp->vm_quantum);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3038
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3039
	return (addr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3040
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3041
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3042
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3043
kmem_firewall_va_free(vmem_t *vmp, void *addr, size_t size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3044
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3045
	ASSERT((kvseg.s_base == NULL ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3046
	    va_to_pfn((char *)addr + size) :
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3047
	    hat_getpfnum(kas.a_hat, (caddr_t)addr + size)) == PFN_INVALID);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3048
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3049
	vmem_free(vmp, addr, size + vmp->vm_quantum);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3050
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3051
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3052
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3053
 * Try to allocate at least `size' bytes of memory without sleeping or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3054
 * panicking. Return actual allocated size in `asize'. If allocation failed,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3055
 * try final allocation with sleep or panic allowed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3056
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3057
void *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3058
kmem_alloc_tryhard(size_t size, size_t *asize, int kmflag)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3059
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3060
	void *p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3061
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3062
	*asize = P2ROUNDUP(size, KMEM_ALIGN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3063
	do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3064
		p = kmem_alloc(*asize, (kmflag | KM_NOSLEEP) & ~KM_PANIC);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3065
		if (p != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3066
			return (p);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3067
		*asize += KMEM_ALIGN;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3068
	} while (*asize <= PAGESIZE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3069
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3070
	*asize = P2ROUNDUP(size, KMEM_ALIGN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3071
	return (kmem_alloc(*asize, kmflag));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3072
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3073
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3074
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3075
 * Reclaim all unused memory from a cache.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3076
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3077
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3078
kmem_cache_reap(kmem_cache_t *cp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3079
{
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3080
	ASSERT(taskq_member(kmem_taskq, curthread));
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  3081
	cp->cache_reap++;
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3082
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3083
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3084
	 * Ask the cache's owner to free some memory if possible.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3085
	 * The idea is to handle things like the inode cache, which
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3086
	 * typically sits on a bunch of memory that it doesn't truly
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3087
	 * *need*.  Reclaim policy is entirely up to the owner; this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3088
	 * callback is just an advisory plea for help.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3089
	 */
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3090
	if (cp->cache_reclaim != NULL) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3091
		long delta;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3092
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3093
		/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3094
		 * Reclaimed memory should be reapable (not included in the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3095
		 * depot's working set).
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3096
		 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3097
		delta = cp->cache_full.ml_total;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3098
		cp->cache_reclaim(cp->cache_private);
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3099
		delta = cp->cache_full.ml_total - delta;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3100
		if (delta > 0) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3101
			mutex_enter(&cp->cache_depot_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3102
			cp->cache_full.ml_reaplimit += delta;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3103
			cp->cache_full.ml_min += delta;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3104
			mutex_exit(&cp->cache_depot_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3105
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3106
	}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3107
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3108
	kmem_depot_ws_reap(cp);
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3109
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3110
	if (cp->cache_defrag != NULL && !kmem_move_noreap) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3111
		kmem_cache_defrag(cp);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3112
	}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3113
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3114
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3115
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3116
kmem_reap_timeout(void *flag_arg)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3117
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3118
	uint32_t *flag = (uint32_t *)flag_arg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3119
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3120
	ASSERT(flag == &kmem_reaping || flag == &kmem_reaping_idspace);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3121
	*flag = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3122
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3123
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3124
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3125
kmem_reap_done(void *flag)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3126
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3127
	(void) timeout(kmem_reap_timeout, flag, kmem_reap_interval);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3128
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3129
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3130
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3131
kmem_reap_start(void *flag)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3132
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3133
	ASSERT(flag == &kmem_reaping || flag == &kmem_reaping_idspace);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3134
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3135
	if (flag == &kmem_reaping) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3136
		kmem_cache_applyall(kmem_cache_reap, kmem_taskq, TQ_NOSLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3137
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3138
		 * if we have segkp under heap, reap segkp cache.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3139
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3140
		if (segkp_fromheap)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3141
			segkp_cache_free();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3142
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3143
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3144
		kmem_cache_applyall_id(kmem_cache_reap, kmem_taskq, TQ_NOSLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3145
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3146
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3147
	 * We use taskq_dispatch() to schedule a timeout to clear
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3148
	 * the flag so that kmem_reap() becomes self-throttling:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3149
	 * we won't reap again until the current reap completes *and*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3150
	 * at least kmem_reap_interval ticks have elapsed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3151
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3152
	if (!taskq_dispatch(kmem_taskq, kmem_reap_done, flag, TQ_NOSLEEP))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3153
		kmem_reap_done(flag);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3154
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3155
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3156
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3157
kmem_reap_common(void *flag_arg)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3158
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3159
	uint32_t *flag = (uint32_t *)flag_arg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3160
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3161
	if (MUTEX_HELD(&kmem_cache_lock) || kmem_taskq == NULL ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3162
	    cas32(flag, 0, 1) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3163
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3164
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3165
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3166
	 * It may not be kosher to do memory allocation when a reap is called
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3167
	 * is called (for example, if vmem_populate() is in the call chain).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3168
	 * So we start the reap going with a TQ_NOALLOC dispatch.  If the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3169
	 * dispatch fails, we reset the flag, and the next reap will try again.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3170
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3171
	if (!taskq_dispatch(kmem_taskq, kmem_reap_start, flag, TQ_NOALLOC))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3172
		*flag = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3173
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3174
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3175
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3176
 * Reclaim all unused memory from all caches.  Called from the VM system
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3177
 * when memory gets tight.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3178
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3179
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3180
kmem_reap(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3181
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3182
	kmem_reap_common(&kmem_reaping);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3183
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3184
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3185
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3186
 * Reclaim all unused memory from identifier arenas, called when a vmem
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3187
 * arena not back by memory is exhausted.  Since reaping memory-backed caches
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3188
 * cannot help with identifier exhaustion, we avoid both a large amount of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3189
 * work and unwanted side-effects from reclaim callbacks.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3190
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3191
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3192
kmem_reap_idspace(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3193
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3194
	kmem_reap_common(&kmem_reaping_idspace);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3195
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3196
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3197
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3198
 * Purge all magazines from a cache and set its magazine limit to zero.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3199
 * All calls are serialized by the kmem_taskq lock, except for the final
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3200
 * call from kmem_cache_destroy().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3201
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3202
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3203
kmem_cache_magazine_purge(kmem_cache_t *cp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3204
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3205
	kmem_cpu_cache_t *ccp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3206
	kmem_magazine_t *mp, *pmp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3207
	int rounds, prounds, cpu_seqid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3208
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3209
	ASSERT(!list_link_active(&cp->cache_link) ||
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3210
	    taskq_member(kmem_taskq, curthread));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3211
	ASSERT(MUTEX_NOT_HELD(&cp->cache_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3212
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3213
	for (cpu_seqid = 0; cpu_seqid < max_ncpus; cpu_seqid++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3214
		ccp = &cp->cache_cpu[cpu_seqid];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3215
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3216
		mutex_enter(&ccp->cc_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3217
		mp = ccp->cc_loaded;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3218
		pmp = ccp->cc_ploaded;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3219
		rounds = ccp->cc_rounds;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3220
		prounds = ccp->cc_prounds;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3221
		ccp->cc_loaded = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3222
		ccp->cc_ploaded = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3223
		ccp->cc_rounds = -1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3224
		ccp->cc_prounds = -1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3225
		ccp->cc_magsize = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3226
		mutex_exit(&ccp->cc_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3227
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3228
		if (mp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3229
			kmem_magazine_destroy(cp, mp, rounds);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3230
		if (pmp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3231
			kmem_magazine_destroy(cp, pmp, prounds);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3232
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3233
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3234
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3235
	 * Updating the working set statistics twice in a row has the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3236
	 * effect of setting the working set size to zero, so everything
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3237
	 * is eligible for reaping.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3238
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3239
	kmem_depot_ws_update(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3240
	kmem_depot_ws_update(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3241
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3242
	kmem_depot_ws_reap(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3243
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3244
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3245
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3246
 * Enable per-cpu magazines on a cache.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3247
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3248
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3249
kmem_cache_magazine_enable(kmem_cache_t *cp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3250
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3251
	int cpu_seqid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3252
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3253
	if (cp->cache_flags & KMF_NOMAGAZINE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3254
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3255
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3256
	for (cpu_seqid = 0; cpu_seqid < max_ncpus; cpu_seqid++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3257
		kmem_cpu_cache_t *ccp = &cp->cache_cpu[cpu_seqid];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3258
		mutex_enter(&ccp->cc_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3259
		ccp->cc_magsize = cp->cache_magtype->mt_magsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3260
		mutex_exit(&ccp->cc_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3261
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3262
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3263
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3264
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3265
/*
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
  3266
 * Reap (almost) everything right now.  See kmem_cache_magazine_purge()
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
  3267
 * for explanation of the back-to-back kmem_depot_ws_update() calls.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
  3268
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
  3269
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
  3270
kmem_cache_reap_now(kmem_cache_t *cp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
  3271
{
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3272
	ASSERT(list_link_active(&cp->cache_link));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3273
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
  3274
	kmem_depot_ws_update(cp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
  3275
	kmem_depot_ws_update(cp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
  3276
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
  3277
	(void) taskq_dispatch(kmem_taskq,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
  3278
	    (task_func_t *)kmem_depot_ws_reap, cp, TQ_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
  3279
	taskq_wait(kmem_taskq);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
  3280
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
  3281
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
  3282
/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3283
 * Recompute a cache's magazine size.  The trade-off is that larger magazines
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3284
 * provide a higher transfer rate with the depot, while smaller magazines
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3285
 * reduce memory consumption.  Magazine resizing is an expensive operation;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3286
 * it should not be done frequently.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3287
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3288
 * Changes to the magazine size are serialized by the kmem_taskq lock.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3289
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3290
 * Note: at present this only grows the magazine size.  It might be useful
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3291
 * to allow shrinkage too.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3292
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3293
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3294
kmem_cache_magazine_resize(kmem_cache_t *cp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3295
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3296
	kmem_magtype_t *mtp = cp->cache_magtype;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3297
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3298
	ASSERT(taskq_member(kmem_taskq, curthread));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3299
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3300
	if (cp->cache_chunksize < mtp->mt_maxbuf) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3301
		kmem_cache_magazine_purge(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3302
		mutex_enter(&cp->cache_depot_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3303
		cp->cache_magtype = ++mtp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3304
		cp->cache_depot_contention_prev =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3305
		    cp->cache_depot_contention + INT_MAX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3306
		mutex_exit(&cp->cache_depot_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3307
		kmem_cache_magazine_enable(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3308
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3309
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3310
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3311
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3312
 * Rescale a cache's hash table, so that the table size is roughly the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3313
 * cache size.  We want the average lookup time to be extremely small.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3314
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3315
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3316
kmem_hash_rescale(kmem_cache_t *cp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3317
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3318
	kmem_bufctl_t **old_table, **new_table, *bcp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3319
	size_t old_size, new_size, h;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3320
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3321
	ASSERT(taskq_member(kmem_taskq, curthread));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3322
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3323
	new_size = MAX(KMEM_HASH_INITIAL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3324
	    1 << (highbit(3 * cp->cache_buftotal + 4) - 2));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3325
	old_size = cp->cache_hash_mask + 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3326
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3327
	if ((old_size >> 1) <= new_size && new_size <= (old_size << 1))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3328
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3329
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3330
	new_table = vmem_alloc(kmem_hash_arena, new_size * sizeof (void *),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3331
	    VM_NOSLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3332
	if (new_table == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3333
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3334
	bzero(new_table, new_size * sizeof (void *));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3335
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3336
	mutex_enter(&cp->cache_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3337
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3338
	old_size = cp->cache_hash_mask + 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3339
	old_table = cp->cache_hash_table;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3340
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3341
	cp->cache_hash_mask = new_size - 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3342
	cp->cache_hash_table = new_table;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3343
	cp->cache_rescale++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3344
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3345
	for (h = 0; h < old_size; h++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3346
		bcp = old_table[h];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3347
		while (bcp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3348
			void *addr = bcp->bc_addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3349
			kmem_bufctl_t *next_bcp = bcp->bc_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3350
			kmem_bufctl_t **hash_bucket = KMEM_HASH(cp, addr);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3351
			bcp->bc_next = *hash_bucket;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3352
			*hash_bucket = bcp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3353
			bcp = next_bcp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3354
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3355
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3356
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3357
	mutex_exit(&cp->cache_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3358
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3359
	vmem_free(kmem_hash_arena, old_table, old_size * sizeof (void *));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3360
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3361
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3362
/*
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3363
 * Perform periodic maintenance on a cache: hash rescaling, depot working-set
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3364
 * update, magazine resizing, and slab consolidation.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3365
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3366
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3367
kmem_cache_update(kmem_cache_t *cp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3368
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3369
	int need_hash_rescale = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3370
	int need_magazine_resize = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3371
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3372
	ASSERT(MUTEX_HELD(&kmem_cache_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3373
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3374
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3375
	 * If the cache has become much larger or smaller than its hash table,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3376
	 * fire off a request to rescale the hash table.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3377
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3378
	mutex_enter(&cp->cache_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3379
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3380
	if ((cp->cache_flags & KMF_HASH) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3381
	    (cp->cache_buftotal > (cp->cache_hash_mask << 1) ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3382
	    (cp->cache_buftotal < (cp->cache_hash_mask >> 1) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3383
	    cp->cache_hash_mask > KMEM_HASH_INITIAL)))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3384
		need_hash_rescale = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3385
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3386
	mutex_exit(&cp->cache_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3387
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3388
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3389
	 * Update the depot working set statistics.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3390
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3391
	kmem_depot_ws_update(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3392
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3393
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3394
	 * If there's a lot of contention in the depot,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3395
	 * increase the magazine size.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3396
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3397
	mutex_enter(&cp->cache_depot_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3398
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3399
	if (cp->cache_chunksize < cp->cache_magtype->mt_maxbuf &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3400
	    (int)(cp->cache_depot_contention -
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3401
	    cp->cache_depot_contention_prev) > kmem_depot_contention)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3402
		need_magazine_resize = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3403
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3404
	cp->cache_depot_contention_prev = cp->cache_depot_contention;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3405
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3406
	mutex_exit(&cp->cache_depot_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3407
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3408
	if (need_hash_rescale)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3409
		(void) taskq_dispatch(kmem_taskq,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3410
		    (task_func_t *)kmem_hash_rescale, cp, TQ_NOSLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3411
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3412
	if (need_magazine_resize)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3413
		(void) taskq_dispatch(kmem_taskq,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3414
		    (task_func_t *)kmem_cache_magazine_resize, cp, TQ_NOSLEEP);
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3415
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3416
	if (cp->cache_defrag != NULL)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3417
		(void) taskq_dispatch(kmem_taskq,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3418
		    (task_func_t *)kmem_cache_scan, cp, TQ_NOSLEEP);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3419
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3420
9694
78fafb281255 6795209 Enable compilation of ON-consolidation with GCC 4.2
Scott Rotondo <Scott.Rotondo@Sun.COM>
parents: 9521
diff changeset
  3421
static void kmem_update(void *);
78fafb281255 6795209 Enable compilation of ON-consolidation with GCC 4.2
Scott Rotondo <Scott.Rotondo@Sun.COM>
parents: 9521
diff changeset
  3422
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3423
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3424
kmem_update_timeout(void *dummy)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3425
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3426
	(void) timeout(kmem_update, dummy, kmem_reap_interval);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3427
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3428
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3429
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3430
kmem_update(void *dummy)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3431
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3432
	kmem_cache_applyall(kmem_cache_update, NULL, TQ_NOSLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3433
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3434
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3435
	 * We use taskq_dispatch() to reschedule the timeout so that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3436
	 * kmem_update() becomes self-throttling: it won't schedule
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3437
	 * new tasks until all previous tasks have completed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3438
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3439
	if (!taskq_dispatch(kmem_taskq, kmem_update_timeout, dummy, TQ_NOSLEEP))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3440
		kmem_update_timeout(NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3441
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3442
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3443
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3444
kmem_cache_kstat_update(kstat_t *ksp, int rw)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3445
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3446
	struct kmem_cache_kstat *kmcp = &kmem_cache_kstat;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3447
	kmem_cache_t *cp = ksp->ks_private;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3448
	uint64_t cpu_buf_avail;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3449
	uint64_t buf_avail = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3450
	int cpu_seqid;
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  3451
	long reap;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3452
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3453
	ASSERT(MUTEX_HELD(&kmem_cache_kstat_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3454
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3455
	if (rw == KSTAT_WRITE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3456
		return (EACCES);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3457
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3458
	mutex_enter(&cp->cache_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3459
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3460
	kmcp->kmc_alloc_fail.value.ui64		= cp->cache_alloc_fail;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3461
	kmcp->kmc_alloc.value.ui64		= cp->cache_slab_alloc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3462
	kmcp->kmc_free.value.ui64		= cp->cache_slab_free;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3463
	kmcp->kmc_slab_alloc.value.ui64		= cp->cache_slab_alloc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3464
	kmcp->kmc_slab_free.value.ui64		= cp->cache_slab_free;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3465
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3466
	for (cpu_seqid = 0; cpu_seqid < max_ncpus; cpu_seqid++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3467
		kmem_cpu_cache_t *ccp = &cp->cache_cpu[cpu_seqid];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3468
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3469
		mutex_enter(&ccp->cc_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3470
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3471
		cpu_buf_avail = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3472
		if (ccp->cc_rounds > 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3473
			cpu_buf_avail += ccp->cc_rounds;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3474
		if (ccp->cc_prounds > 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3475
			cpu_buf_avail += ccp->cc_prounds;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3476
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3477
		kmcp->kmc_alloc.value.ui64	+= ccp->cc_alloc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3478
		kmcp->kmc_free.value.ui64	+= ccp->cc_free;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3479
		buf_avail			+= cpu_buf_avail;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3480
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3481
		mutex_exit(&ccp->cc_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3482
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3483
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3484
	mutex_enter(&cp->cache_depot_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3485
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3486
	kmcp->kmc_depot_alloc.value.ui64	= cp->cache_full.ml_alloc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3487
	kmcp->kmc_depot_free.value.ui64		= cp->cache_empty.ml_alloc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3488
	kmcp->kmc_depot_contention.value.ui64	= cp->cache_depot_contention;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3489
	kmcp->kmc_full_magazines.value.ui64	= cp->cache_full.ml_total;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3490
	kmcp->kmc_empty_magazines.value.ui64	= cp->cache_empty.ml_total;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3491
	kmcp->kmc_magazine_size.value.ui64	=
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3492
	    (cp->cache_flags & KMF_NOMAGAZINE) ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3493
	    0 : cp->cache_magtype->mt_magsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3494
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3495
	kmcp->kmc_alloc.value.ui64		+= cp->cache_full.ml_alloc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3496
	kmcp->kmc_free.value.ui64		+= cp->cache_empty.ml_alloc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3497
	buf_avail += cp->cache_full.ml_total * cp->cache_magtype->mt_magsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3498
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  3499
	reap = MIN(cp->cache_full.ml_reaplimit, cp->cache_full.ml_min);
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  3500
	reap = MIN(reap, cp->cache_full.ml_total);
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  3501
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3502
	mutex_exit(&cp->cache_depot_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3503
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3504
	kmcp->kmc_buf_size.value.ui64	= cp->cache_bufsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3505
	kmcp->kmc_align.value.ui64	= cp->cache_align;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3506
	kmcp->kmc_chunk_size.value.ui64	= cp->cache_chunksize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3507
	kmcp->kmc_slab_size.value.ui64	= cp->cache_slabsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3508
	kmcp->kmc_buf_constructed.value.ui64 = buf_avail;
6306
ecac2262dc70 6675361 kmem_cache_kstat_update() is hot on large servers
tomee
parents: 3448
diff changeset
  3509
	buf_avail += cp->cache_bufslab;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3510
	kmcp->kmc_buf_avail.value.ui64	= buf_avail;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3511
	kmcp->kmc_buf_inuse.value.ui64	= cp->cache_buftotal - buf_avail;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3512
	kmcp->kmc_buf_total.value.ui64	= cp->cache_buftotal;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3513
	kmcp->kmc_buf_max.value.ui64	= cp->cache_bufmax;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3514
	kmcp->kmc_slab_create.value.ui64	= cp->cache_slab_create;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3515
	kmcp->kmc_slab_destroy.value.ui64	= cp->cache_slab_destroy;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3516
	kmcp->kmc_hash_size.value.ui64	= (cp->cache_flags & KMF_HASH) ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3517
	    cp->cache_hash_mask + 1 : 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3518
	kmcp->kmc_hash_lookup_depth.value.ui64	= cp->cache_lookup_depth;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3519
	kmcp->kmc_hash_rescale.value.ui64	= cp->cache_rescale;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3520
	kmcp->kmc_vmem_source.value.ui64	= cp->cache_arena->vm_id;
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  3521
	kmcp->kmc_reap.value.ui64	= cp->cache_reap;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3522
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3523
	if (cp->cache_defrag == NULL) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3524
		kmcp->kmc_move_callbacks.value.ui64	= 0;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3525
		kmcp->kmc_move_yes.value.ui64		= 0;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3526
		kmcp->kmc_move_no.value.ui64		= 0;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3527
		kmcp->kmc_move_later.value.ui64		= 0;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3528
		kmcp->kmc_move_dont_need.value.ui64	= 0;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3529
		kmcp->kmc_move_dont_know.value.ui64	= 0;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3530
		kmcp->kmc_move_hunt_found.value.ui64	= 0;
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  3531
		kmcp->kmc_move_slabs_freed.value.ui64	= 0;
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  3532
		kmcp->kmc_defrag.value.ui64		= 0;
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  3533
		kmcp->kmc_scan.value.ui64		= 0;
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  3534
		kmcp->kmc_move_reclaimable.value.ui64	= 0;
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3535
	} else {
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  3536
		int64_t reclaimable;
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  3537
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3538
		kmem_defrag_t *kd = cp->cache_defrag;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3539
		kmcp->kmc_move_callbacks.value.ui64	= kd->kmd_callbacks;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3540
		kmcp->kmc_move_yes.value.ui64		= kd->kmd_yes;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3541
		kmcp->kmc_move_no.value.ui64		= kd->kmd_no;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3542
		kmcp->kmc_move_later.value.ui64		= kd->kmd_later;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3543
		kmcp->kmc_move_dont_need.value.ui64	= kd->kmd_dont_need;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3544
		kmcp->kmc_move_dont_know.value.ui64	= kd->kmd_dont_know;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3545
		kmcp->kmc_move_hunt_found.value.ui64	= kd->kmd_hunt_found;
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  3546
		kmcp->kmc_move_slabs_freed.value.ui64	= kd->kmd_slabs_freed;
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  3547
		kmcp->kmc_defrag.value.ui64		= kd->kmd_defrags;
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  3548
		kmcp->kmc_scan.value.ui64		= kd->kmd_scans;
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  3549
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  3550
		reclaimable = cp->cache_bufslab - (cp->cache_maxchunks - 1);
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  3551
		reclaimable = MAX(reclaimable, 0);
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  3552
		reclaimable += ((uint64_t)reap * cp->cache_magtype->mt_magsize);
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  3553
		kmcp->kmc_move_reclaimable.value.ui64	= reclaimable;
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3554
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3555
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3556
	mutex_exit(&cp->cache_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3557
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3558
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3559
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3560
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3561
 * Return a named statistic about a particular cache.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3562
 * This shouldn't be called very often, so it's currently designed for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3563
 * simplicity (leverages existing kstat support) rather than efficiency.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3564
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3565
uint64_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3566
kmem_cache_stat(kmem_cache_t *cp, char *name)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3567
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3568
	int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3569
	kstat_t *ksp = cp->cache_kstat;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3570
	kstat_named_t *knp = (kstat_named_t *)&kmem_cache_kstat;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3571
	uint64_t value = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3572
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3573
	if (ksp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3574
		mutex_enter(&kmem_cache_kstat_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3575
		(void) kmem_cache_kstat_update(ksp, KSTAT_READ);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3576
		for (i = 0; i < ksp->ks_ndata; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3577
			if (strcmp(knp[i].name, name) == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3578
				value = knp[i].value.ui64;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3579
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3580
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3581
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3582
		mutex_exit(&kmem_cache_kstat_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3583
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3584
	return (value);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3585
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3586
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3587
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3588
 * Return an estimate of currently available kernel heap memory.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3589
 * On 32-bit systems, physical memory may exceed virtual memory,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3590
 * we just truncate the result at 1GB.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3591
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3592
size_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3593
kmem_avail(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3594
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3595
	spgcnt_t rmem = availrmem - tune.t_minarmem;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3596
	spgcnt_t fmem = freemem - minfree;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3597
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3598
	return ((size_t)ptob(MIN(MAX(MIN(rmem, fmem), 0),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3599
	    1 << (30 - PAGESHIFT))));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3600
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3601
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3602
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3603
 * Return the maximum amount of memory that is (in theory) allocatable
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3604
 * from the heap. This may be used as an estimate only since there
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3605
 * is no guarentee this space will still be available when an allocation
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3606
 * request is made, nor that the space may be allocated in one big request
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3607
 * due to kernel heap fragmentation.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3608
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3609
size_t
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3610
kmem_maxavail(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3611
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3612
	spgcnt_t pmem = availrmem - tune.t_minarmem;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3613
	spgcnt_t vmem = btop(vmem_size(heap_arena, VMEM_FREE));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3614
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3615
	return ((size_t)ptob(MAX(MIN(pmem, vmem), 0)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3616
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3617
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
  3618
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
  3619
 * Indicate whether memory-intensive kmem debugging is enabled.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
  3620
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
  3621
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
  3622
kmem_debugging(void)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
  3623
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
  3624
	return (kmem_flags & (KMF_AUDIT | KMF_REDZONE));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
  3625
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents: 0
diff changeset
  3626
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3627
/* binning function, sorts finely at the two extremes */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3628
#define	KMEM_PARTIAL_SLAB_WEIGHT(sp, binshift)				\
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3629
	((((sp)->slab_refcnt <= (binshift)) ||				\
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3630
	    (((sp)->slab_chunks - (sp)->slab_refcnt) <= (binshift)))	\
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3631
	    ? -(sp)->slab_refcnt					\
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3632
	    : -((binshift) + ((sp)->slab_refcnt >> (binshift))))
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3633
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3634
/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3635
 * Minimizing the number of partial slabs on the freelist minimizes
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3636
 * fragmentation (the ratio of unused buffers held by the slab layer). There are
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3637
 * two ways to get a slab off of the freelist: 1) free all the buffers on the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3638
 * slab, and 2) allocate all the buffers on the slab. It follows that we want
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3639
 * the most-used slabs at the front of the list where they have the best chance
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3640
 * of being completely allocated, and the least-used slabs at a safe distance
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3641
 * from the front to improve the odds that the few remaining buffers will all be
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3642
 * freed before another allocation can tie up the slab. For that reason a slab
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3643
 * with a higher slab_refcnt sorts less than than a slab with a lower
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3644
 * slab_refcnt.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3645
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3646
 * However, if a slab has at least one buffer that is deemed unfreeable, we
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3647
 * would rather have that slab at the front of the list regardless of
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3648
 * slab_refcnt, since even one unfreeable buffer makes the entire slab
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3649
 * unfreeable. If the client returns KMEM_CBRC_NO in response to a cache_move()
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3650
 * callback, the slab is marked unfreeable for as long as it remains on the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3651
 * freelist.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3652
 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3653
static int
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3654
kmem_partial_slab_cmp(const void *p0, const void *p1)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3655
{
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3656
	const kmem_cache_t *cp;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3657
	const kmem_slab_t *s0 = p0;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3658
	const kmem_slab_t *s1 = p1;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3659
	int w0, w1;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3660
	size_t binshift;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3661
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3662
	ASSERT(KMEM_SLAB_IS_PARTIAL(s0));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3663
	ASSERT(KMEM_SLAB_IS_PARTIAL(s1));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3664
	ASSERT(s0->slab_cache == s1->slab_cache);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3665
	cp = s1->slab_cache;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3666
	ASSERT(MUTEX_HELD(&cp->cache_lock));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3667
	binshift = cp->cache_partial_binshift;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3668
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3669
	/* weight of first slab */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3670
	w0 = KMEM_PARTIAL_SLAB_WEIGHT(s0, binshift);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3671
	if (s0->slab_flags & KMEM_SLAB_NOMOVE) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3672
		w0 -= cp->cache_maxchunks;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3673
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3674
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3675
	/* weight of second slab */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3676
	w1 = KMEM_PARTIAL_SLAB_WEIGHT(s1, binshift);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3677
	if (s1->slab_flags & KMEM_SLAB_NOMOVE) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3678
		w1 -= cp->cache_maxchunks;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3679
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3680
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3681
	if (w0 < w1)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3682
		return (-1);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3683
	if (w0 > w1)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3684
		return (1);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3685
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3686
	/* compare pointer values */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3687
	if ((uintptr_t)s0 < (uintptr_t)s1)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3688
		return (-1);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3689
	if ((uintptr_t)s0 > (uintptr_t)s1)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3690
		return (1);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3691
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3692
	return (0);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3693
}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3694
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3695
/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3696
 * It must be valid to call the destructor (if any) on a newly created object.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3697
 * That is, the constructor (if any) must leave the object in a valid state for
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3698
 * the destructor.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3699
 */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3700
kmem_cache_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3701
kmem_cache_create(
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3702
	char *name,		/* descriptive name for this cache */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3703
	size_t bufsize,		/* size of the objects it manages */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3704
	size_t align,		/* required object alignment */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3705
	int (*constructor)(void *, void *, int), /* object constructor */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3706
	void (*destructor)(void *, void *),	/* object destructor */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3707
	void (*reclaim)(void *), /* memory reclaim callback */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3708
	void *private,		/* pass-thru arg for constr/destr/reclaim */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3709
	vmem_t *vmp,		/* vmem source for slab allocation */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3710
	int cflags)		/* cache creation flags */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3711
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3712
	int cpu_seqid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3713
	size_t chunksize;
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3714
	kmem_cache_t *cp;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3715
	kmem_magtype_t *mtp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3716
	size_t csize = KMEM_CACHE_SIZE(max_ncpus);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3717
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3718
#ifdef	DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3719
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3720
	 * Cache names should conform to the rules for valid C identifiers
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3721
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3722
	if (!strident_valid(name)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3723
		cmn_err(CE_CONT,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3724
		    "kmem_cache_create: '%s' is an invalid cache name\n"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3725
		    "cache names must conform to the rules for "
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3726
		    "C identifiers\n", name);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3727
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3728
#endif	/* DEBUG */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3729
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3730
	if (vmp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3731
		vmp = kmem_default_arena;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3732
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3733
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3734
	 * If this kmem cache has an identifier vmem arena as its source, mark
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3735
	 * it such to allow kmem_reap_idspace().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3736
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3737
	ASSERT(!(cflags & KMC_IDENTIFIER));   /* consumer should not set this */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3738
	if (vmp->vm_cflags & VMC_IDENTIFIER)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3739
		cflags |= KMC_IDENTIFIER;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3740
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3741
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3742
	 * Get a kmem_cache structure.  We arrange that cp->cache_cpu[]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3743
	 * is aligned on a KMEM_CPU_CACHE_SIZE boundary to prevent
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3744
	 * false sharing of per-CPU data.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3745
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3746
	cp = vmem_xalloc(kmem_cache_arena, csize, KMEM_CPU_CACHE_SIZE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3747
	    P2NPHASE(csize, KMEM_CPU_CACHE_SIZE), 0, NULL, NULL, VM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3748
	bzero(cp, csize);
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3749
	list_link_init(&cp->cache_link);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3750
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3751
	if (align == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3752
		align = KMEM_ALIGN;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3753
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3754
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3755
	 * If we're not at least KMEM_ALIGN aligned, we can't use free
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3756
	 * memory to hold bufctl information (because we can't safely
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3757
	 * perform word loads and stores on it).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3758
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3759
	if (align < KMEM_ALIGN)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3760
		cflags |= KMC_NOTOUCH;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3761
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3762
	if ((align & (align - 1)) != 0 || align > vmp->vm_quantum)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3763
		panic("kmem_cache_create: bad alignment %lu", align);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3764
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3765
	mutex_enter(&kmem_flags_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3766
	if (kmem_flags & KMF_RANDOMIZE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3767
		kmem_flags = (((kmem_flags | ~KMF_RANDOM) + 1) & KMF_RANDOM) |
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3768
		    KMF_RANDOMIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3769
	cp->cache_flags = (kmem_flags | cflags) & KMF_DEBUG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3770
	mutex_exit(&kmem_flags_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3771
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3772
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3773
	 * Make sure all the various flags are reasonable.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3774
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3775
	ASSERT(!(cflags & KMC_NOHASH) || !(cflags & KMC_NOTOUCH));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3776
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3777
	if (cp->cache_flags & KMF_LITE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3778
		if (bufsize >= kmem_lite_minsize &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3779
		    align <= kmem_lite_maxalign &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3780
		    P2PHASE(bufsize, kmem_lite_maxalign) != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3781
			cp->cache_flags |= KMF_BUFTAG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3782
			cp->cache_flags &= ~(KMF_AUDIT | KMF_FIREWALL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3783
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3784
			cp->cache_flags &= ~KMF_DEBUG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3785
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3786
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3787
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3788
	if (cp->cache_flags & KMF_DEADBEEF)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3789
		cp->cache_flags |= KMF_REDZONE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3790
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3791
	if ((cflags & KMC_QCACHE) && (cp->cache_flags & KMF_AUDIT))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3792
		cp->cache_flags |= KMF_NOMAGAZINE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3793
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3794
	if (cflags & KMC_NODEBUG)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3795
		cp->cache_flags &= ~KMF_DEBUG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3796
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3797
	if (cflags & KMC_NOTOUCH)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3798
		cp->cache_flags &= ~KMF_TOUCH;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3799
12093
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  3800
	if (cflags & KMC_PREFILL)
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  3801
		cp->cache_flags |= KMF_PREFILL;
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  3802
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3803
	if (cflags & KMC_NOHASH)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3804
		cp->cache_flags &= ~(KMF_AUDIT | KMF_FIREWALL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3805
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3806
	if (cflags & KMC_NOMAGAZINE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3807
		cp->cache_flags |= KMF_NOMAGAZINE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3808
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3809
	if ((cp->cache_flags & KMF_AUDIT) && !(cflags & KMC_NOTOUCH))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3810
		cp->cache_flags |= KMF_REDZONE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3811
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3812
	if (!(cp->cache_flags & KMF_AUDIT))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3813
		cp->cache_flags &= ~KMF_CONTENTS;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3814
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3815
	if ((cp->cache_flags & KMF_BUFTAG) && bufsize >= kmem_minfirewall &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3816
	    !(cp->cache_flags & KMF_LITE) && !(cflags & KMC_NOHASH))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3817
		cp->cache_flags |= KMF_FIREWALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3818
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3819
	if (vmp != kmem_default_arena || kmem_firewall_arena == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3820
		cp->cache_flags &= ~KMF_FIREWALL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3821
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3822
	if (cp->cache_flags & KMF_FIREWALL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3823
		cp->cache_flags &= ~KMF_BUFTAG;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3824
		cp->cache_flags |= KMF_NOMAGAZINE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3825
		ASSERT(vmp == kmem_default_arena);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3826
		vmp = kmem_firewall_arena;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3827
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3828
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3829
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3830
	 * Set cache properties.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3831
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3832
	(void) strncpy(cp->cache_name, name, KMEM_CACHE_NAMELEN);
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3833
	strident_canon(cp->cache_name, KMEM_CACHE_NAMELEN + 1);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3834
	cp->cache_bufsize = bufsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3835
	cp->cache_align = align;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3836
	cp->cache_constructor = constructor;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3837
	cp->cache_destructor = destructor;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3838
	cp->cache_reclaim = reclaim;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3839
	cp->cache_private = private;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3840
	cp->cache_arena = vmp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3841
	cp->cache_cflags = cflags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3842
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3843
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3844
	 * Determine the chunk size.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3845
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3846
	chunksize = bufsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3847
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3848
	if (align >= KMEM_ALIGN) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3849
		chunksize = P2ROUNDUP(chunksize, KMEM_ALIGN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3850
		cp->cache_bufctl = chunksize - KMEM_ALIGN;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3851
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3852
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3853
	if (cp->cache_flags & KMF_BUFTAG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3854
		cp->cache_bufctl = chunksize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3855
		cp->cache_buftag = chunksize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3856
		if (cp->cache_flags & KMF_LITE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3857
			chunksize += KMEM_BUFTAG_LITE_SIZE(kmem_lite_count);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3858
		else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3859
			chunksize += sizeof (kmem_buftag_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3860
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3861
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3862
	if (cp->cache_flags & KMF_DEADBEEF) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3863
		cp->cache_verify = MIN(cp->cache_buftag, kmem_maxverify);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3864
		if (cp->cache_flags & KMF_LITE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3865
			cp->cache_verify = sizeof (uint64_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3866
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3867
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3868
	cp->cache_contents = MIN(cp->cache_bufctl, kmem_content_maxsave);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3869
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3870
	cp->cache_chunksize = chunksize = P2ROUNDUP(chunksize, align);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3871
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3872
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3873
	 * Now that we know the chunk size, determine the optimal slab size.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3874
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3875
	if (vmp == kmem_firewall_arena) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3876
		cp->cache_slabsize = P2ROUNDUP(chunksize, vmp->vm_quantum);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3877
		cp->cache_mincolor = cp->cache_slabsize - chunksize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3878
		cp->cache_maxcolor = cp->cache_mincolor;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3879
		cp->cache_flags |= KMF_HASH;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3880
		ASSERT(!(cp->cache_flags & KMF_BUFTAG));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3881
	} else if ((cflags & KMC_NOHASH) || (!(cflags & KMC_NOTOUCH) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3882
	    !(cp->cache_flags & KMF_AUDIT) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3883
	    chunksize < vmp->vm_quantum / KMEM_VOID_FRACTION)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3884
		cp->cache_slabsize = vmp->vm_quantum;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3885
		cp->cache_mincolor = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3886
		cp->cache_maxcolor =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3887
		    (cp->cache_slabsize - sizeof (kmem_slab_t)) % chunksize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3888
		ASSERT(chunksize + sizeof (kmem_slab_t) <= cp->cache_slabsize);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3889
		ASSERT(!(cp->cache_flags & KMF_AUDIT));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3890
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3891
		size_t chunks, bestfit, waste, slabsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3892
		size_t minwaste = LONG_MAX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3893
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3894
		for (chunks = 1; chunks <= KMEM_VOID_FRACTION; chunks++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3895
			slabsize = P2ROUNDUP(chunksize * chunks,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3896
			    vmp->vm_quantum);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3897
			chunks = slabsize / chunksize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3898
			waste = (slabsize % chunksize) / chunks;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3899
			if (waste < minwaste) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3900
				minwaste = waste;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3901
				bestfit = slabsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3902
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3903
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3904
		if (cflags & KMC_QCACHE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3905
			bestfit = VMEM_QCACHE_SLABSIZE(vmp->vm_qcache_max);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3906
		cp->cache_slabsize = bestfit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3907
		cp->cache_mincolor = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3908
		cp->cache_maxcolor = bestfit % chunksize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3909
		cp->cache_flags |= KMF_HASH;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3910
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3911
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3912
	cp->cache_maxchunks = (cp->cache_slabsize / cp->cache_chunksize);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3913
	cp->cache_partial_binshift = highbit(cp->cache_maxchunks / 16) + 1;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3914
12093
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  3915
	/*
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  3916
	 * Disallowing prefill when either the DEBUG or HASH flag is set or when
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  3917
	 * there is a constructor avoids some tricky issues with debug setup
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  3918
	 * that may be revisited later. We cannot allow prefill in a
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  3919
	 * metadata cache because of potential recursion.
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  3920
	 */
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  3921
	if (vmp == kmem_msb_arena ||
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  3922
	    cp->cache_flags & (KMF_HASH | KMF_BUFTAG) ||
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  3923
	    cp->cache_constructor != NULL)
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  3924
		cp->cache_flags &= ~KMF_PREFILL;
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  3925
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3926
	if (cp->cache_flags & KMF_HASH) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3927
		ASSERT(!(cflags & KMC_NOHASH));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3928
		cp->cache_bufctl_cache = (cp->cache_flags & KMF_AUDIT) ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3929
		    kmem_bufctl_audit_cache : kmem_bufctl_cache;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3930
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3931
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3932
	if (cp->cache_maxcolor >= vmp->vm_quantum)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3933
		cp->cache_maxcolor = vmp->vm_quantum - 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3934
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3935
	cp->cache_color = cp->cache_mincolor;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3936
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3937
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3938
	 * Initialize the rest of the slab layer.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3939
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3940
	mutex_init(&cp->cache_lock, NULL, MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3941
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3942
	avl_create(&cp->cache_partial_slabs, kmem_partial_slab_cmp,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3943
	    sizeof (kmem_slab_t), offsetof(kmem_slab_t, slab_link));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3944
	/* LINTED: E_TRUE_LOGICAL_EXPR */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3945
	ASSERT(sizeof (list_node_t) <= sizeof (avl_node_t));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3946
	/* reuse partial slab AVL linkage for complete slab list linkage */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3947
	list_create(&cp->cache_complete_slabs,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3948
	    sizeof (kmem_slab_t), offsetof(kmem_slab_t, slab_link));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3949
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3950
	if (cp->cache_flags & KMF_HASH) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3951
		cp->cache_hash_table = vmem_alloc(kmem_hash_arena,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3952
		    KMEM_HASH_INITIAL * sizeof (void *), VM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3953
		bzero(cp->cache_hash_table,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3954
		    KMEM_HASH_INITIAL * sizeof (void *));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3955
		cp->cache_hash_mask = KMEM_HASH_INITIAL - 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3956
		cp->cache_hash_shift = highbit((ulong_t)chunksize) - 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3957
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3958
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3959
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3960
	 * Initialize the depot.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3961
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3962
	mutex_init(&cp->cache_depot_lock, NULL, MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3963
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3964
	for (mtp = kmem_magtype; chunksize <= mtp->mt_minbuf; mtp++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3965
		continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3966
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3967
	cp->cache_magtype = mtp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3968
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3969
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3970
	 * Initialize the CPU layer.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3971
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3972
	for (cpu_seqid = 0; cpu_seqid < max_ncpus; cpu_seqid++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3973
		kmem_cpu_cache_t *ccp = &cp->cache_cpu[cpu_seqid];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3974
		mutex_init(&ccp->cc_lock, NULL, MUTEX_DEFAULT, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3975
		ccp->cc_flags = cp->cache_flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3976
		ccp->cc_rounds = -1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3977
		ccp->cc_prounds = -1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3978
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3979
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3980
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3981
	 * Create the cache's kstats.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3982
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3983
	if ((cp->cache_kstat = kstat_create("unix", 0, cp->cache_name,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3984
	    "kmem_cache", KSTAT_TYPE_NAMED,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3985
	    sizeof (kmem_cache_kstat) / sizeof (kstat_named_t),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3986
	    KSTAT_FLAG_VIRTUAL)) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3987
		cp->cache_kstat->ks_data = &kmem_cache_kstat;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3988
		cp->cache_kstat->ks_update = kmem_cache_kstat_update;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3989
		cp->cache_kstat->ks_private = cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3990
		cp->cache_kstat->ks_lock = &kmem_cache_kstat_lock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3991
		kstat_install(cp->cache_kstat);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3992
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3993
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3994
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3995
	 * Add the cache to the global list.  This makes it visible
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3996
	 * to kmem_update(), so the cache must be ready for business.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3997
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  3998
	mutex_enter(&kmem_cache_lock);
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  3999
	list_insert_tail(&kmem_caches, cp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4000
	mutex_exit(&kmem_cache_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4001
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4002
	if (kmem_ready)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4003
		kmem_cache_magazine_enable(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4004
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4005
	return (cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4006
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4007
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4008
static int
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4009
kmem_move_cmp(const void *buf, const void *p)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4010
{
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4011
	const kmem_move_t *kmm = p;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4012
	uintptr_t v1 = (uintptr_t)buf;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4013
	uintptr_t v2 = (uintptr_t)kmm->kmm_from_buf;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4014
	return (v1 < v2 ? -1 : (v1 > v2 ? 1 : 0));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4015
}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4016
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4017
static void
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4018
kmem_reset_reclaim_threshold(kmem_defrag_t *kmd)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4019
{
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4020
	kmd->kmd_reclaim_numer = 1;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4021
}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4022
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4023
/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4024
 * Initially, when choosing candidate slabs for buffers to move, we want to be
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4025
 * very selective and take only slabs that are less than
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4026
 * (1 / KMEM_VOID_FRACTION) allocated. If we have difficulty finding candidate
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4027
 * slabs, then we raise the allocation ceiling incrementally. The reclaim
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4028
 * threshold is reset to (1 / KMEM_VOID_FRACTION) as soon as the cache is no
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4029
 * longer fragmented.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4030
 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4031
static void
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4032
kmem_adjust_reclaim_threshold(kmem_defrag_t *kmd, int direction)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4033
{
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4034
	if (direction > 0) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4035
		/* make it easier to find a candidate slab */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4036
		if (kmd->kmd_reclaim_numer < (KMEM_VOID_FRACTION - 1)) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4037
			kmd->kmd_reclaim_numer++;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4038
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4039
	} else {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4040
		/* be more selective */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4041
		if (kmd->kmd_reclaim_numer > 1) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4042
			kmd->kmd_reclaim_numer--;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4043
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4044
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4045
}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4046
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4047
void
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4048
kmem_cache_set_move(kmem_cache_t *cp,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4049
    kmem_cbrc_t (*move)(void *, void *, size_t, void *))
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4050
{
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4051
	kmem_defrag_t *defrag;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4052
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4053
	ASSERT(move != NULL);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4054
	/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4055
	 * The consolidator does not support NOTOUCH caches because kmem cannot
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4056
	 * initialize their slabs with the 0xbaddcafe memory pattern, which sets
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4057
	 * a low order bit usable by clients to distinguish uninitialized memory
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4058
	 * from known objects (see kmem_slab_create).
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4059
	 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4060
	ASSERT(!(cp->cache_cflags & KMC_NOTOUCH));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4061
	ASSERT(!(cp->cache_cflags & KMC_IDENTIFIER));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4062
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4063
	/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4064
	 * We should not be holding anyone's cache lock when calling
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4065
	 * kmem_cache_alloc(), so allocate in all cases before acquiring the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4066
	 * lock.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4067
	 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4068
	defrag = kmem_cache_alloc(kmem_defrag_cache, KM_SLEEP);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4069
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4070
	mutex_enter(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4071
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4072
	if (KMEM_IS_MOVABLE(cp)) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4073
		if (cp->cache_move == NULL) {
7546
b7eb4c89d3a0 6738434 kmem_check_destructor() introduces binary compatibility issue
Tom Erickson <tomee@eng.sun.com>
parents: 6908
diff changeset
  4074
			ASSERT(cp->cache_slab_alloc == 0);
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4075
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4076
			cp->cache_defrag = defrag;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4077
			defrag = NULL; /* nothing to free */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4078
			bzero(cp->cache_defrag, sizeof (kmem_defrag_t));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4079
			avl_create(&cp->cache_defrag->kmd_moves_pending,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4080
			    kmem_move_cmp, sizeof (kmem_move_t),
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4081
			    offsetof(kmem_move_t, kmm_entry));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4082
			/* LINTED: E_TRUE_LOGICAL_EXPR */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4083
			ASSERT(sizeof (list_node_t) <= sizeof (avl_node_t));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4084
			/* reuse the slab's AVL linkage for deadlist linkage */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4085
			list_create(&cp->cache_defrag->kmd_deadlist,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4086
			    sizeof (kmem_slab_t),
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4087
			    offsetof(kmem_slab_t, slab_link));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4088
			kmem_reset_reclaim_threshold(cp->cache_defrag);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4089
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4090
		cp->cache_move = move;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4091
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4092
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4093
	mutex_exit(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4094
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4095
	if (defrag != NULL) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4096
		kmem_cache_free(kmem_defrag_cache, defrag); /* unused */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4097
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4098
}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4099
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4100
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4101
kmem_cache_destroy(kmem_cache_t *cp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4102
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4103
	int cpu_seqid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4104
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4105
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4106
	 * Remove the cache from the global cache list so that no one else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4107
	 * can schedule tasks on its behalf, wait for any pending tasks to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4108
	 * complete, purge the cache, and then destroy it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4109
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4110
	mutex_enter(&kmem_cache_lock);
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4111
	list_remove(&kmem_caches, cp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4112
	mutex_exit(&kmem_cache_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4113
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4114
	if (kmem_taskq != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4115
		taskq_wait(kmem_taskq);
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4116
	if (kmem_move_taskq != NULL)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4117
		taskq_wait(kmem_move_taskq);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4118
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4119
	kmem_cache_magazine_purge(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4120
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4121
	mutex_enter(&cp->cache_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4122
	if (cp->cache_buftotal != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4123
		cmn_err(CE_WARN, "kmem_cache_destroy: '%s' (%p) not empty",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4124
		    cp->cache_name, (void *)cp);
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4125
	if (cp->cache_defrag != NULL) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4126
		avl_destroy(&cp->cache_defrag->kmd_moves_pending);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4127
		list_destroy(&cp->cache_defrag->kmd_deadlist);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4128
		kmem_cache_free(kmem_defrag_cache, cp->cache_defrag);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4129
		cp->cache_defrag = NULL;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4130
	}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4131
	/*
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4132
	 * The cache is now dead.  There should be no further activity.  We
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4133
	 * enforce this by setting land mines in the constructor, destructor,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4134
	 * reclaim, and move routines that induce a kernel text fault if
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4135
	 * invoked.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4136
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4137
	cp->cache_constructor = (int (*)(void *, void *, int))1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4138
	cp->cache_destructor = (void (*)(void *, void *))2;
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4139
	cp->cache_reclaim = (void (*)(void *))3;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4140
	cp->cache_move = (kmem_cbrc_t (*)(void *, void *, size_t, void *))4;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4141
	mutex_exit(&cp->cache_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4142
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4143
	kstat_delete(cp->cache_kstat);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4144
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4145
	if (cp->cache_hash_table != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4146
		vmem_free(kmem_hash_arena, cp->cache_hash_table,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4147
		    (cp->cache_hash_mask + 1) * sizeof (void *));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4148
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4149
	for (cpu_seqid = 0; cpu_seqid < max_ncpus; cpu_seqid++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4150
		mutex_destroy(&cp->cache_cpu[cpu_seqid].cc_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4151
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4152
	mutex_destroy(&cp->cache_depot_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4153
	mutex_destroy(&cp->cache_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4154
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4155
	vmem_free(kmem_cache_arena, cp, KMEM_CACHE_SIZE(max_ncpus));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4156
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4157
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4158
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4159
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4160
kmem_cpu_setup(cpu_setup_t what, int id, void *arg)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4161
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4162
	ASSERT(MUTEX_HELD(&cpu_lock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4163
	if (what == CPU_UNCONFIG) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4164
		kmem_cache_applyall(kmem_cache_magazine_purge,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4165
		    kmem_taskq, TQ_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4166
		kmem_cache_applyall(kmem_cache_magazine_enable,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4167
		    kmem_taskq, TQ_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4168
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4169
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4170
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4171
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4172
static void
9367
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4173
kmem_alloc_caches_create(const int *array, size_t count,
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4174
    kmem_cache_t **alloc_table, size_t maxbuf, uint_t shift)
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4175
{
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4176
	char name[KMEM_CACHE_NAMELEN + 1];
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4177
	size_t table_unit = (1 << shift); /* range of one alloc_table entry */
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4178
	size_t size = table_unit;
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4179
	int i;
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4180
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4181
	for (i = 0; i < count; i++) {
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4182
		size_t cache_size = array[i];
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4183
		size_t align = KMEM_ALIGN;
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4184
		kmem_cache_t *cp;
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4185
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4186
		/* if the table has an entry for maxbuf, we're done */
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4187
		if (size > maxbuf)
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4188
			break;
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4189
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4190
		/* cache size must be a multiple of the table unit */
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4191
		ASSERT(P2PHASE(cache_size, table_unit) == 0);
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4192
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4193
		/*
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4194
		 * If they allocate a multiple of the coherency granularity,
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4195
		 * they get a coherency-granularity-aligned address.
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4196
		 */
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4197
		if (IS_P2ALIGNED(cache_size, 64))
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4198
			align = 64;
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4199
		if (IS_P2ALIGNED(cache_size, PAGESIZE))
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4200
			align = PAGESIZE;
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4201
		(void) snprintf(name, sizeof (name),
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4202
		    "kmem_alloc_%lu", cache_size);
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4203
		cp = kmem_cache_create(name, cache_size, align,
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4204
		    NULL, NULL, NULL, NULL, NULL, KMC_KMEM_ALLOC);
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4205
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4206
		while (size <= cache_size) {
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4207
			alloc_table[(size - 1) >> shift] = cp;
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4208
			size += table_unit;
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4209
		}
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4210
	}
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4211
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4212
	ASSERT(size > maxbuf);		/* i.e. maxbuf <= max(cache_size) */
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4213
}
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4214
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4215
static void
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4216
kmem_cache_init(int pass, int use_large_pages)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4217
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4218
	int i;
9367
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4219
	size_t maxbuf;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4220
	kmem_magtype_t *mtp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4221
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4222
	for (i = 0; i < sizeof (kmem_magtype) / sizeof (*mtp); i++) {
9367
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4223
		char name[KMEM_CACHE_NAMELEN + 1];
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4224
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4225
		mtp = &kmem_magtype[i];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4226
		(void) sprintf(name, "kmem_magazine_%d", mtp->mt_magsize);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4227
		mtp->mt_cache = kmem_cache_create(name,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4228
		    (mtp->mt_magsize + 1) * sizeof (void *),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4229
		    mtp->mt_align, NULL, NULL, NULL, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4230
		    kmem_msb_arena, KMC_NOHASH);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4231
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4232
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4233
	kmem_slab_cache = kmem_cache_create("kmem_slab_cache",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4234
	    sizeof (kmem_slab_t), 0, NULL, NULL, NULL, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4235
	    kmem_msb_arena, KMC_NOHASH);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4236
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4237
	kmem_bufctl_cache = kmem_cache_create("kmem_bufctl_cache",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4238
	    sizeof (kmem_bufctl_t), 0, NULL, NULL, NULL, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4239
	    kmem_msb_arena, KMC_NOHASH);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4240
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4241
	kmem_bufctl_audit_cache = kmem_cache_create("kmem_bufctl_audit_cache",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4242
	    sizeof (kmem_bufctl_audit_t), 0, NULL, NULL, NULL, NULL,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4243
	    kmem_msb_arena, KMC_NOHASH);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4244
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4245
	if (pass == 2) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4246
		kmem_va_arena = vmem_create("kmem_va",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4247
		    NULL, 0, PAGESIZE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4248
		    vmem_alloc, vmem_free, heap_arena,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4249
		    8 * PAGESIZE, VM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4250
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4251
		if (use_large_pages) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4252
			kmem_default_arena = vmem_xcreate("kmem_default",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4253
			    NULL, 0, PAGESIZE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4254
			    segkmem_alloc_lp, segkmem_free_lp, kmem_va_arena,
11178
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  4255
			    0, VMC_DUMPSAFE | VM_SLEEP);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4256
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4257
			kmem_default_arena = vmem_create("kmem_default",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4258
			    NULL, 0, PAGESIZE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4259
			    segkmem_alloc, segkmem_free, kmem_va_arena,
11178
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  4260
			    0, VMC_DUMPSAFE | VM_SLEEP);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4261
		}
9367
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4262
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4263
		/* Figure out what our maximum cache size is */
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4264
		maxbuf = kmem_max_cached;
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4265
		if (maxbuf <= KMEM_MAXBUF) {
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4266
			maxbuf = 0;
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4267
			kmem_max_cached = KMEM_MAXBUF;
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4268
		} else {
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4269
			size_t size = 0;
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4270
			size_t max =
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4271
			    sizeof (kmem_big_alloc_sizes) / sizeof (int);
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4272
			/*
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4273
			 * Round maxbuf up to an existing cache size.  If maxbuf
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4274
			 * is larger than the largest cache, we truncate it to
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4275
			 * the largest cache's size.
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4276
			 */
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4277
			for (i = 0; i < max; i++) {
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4278
				size = kmem_big_alloc_sizes[i];
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4279
				if (maxbuf <= size)
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4280
					break;
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4281
			}
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4282
			kmem_max_cached = maxbuf = size;
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4283
		}
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4284
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4285
		/*
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4286
		 * The big alloc table may not be completely overwritten, so
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4287
		 * we clear out any stale cache pointers from the first pass.
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4288
		 */
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4289
		bzero(kmem_big_alloc_table, sizeof (kmem_big_alloc_table));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4290
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4291
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4292
		 * During the first pass, the kmem_alloc_* caches
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4293
		 * are treated as metadata.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4294
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4295
		kmem_default_arena = kmem_msb_arena;
9367
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4296
		maxbuf = KMEM_BIG_MAXBUF_32BIT;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4297
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4298
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4299
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4300
	 * Set up the default caches to back kmem_alloc()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4301
	 */
9367
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4302
	kmem_alloc_caches_create(
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4303
	    kmem_alloc_sizes, sizeof (kmem_alloc_sizes) / sizeof (int),
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4304
	    kmem_alloc_table, KMEM_MAXBUF, KMEM_ALIGN_SHIFT);
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4305
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4306
	kmem_alloc_caches_create(
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4307
	    kmem_big_alloc_sizes, sizeof (kmem_big_alloc_sizes) / sizeof (int),
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4308
	    kmem_big_alloc_table, maxbuf, KMEM_BIG_SHIFT);
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4309
1f2604c227a1 6812655 need larger kmem caches for newer workloads
Jonathan W Adams <Jonathan.Adams@Sun.COM>
parents: 7546
diff changeset
  4310
	kmem_big_alloc_table_max = maxbuf >> KMEM_BIG_SHIFT;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4311
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4312
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4313
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4314
kmem_init(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4315
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4316
	kmem_cache_t *cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4317
	int old_kmem_flags = kmem_flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4318
	int use_large_pages = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4319
	size_t maxverify, minfirewall;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4320
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4321
	kstat_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4322
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4323
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4324
	 * Small-memory systems (< 24 MB) can't handle kmem_flags overhead.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4325
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4326
	if (physmem < btop(24 << 20) && !(old_kmem_flags & KMF_STICKY))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4327
		kmem_flags = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4328
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4329
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4330
	 * Don't do firewalled allocations if the heap is less than 1TB
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4331
	 * (i.e. on a 32-bit kernel)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4332
	 * The resulting VM_NEXTFIT allocations would create too much
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4333
	 * fragmentation in a small heap.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4334
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4335
#if defined(_LP64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4336
	maxverify = minfirewall = PAGESIZE / 2;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4337
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4338
	maxverify = minfirewall = ULONG_MAX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4339
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4340
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4341
	/* LINTED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4342
	ASSERT(sizeof (kmem_cpu_cache_t) == KMEM_CPU_CACHE_SIZE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4343
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4344
	list_create(&kmem_caches, sizeof (kmem_cache_t),
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4345
	    offsetof(kmem_cache_t, cache_link));
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4346
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4347
	kmem_metadata_arena = vmem_create("kmem_metadata", NULL, 0, PAGESIZE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4348
	    vmem_alloc, vmem_free, heap_arena, 8 * PAGESIZE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4349
	    VM_SLEEP | VMC_NO_QCACHE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4350
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4351
	kmem_msb_arena = vmem_create("kmem_msb", NULL, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4352
	    PAGESIZE, segkmem_alloc, segkmem_free, kmem_metadata_arena, 0,
11178
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  4353
	    VMC_DUMPSAFE | VM_SLEEP);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4354
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4355
	kmem_cache_arena = vmem_create("kmem_cache", NULL, 0, KMEM_ALIGN,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4356
	    segkmem_alloc, segkmem_free, kmem_metadata_arena, 0, VM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4357
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4358
	kmem_hash_arena = vmem_create("kmem_hash", NULL, 0, KMEM_ALIGN,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4359
	    segkmem_alloc, segkmem_free, kmem_metadata_arena, 0, VM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4360
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4361
	kmem_log_arena = vmem_create("kmem_log", NULL, 0, KMEM_ALIGN,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4362
	    segkmem_alloc, segkmem_free, heap_arena, 0, VM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4363
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4364
	kmem_firewall_va_arena = vmem_create("kmem_firewall_va",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4365
	    NULL, 0, PAGESIZE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4366
	    kmem_firewall_va_alloc, kmem_firewall_va_free, heap_arena,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4367
	    0, VM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4368
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4369
	kmem_firewall_arena = vmem_create("kmem_firewall", NULL, 0, PAGESIZE,
11178
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  4370
	    segkmem_alloc, segkmem_free, kmem_firewall_va_arena, 0,
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  4371
	    VMC_DUMPSAFE | VM_SLEEP);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4372
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4373
	/* temporary oversize arena for mod_read_system_file */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4374
	kmem_oversize_arena = vmem_create("kmem_oversize", NULL, 0, PAGESIZE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4375
	    segkmem_alloc, segkmem_free, heap_arena, 0, VM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4376
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4377
	kmem_reap_interval = 15 * hz;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4378
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4379
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4380
	 * Read /etc/system.  This is a chicken-and-egg problem because
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4381
	 * kmem_flags may be set in /etc/system, but mod_read_system_file()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4382
	 * needs to use the allocator.  The simplest solution is to create
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4383
	 * all the standard kmem caches, read /etc/system, destroy all the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4384
	 * caches we just created, and then create them all again in light
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4385
	 * of the (possibly) new kmem_flags and other kmem tunables.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4386
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4387
	kmem_cache_init(1, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4388
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4389
	mod_read_system_file(boothowto & RB_ASKNAME);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4390
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4391
	while ((cp = list_tail(&kmem_caches)) != NULL)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4392
		kmem_cache_destroy(cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4393
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4394
	vmem_destroy(kmem_oversize_arena);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4395
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4396
	if (old_kmem_flags & KMF_STICKY)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4397
		kmem_flags = old_kmem_flags;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4398
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4399
	if (!(kmem_flags & KMF_AUDIT))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4400
		vmem_seg_size = offsetof(vmem_seg_t, vs_thread);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4401
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4402
	if (kmem_maxverify == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4403
		kmem_maxverify = maxverify;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4404
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4405
	if (kmem_minfirewall == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4406
		kmem_minfirewall = minfirewall;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4407
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4408
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4409
	 * give segkmem a chance to figure out if we are using large pages
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4410
	 * for the kernel heap
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4411
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4412
	use_large_pages = segkmem_lpsetup();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4413
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4414
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4415
	 * To protect against corruption, we keep the actual number of callers
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4416
	 * KMF_LITE records seperate from the tunable.  We arbitrarily clamp
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4417
	 * to 16, since the overhead for small buffers quickly gets out of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4418
	 * hand.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4419
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4420
	 * The real limit would depend on the needs of the largest KMC_NOHASH
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4421
	 * cache.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4422
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4423
	kmem_lite_count = MIN(MAX(0, kmem_lite_pcs), 16);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4424
	kmem_lite_pcs = kmem_lite_count;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4425
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4426
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4427
	 * Normally, we firewall oversized allocations when possible, but
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4428
	 * if we are using large pages for kernel memory, and we don't have
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4429
	 * any non-LITE debugging flags set, we want to allocate oversized
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4430
	 * buffers from large pages, and so skip the firewalling.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4431
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4432
	if (use_large_pages &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4433
	    ((kmem_flags & KMF_LITE) || !(kmem_flags & KMF_DEBUG))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4434
		kmem_oversize_arena = vmem_xcreate("kmem_oversize", NULL, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4435
		    PAGESIZE, segkmem_alloc_lp, segkmem_free_lp, heap_arena,
11178
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  4436
		    0, VMC_DUMPSAFE | VM_SLEEP);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4437
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4438
		kmem_oversize_arena = vmem_create("kmem_oversize",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4439
		    NULL, 0, PAGESIZE,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4440
		    segkmem_alloc, segkmem_free, kmem_minfirewall < ULONG_MAX?
11178
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  4441
		    kmem_firewall_va_arena : heap_arena, 0, VMC_DUMPSAFE |
d671c0911ce4 6898505 kmem_verify oddities around Fast Crash Dump integration
Dave Plauger <Dave.Plauger@Sun.COM>
parents: 10217
diff changeset
  4442
		    VM_SLEEP);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4443
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4444
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4445
	kmem_cache_init(2, use_large_pages);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4446
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4447
	if (kmem_flags & (KMF_AUDIT | KMF_RANDOMIZE)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4448
		if (kmem_transaction_log_size == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4449
			kmem_transaction_log_size = kmem_maxavail() / 50;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4450
		kmem_transaction_log = kmem_log_init(kmem_transaction_log_size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4451
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4452
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4453
	if (kmem_flags & (KMF_CONTENTS | KMF_RANDOMIZE)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4454
		if (kmem_content_log_size == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4455
			kmem_content_log_size = kmem_maxavail() / 50;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4456
		kmem_content_log = kmem_log_init(kmem_content_log_size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4457
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4458
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4459
	kmem_failure_log = kmem_log_init(kmem_failure_log_size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4460
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4461
	kmem_slab_log = kmem_log_init(kmem_slab_log_size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4462
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4463
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4464
	 * Initialize STREAMS message caches so allocb() is available.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4465
	 * This allows us to initialize the logging framework (cmn_err(9F),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4466
	 * strlog(9F), etc) so we can start recording messages.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4467
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4468
	streams_msg_init();
2208
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4469
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4470
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4471
	 * Initialize the ZSD framework in Zones so modules loaded henceforth
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4472
	 * can register their callbacks.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4473
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4474
	zone_zsd_init();
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3290
diff changeset
  4475
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4476
	log_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4477
	taskq_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4478
2208
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4479
	/*
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4480
	 * Warn about invalid or dangerous values of kmem_flags.
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4481
	 * Always warn about unsupported values.
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4482
	 */
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4483
	if (((kmem_flags & ~(KMF_AUDIT | KMF_DEADBEEF | KMF_REDZONE |
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4484
	    KMF_CONTENTS | KMF_LITE)) != 0) ||
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4485
	    ((kmem_flags & KMF_LITE) && kmem_flags != KMF_LITE))
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4486
		cmn_err(CE_WARN, "kmem_flags set to unsupported value 0x%x. "
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4487
		    "See the Solaris Tunable Parameters Reference Manual.",
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4488
		    kmem_flags);
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4489
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4490
#ifdef DEBUG
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4491
	if ((kmem_flags & KMF_DEBUG) == 0)
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4492
		cmn_err(CE_NOTE, "kmem debugging disabled.");
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4493
#else
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4494
	/*
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4495
	 * For non-debug kernels, the only "normal" flags are 0, KMF_LITE,
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4496
	 * KMF_REDZONE, and KMF_CONTENTS (the last because it is only enabled
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4497
	 * if KMF_AUDIT is set). We should warn the user about the performance
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4498
	 * penalty of KMF_AUDIT or KMF_DEADBEEF if they are set and KMF_LITE
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4499
	 * isn't set (since that disables AUDIT).
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4500
	 */
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4501
	if (!(kmem_flags & KMF_LITE) &&
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4502
	    (kmem_flags & (KMF_AUDIT | KMF_DEADBEEF)) != 0)
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4503
		cmn_err(CE_WARN, "High-overhead kmem debugging features "
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4504
		    "enabled (kmem_flags = 0x%x).  Performance degradation "
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4505
		    "and large memory overhead possible. See the Solaris "
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4506
		    "Tunable Parameters Reference Manual.", kmem_flags);
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4507
#endif /* not DEBUG */
09bf0059b883 5053471 emit warning on non-DEBUG kernels when kmem flags are unsupported
dp201428
parents: 789
diff changeset
  4508
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4509
	kmem_cache_applyall(kmem_cache_magazine_enable, NULL, TQ_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4510
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4511
	kmem_ready = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4512
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4513
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4514
	 * Initialize the platform-specific aligned/DMA memory allocator.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4515
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4516
	ka_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4517
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4518
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4519
	 * Initialize 32-bit ID cache.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4520
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4521
	id32_init();
3448
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3290
diff changeset
  4522
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3290
diff changeset
  4523
	/*
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3290
diff changeset
  4524
	 * Initialize the networking stack so modules loaded can
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3290
diff changeset
  4525
	 * register their callbacks.
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3290
diff changeset
  4526
	 */
aaf16568054b PSARC 2006/366 IP Instances
dh155122
parents: 3290
diff changeset
  4527
	netstack_init();
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4528
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4529
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4530
static void
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4531
kmem_move_init(void)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4532
{
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4533
	kmem_defrag_cache = kmem_cache_create("kmem_defrag_cache",
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4534
	    sizeof (kmem_defrag_t), 0, NULL, NULL, NULL, NULL,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4535
	    kmem_msb_arena, KMC_NOHASH);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4536
	kmem_move_cache = kmem_cache_create("kmem_move_cache",
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4537
	    sizeof (kmem_move_t), 0, NULL, NULL, NULL, NULL,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4538
	    kmem_msb_arena, KMC_NOHASH);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4539
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4540
	/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4541
	 * kmem guarantees that move callbacks are sequential and that even
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4542
	 * across multiple caches no two moves ever execute simultaneously.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4543
	 * Move callbacks are processed on a separate taskq so that client code
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4544
	 * does not interfere with internal maintenance tasks.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4545
	 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4546
	kmem_move_taskq = taskq_create_instance("kmem_move_taskq", 0, 1,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4547
	    minclsyspri, 100, INT_MAX, TASKQ_PREPOPULATE);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4548
}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4549
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4550
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4551
kmem_thread_init(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4552
{
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4553
	kmem_move_init();
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4554
	kmem_taskq = taskq_create_instance("kmem_taskq", 0, 1, minclsyspri,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4555
	    300, INT_MAX, TASKQ_PREPOPULATE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4556
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4557
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4558
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4559
kmem_mp_init(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4560
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4561
	mutex_enter(&cpu_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4562
	register_cpu_setup_func(kmem_cpu_setup, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4563
	mutex_exit(&cpu_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4564
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4565
	kmem_update_timeout(NULL);
9515
d3b739d9d043 6586537 async zio taskqs can block out userland commands
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 9367
diff changeset
  4566
d3b739d9d043 6586537 async zio taskqs can block out userland commands
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 9367
diff changeset
  4567
	taskq_mp_init();
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  4568
}
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4569
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4570
/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4571
 * Return the slab of the allocated buffer, or NULL if the buffer is not
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4572
 * allocated. This function may be called with a known slab address to determine
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4573
 * whether or not the buffer is allocated, or with a NULL slab address to obtain
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4574
 * an allocated buffer's slab.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4575
 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4576
static kmem_slab_t *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4577
kmem_slab_allocated(kmem_cache_t *cp, kmem_slab_t *sp, void *buf)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4578
{
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4579
	kmem_bufctl_t *bcp, *bufbcp;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4580
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4581
	ASSERT(MUTEX_HELD(&cp->cache_lock));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4582
	ASSERT(sp == NULL || KMEM_SLAB_MEMBER(sp, buf));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4583
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4584
	if (cp->cache_flags & KMF_HASH) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4585
		for (bcp = *KMEM_HASH(cp, buf);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4586
		    (bcp != NULL) && (bcp->bc_addr != buf);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4587
		    bcp = bcp->bc_next) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4588
			continue;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4589
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4590
		ASSERT(sp != NULL && bcp != NULL ? sp == bcp->bc_slab : 1);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4591
		return (bcp == NULL ? NULL : bcp->bc_slab);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4592
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4593
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4594
	if (sp == NULL) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4595
		sp = KMEM_SLAB(cp, buf);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4596
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4597
	bufbcp = KMEM_BUFCTL(cp, buf);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4598
	for (bcp = sp->slab_head;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4599
	    (bcp != NULL) && (bcp != bufbcp);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4600
	    bcp = bcp->bc_next) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4601
		continue;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4602
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4603
	return (bcp == NULL ? sp : NULL);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4604
}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4605
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4606
static boolean_t
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4607
kmem_slab_is_reclaimable(kmem_cache_t *cp, kmem_slab_t *sp, int flags)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4608
{
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  4609
	long refcnt = sp->slab_refcnt;
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4610
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4611
	ASSERT(cp->cache_defrag != NULL);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4612
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  4613
	/*
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  4614
	 * For code coverage we want to be able to move an object within the
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  4615
	 * same slab (the only partial slab) even if allocating the destination
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  4616
	 * buffer resulted in a completely allocated slab.
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  4617
	 */
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  4618
	if (flags & KMM_DEBUG) {
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  4619
		return ((flags & KMM_DESPERATE) ||
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  4620
		    ((sp->slab_flags & KMEM_SLAB_NOMOVE) == 0));
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  4621
	}
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  4622
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4623
	/* If we're desperate, we don't care if the client said NO. */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4624
	if (flags & KMM_DESPERATE) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4625
		return (refcnt < sp->slab_chunks); /* any partial */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4626
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4627
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4628
	if (sp->slab_flags & KMEM_SLAB_NOMOVE) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4629
		return (B_FALSE);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4630
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4631
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  4632
	if ((refcnt == 1) || kmem_move_any_partial) {
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4633
		return (refcnt < sp->slab_chunks);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4634
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4635
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4636
	/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4637
	 * The reclaim threshold is adjusted at each kmem_cache_scan() so that
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4638
	 * slabs with a progressively higher percentage of used buffers can be
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4639
	 * reclaimed until the cache as a whole is no longer fragmented.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4640
	 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4641
	 *	sp->slab_refcnt   kmd_reclaim_numer
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4642
	 *	--------------- < ------------------
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4643
	 *	sp->slab_chunks   KMEM_VOID_FRACTION
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4644
	 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4645
	return ((refcnt * KMEM_VOID_FRACTION) <
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4646
	    (sp->slab_chunks * cp->cache_defrag->kmd_reclaim_numer));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4647
}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4648
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4649
static void *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4650
kmem_hunt_mag(kmem_cache_t *cp, kmem_magazine_t *m, int n, void *buf,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4651
    void *tbuf)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4652
{
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4653
	int i;		/* magazine round index */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4654
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4655
	for (i = 0; i < n; i++) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4656
		if (buf == m->mag_round[i]) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4657
			if (cp->cache_flags & KMF_BUFTAG) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4658
				(void) kmem_cache_free_debug(cp, tbuf,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4659
				    caller());
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4660
			}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4661
			m->mag_round[i] = tbuf;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4662
			return (buf);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4663
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4664
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4665
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4666
	return (NULL);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4667
}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4668
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4669
/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4670
 * Hunt the magazine layer for the given buffer. If found, the buffer is
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4671
 * removed from the magazine layer and returned, otherwise NULL is returned.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4672
 * The state of the returned buffer is freed and constructed.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4673
 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4674
static void *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4675
kmem_hunt_mags(kmem_cache_t *cp, void *buf)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4676
{
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4677
	kmem_cpu_cache_t *ccp;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4678
	kmem_magazine_t	*m;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4679
	int cpu_seqid;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4680
	int n;		/* magazine rounds */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4681
	void *tbuf;	/* temporary swap buffer */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4682
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4683
	ASSERT(MUTEX_NOT_HELD(&cp->cache_lock));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4684
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4685
	/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4686
	 * Allocated a buffer to swap with the one we hope to pull out of a
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4687
	 * magazine when found.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4688
	 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4689
	tbuf = kmem_cache_alloc(cp, KM_NOSLEEP);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4690
	if (tbuf == NULL) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4691
		KMEM_STAT_ADD(kmem_move_stats.kms_hunt_alloc_fail);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4692
		return (NULL);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4693
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4694
	if (tbuf == buf) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4695
		KMEM_STAT_ADD(kmem_move_stats.kms_hunt_lucky);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4696
		if (cp->cache_flags & KMF_BUFTAG) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4697
			(void) kmem_cache_free_debug(cp, buf, caller());
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4698
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4699
		return (buf);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4700
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4701
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4702
	/* Hunt the depot. */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4703
	mutex_enter(&cp->cache_depot_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4704
	n = cp->cache_magtype->mt_magsize;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4705
	for (m = cp->cache_full.ml_list; m != NULL; m = m->mag_next) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4706
		if (kmem_hunt_mag(cp, m, n, buf, tbuf) != NULL) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4707
			mutex_exit(&cp->cache_depot_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4708
			return (buf);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4709
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4710
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4711
	mutex_exit(&cp->cache_depot_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4713
	/* Hunt the per-CPU magazines. */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4714
	for (cpu_seqid = 0; cpu_seqid < max_ncpus; cpu_seqid++) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4715
		ccp = &cp->cache_cpu[cpu_seqid];
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4716
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4717
		mutex_enter(&ccp->cc_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4718
		m = ccp->cc_loaded;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4719
		n = ccp->cc_rounds;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4720
		if (kmem_hunt_mag(cp, m, n, buf, tbuf) != NULL) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4721
			mutex_exit(&ccp->cc_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4722
			return (buf);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4723
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4724
		m = ccp->cc_ploaded;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4725
		n = ccp->cc_prounds;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4726
		if (kmem_hunt_mag(cp, m, n, buf, tbuf) != NULL) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4727
			mutex_exit(&ccp->cc_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4728
			return (buf);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4729
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4730
		mutex_exit(&ccp->cc_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4731
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4732
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4733
	kmem_cache_free(cp, tbuf);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4734
	return (NULL);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4735
}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4736
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4737
/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4738
 * May be called from the kmem_move_taskq, from kmem_cache_move_notify_task(),
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4739
 * or when the buffer is freed.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4740
 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4741
static void
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4742
kmem_slab_move_yes(kmem_cache_t *cp, kmem_slab_t *sp, void *from_buf)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4743
{
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4744
	ASSERT(MUTEX_HELD(&cp->cache_lock));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4745
	ASSERT(KMEM_SLAB_MEMBER(sp, from_buf));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4746
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4747
	if (!KMEM_SLAB_IS_PARTIAL(sp)) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4748
		return;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4749
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4750
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4751
	if (sp->slab_flags & KMEM_SLAB_NOMOVE) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4752
		if (KMEM_SLAB_OFFSET(sp, from_buf) == sp->slab_stuck_offset) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4753
			avl_remove(&cp->cache_partial_slabs, sp);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4754
			sp->slab_flags &= ~KMEM_SLAB_NOMOVE;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4755
			sp->slab_stuck_offset = (uint32_t)-1;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4756
			avl_add(&cp->cache_partial_slabs, sp);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4757
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4758
	} else {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4759
		sp->slab_later_count = 0;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4760
		sp->slab_stuck_offset = (uint32_t)-1;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4761
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4762
}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4763
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4764
static void
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4765
kmem_slab_move_no(kmem_cache_t *cp, kmem_slab_t *sp, void *from_buf)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4766
{
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4767
	ASSERT(taskq_member(kmem_move_taskq, curthread));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4768
	ASSERT(MUTEX_HELD(&cp->cache_lock));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4769
	ASSERT(KMEM_SLAB_MEMBER(sp, from_buf));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4770
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4771
	if (!KMEM_SLAB_IS_PARTIAL(sp)) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4772
		return;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4773
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4774
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4775
	avl_remove(&cp->cache_partial_slabs, sp);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4776
	sp->slab_later_count = 0;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4777
	sp->slab_flags |= KMEM_SLAB_NOMOVE;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4778
	sp->slab_stuck_offset = KMEM_SLAB_OFFSET(sp, from_buf);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4779
	avl_add(&cp->cache_partial_slabs, sp);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4780
}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4781
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4782
static void kmem_move_end(kmem_cache_t *, kmem_move_t *);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4783
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4784
/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4785
 * The move callback takes two buffer addresses, the buffer to be moved, and a
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4786
 * newly allocated and constructed buffer selected by kmem as the destination.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4787
 * It also takes the size of the buffer and an optional user argument specified
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4788
 * at cache creation time. kmem guarantees that the buffer to be moved has not
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4789
 * been unmapped by the virtual memory subsystem. Beyond that, it cannot
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4790
 * guarantee the present whereabouts of the buffer to be moved, so it is up to
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4791
 * the client to safely determine whether or not it is still using the buffer.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4792
 * The client must not free either of the buffers passed to the move callback,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4793
 * since kmem wants to free them directly to the slab layer. The client response
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4794
 * tells kmem which of the two buffers to free:
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4795
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4796
 * YES		kmem frees the old buffer (the move was successful)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4797
 * NO		kmem frees the new buffer, marks the slab of the old buffer
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4798
 *              non-reclaimable to avoid bothering the client again
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4799
 * LATER	kmem frees the new buffer, increments slab_later_count
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4800
 * DONT_KNOW	kmem frees the new buffer, searches mags for the old buffer
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4801
 * DONT_NEED	kmem frees both the old buffer and the new buffer
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4802
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4803
 * The pending callback argument now being processed contains both of the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4804
 * buffers (old and new) passed to the move callback function, the slab of the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4805
 * old buffer, and flags related to the move request, such as whether or not the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4806
 * system was desperate for memory.
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  4807
 *
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  4808
 * Slabs are not freed while there is a pending callback, but instead are kept
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  4809
 * on a deadlist, which is drained after the last callback completes. This means
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  4810
 * that slabs are safe to access until kmem_move_end(), no matter how many of
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  4811
 * their buffers have been freed. Once slab_refcnt reaches zero, it stays at
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  4812
 * zero for as long as the slab remains on the deadlist and until the slab is
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  4813
 * freed.
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4814
 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4815
static void
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4816
kmem_move_buffer(kmem_move_t *callback)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4817
{
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4818
	kmem_cbrc_t response;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4819
	kmem_slab_t *sp = callback->kmm_from_slab;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4820
	kmem_cache_t *cp = sp->slab_cache;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4821
	boolean_t free_on_slab;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4822
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4823
	ASSERT(taskq_member(kmem_move_taskq, curthread));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4824
	ASSERT(MUTEX_NOT_HELD(&cp->cache_lock));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4825
	ASSERT(KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4826
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4827
	/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4828
	 * The number of allocated buffers on the slab may have changed since we
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4829
	 * last checked the slab's reclaimability (when the pending move was
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4830
	 * enqueued), or the client may have responded NO when asked to move
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4831
	 * another buffer on the same slab.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4832
	 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4833
	if (!kmem_slab_is_reclaimable(cp, sp, callback->kmm_flags)) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4834
		KMEM_STAT_ADD(kmem_move_stats.kms_no_longer_reclaimable);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4835
		KMEM_STAT_COND_ADD((callback->kmm_flags & KMM_NOTIFY),
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4836
		    kmem_move_stats.kms_notify_no_longer_reclaimable);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4837
		kmem_slab_free(cp, callback->kmm_to_buf);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4838
		kmem_move_end(cp, callback);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4839
		return;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4840
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4841
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4842
	/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4843
	 * Hunting magazines is expensive, so we'll wait to do that until the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4844
	 * client responds KMEM_CBRC_DONT_KNOW. However, checking the slab layer
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4845
	 * is cheap, so we might as well do that here in case we can avoid
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4846
	 * bothering the client.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4847
	 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4848
	mutex_enter(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4849
	free_on_slab = (kmem_slab_allocated(cp, sp,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4850
	    callback->kmm_from_buf) == NULL);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4851
	mutex_exit(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4852
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4853
	if (free_on_slab) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4854
		KMEM_STAT_ADD(kmem_move_stats.kms_hunt_found_slab);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4855
		kmem_slab_free(cp, callback->kmm_to_buf);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4856
		kmem_move_end(cp, callback);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4857
		return;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4858
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4859
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4860
	if (cp->cache_flags & KMF_BUFTAG) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4861
		/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4862
		 * Make kmem_cache_alloc_debug() apply the constructor for us.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4863
		 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4864
		if (kmem_cache_alloc_debug(cp, callback->kmm_to_buf,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4865
		    KM_NOSLEEP, 1, caller()) != 0) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4866
			KMEM_STAT_ADD(kmem_move_stats.kms_alloc_fail);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4867
			kmem_move_end(cp, callback);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4868
			return;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4869
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4870
	} else if (cp->cache_constructor != NULL &&
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4871
	    cp->cache_constructor(callback->kmm_to_buf, cp->cache_private,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4872
	    KM_NOSLEEP) != 0) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4873
		atomic_add_64(&cp->cache_alloc_fail, 1);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4874
		KMEM_STAT_ADD(kmem_move_stats.kms_constructor_fail);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4875
		kmem_slab_free(cp, callback->kmm_to_buf);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4876
		kmem_move_end(cp, callback);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4877
		return;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4878
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4879
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4880
	KMEM_STAT_ADD(kmem_move_stats.kms_callbacks);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4881
	KMEM_STAT_COND_ADD((callback->kmm_flags & KMM_NOTIFY),
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4882
	    kmem_move_stats.kms_notify_callbacks);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4883
	cp->cache_defrag->kmd_callbacks++;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4884
	cp->cache_defrag->kmd_thread = curthread;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4885
	cp->cache_defrag->kmd_from_buf = callback->kmm_from_buf;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4886
	cp->cache_defrag->kmd_to_buf = callback->kmm_to_buf;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4887
	DTRACE_PROBE2(kmem__move__start, kmem_cache_t *, cp, kmem_move_t *,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4888
	    callback);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4889
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4890
	response = cp->cache_move(callback->kmm_from_buf,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4891
	    callback->kmm_to_buf, cp->cache_bufsize, cp->cache_private);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4892
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4893
	DTRACE_PROBE3(kmem__move__end, kmem_cache_t *, cp, kmem_move_t *,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4894
	    callback, kmem_cbrc_t, response);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4895
	cp->cache_defrag->kmd_thread = NULL;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4896
	cp->cache_defrag->kmd_from_buf = NULL;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4897
	cp->cache_defrag->kmd_to_buf = NULL;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4898
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4899
	if (response == KMEM_CBRC_YES) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4900
		KMEM_STAT_ADD(kmem_move_stats.kms_yes);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4901
		cp->cache_defrag->kmd_yes++;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4902
		kmem_slab_free_constructed(cp, callback->kmm_from_buf, B_FALSE);
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  4903
		/* slab safe to access until kmem_move_end() */
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  4904
		if (sp->slab_refcnt == 0)
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  4905
			cp->cache_defrag->kmd_slabs_freed++;
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4906
		mutex_enter(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4907
		kmem_slab_move_yes(cp, sp, callback->kmm_from_buf);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4908
		mutex_exit(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4909
		kmem_move_end(cp, callback);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4910
		return;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4911
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4912
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4913
	switch (response) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4914
	case KMEM_CBRC_NO:
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4915
		KMEM_STAT_ADD(kmem_move_stats.kms_no);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4916
		cp->cache_defrag->kmd_no++;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4917
		mutex_enter(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4918
		kmem_slab_move_no(cp, sp, callback->kmm_from_buf);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4919
		mutex_exit(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4920
		break;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4921
	case KMEM_CBRC_LATER:
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4922
		KMEM_STAT_ADD(kmem_move_stats.kms_later);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4923
		cp->cache_defrag->kmd_later++;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4924
		mutex_enter(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4925
		if (!KMEM_SLAB_IS_PARTIAL(sp)) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4926
			mutex_exit(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4927
			break;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4928
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4929
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4930
		if (++sp->slab_later_count >= KMEM_DISBELIEF) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4931
			KMEM_STAT_ADD(kmem_move_stats.kms_disbelief);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4932
			kmem_slab_move_no(cp, sp, callback->kmm_from_buf);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4933
		} else if (!(sp->slab_flags & KMEM_SLAB_NOMOVE)) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4934
			sp->slab_stuck_offset = KMEM_SLAB_OFFSET(sp,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4935
			    callback->kmm_from_buf);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4936
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4937
		mutex_exit(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4938
		break;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4939
	case KMEM_CBRC_DONT_NEED:
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4940
		KMEM_STAT_ADD(kmem_move_stats.kms_dont_need);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4941
		cp->cache_defrag->kmd_dont_need++;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4942
		kmem_slab_free_constructed(cp, callback->kmm_from_buf, B_FALSE);
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  4943
		if (sp->slab_refcnt == 0)
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  4944
			cp->cache_defrag->kmd_slabs_freed++;
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4945
		mutex_enter(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4946
		kmem_slab_move_yes(cp, sp, callback->kmm_from_buf);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4947
		mutex_exit(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4948
		break;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4949
	case KMEM_CBRC_DONT_KNOW:
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4950
		KMEM_STAT_ADD(kmem_move_stats.kms_dont_know);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4951
		cp->cache_defrag->kmd_dont_know++;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4952
		if (kmem_hunt_mags(cp, callback->kmm_from_buf) != NULL) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4953
			KMEM_STAT_ADD(kmem_move_stats.kms_hunt_found_mag);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4954
			cp->cache_defrag->kmd_hunt_found++;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4955
			kmem_slab_free_constructed(cp, callback->kmm_from_buf,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4956
			    B_TRUE);
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  4957
			if (sp->slab_refcnt == 0)
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  4958
				cp->cache_defrag->kmd_slabs_freed++;
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4959
			mutex_enter(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4960
			kmem_slab_move_yes(cp, sp, callback->kmm_from_buf);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4961
			mutex_exit(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4962
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4963
		break;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4964
	default:
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4965
		panic("'%s' (%p) unexpected move callback response %d\n",
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4966
		    cp->cache_name, (void *)cp, response);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4967
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4968
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4969
	kmem_slab_free_constructed(cp, callback->kmm_to_buf, B_FALSE);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4970
	kmem_move_end(cp, callback);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4971
}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4972
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4973
/* Return B_FALSE if there is insufficient memory for the move request. */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4974
static boolean_t
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4975
kmem_move_begin(kmem_cache_t *cp, kmem_slab_t *sp, void *buf, int flags)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4976
{
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4977
	void *to_buf;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4978
	avl_index_t index;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4979
	kmem_move_t *callback, *pending;
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  4980
	ulong_t n;
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4981
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4982
	ASSERT(taskq_member(kmem_taskq, curthread));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4983
	ASSERT(MUTEX_NOT_HELD(&cp->cache_lock));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4984
	ASSERT(sp->slab_flags & KMEM_SLAB_MOVE_PENDING);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4985
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4986
	callback = kmem_cache_alloc(kmem_move_cache, KM_NOSLEEP);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4987
	if (callback == NULL) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4988
		KMEM_STAT_ADD(kmem_move_stats.kms_callback_alloc_fail);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4989
		return (B_FALSE);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4990
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4991
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4992
	callback->kmm_from_slab = sp;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4993
	callback->kmm_from_buf = buf;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4994
	callback->kmm_flags = flags;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4995
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4996
	mutex_enter(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  4997
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  4998
	n = avl_numnodes(&cp->cache_partial_slabs);
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  4999
	if ((n == 0) || ((n == 1) && !(flags & KMM_DEBUG))) {
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5000
		mutex_exit(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5001
		kmem_cache_free(kmem_move_cache, callback);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5002
		return (B_TRUE); /* there is no need for the move request */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5003
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5004
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5005
	pending = avl_find(&cp->cache_defrag->kmd_moves_pending, buf, &index);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5006
	if (pending != NULL) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5007
		/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5008
		 * If the move is already pending and we're desperate now,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5009
		 * update the move flags.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5010
		 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5011
		if (flags & KMM_DESPERATE) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5012
			pending->kmm_flags |= KMM_DESPERATE;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5013
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5014
		mutex_exit(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5015
		KMEM_STAT_ADD(kmem_move_stats.kms_already_pending);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5016
		kmem_cache_free(kmem_move_cache, callback);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5017
		return (B_TRUE);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5018
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5019
12093
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  5020
	to_buf = kmem_slab_alloc_impl(cp, avl_first(&cp->cache_partial_slabs),
fa0c0f5bf466 6538954 kmem_cache_alloc() doesn't scale for anon structure allocations when cache magazines are empty
David Valin <David.Valin@Sun.COM>
parents: 11178
diff changeset
  5021
	    B_FALSE);
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5022
	callback->kmm_to_buf = to_buf;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5023
	avl_insert(&cp->cache_defrag->kmd_moves_pending, callback, index);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5024
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5025
	mutex_exit(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5026
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5027
	if (!taskq_dispatch(kmem_move_taskq, (task_func_t *)kmem_move_buffer,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5028
	    callback, TQ_NOSLEEP)) {
6908
f5c1c68a07ca 6712962 mutex_destroy: bad mutex at zfs_znode_cache_destructor
tomee
parents: 6819
diff changeset
  5029
		KMEM_STAT_ADD(kmem_move_stats.kms_callback_taskq_fail);
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5030
		mutex_enter(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5031
		avl_remove(&cp->cache_defrag->kmd_moves_pending, callback);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5032
		mutex_exit(&cp->cache_lock);
6908
f5c1c68a07ca 6712962 mutex_destroy: bad mutex at zfs_znode_cache_destructor
tomee
parents: 6819
diff changeset
  5033
		kmem_slab_free(cp, to_buf);
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5034
		kmem_cache_free(kmem_move_cache, callback);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5035
		return (B_FALSE);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5036
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5037
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5038
	return (B_TRUE);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5039
}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5040
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5041
static void
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5042
kmem_move_end(kmem_cache_t *cp, kmem_move_t *callback)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5043
{
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5044
	avl_index_t index;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5045
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5046
	ASSERT(cp->cache_defrag != NULL);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5047
	ASSERT(taskq_member(kmem_move_taskq, curthread));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5048
	ASSERT(MUTEX_NOT_HELD(&cp->cache_lock));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5049
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5050
	mutex_enter(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5051
	VERIFY(avl_find(&cp->cache_defrag->kmd_moves_pending,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5052
	    callback->kmm_from_buf, &index) != NULL);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5053
	avl_remove(&cp->cache_defrag->kmd_moves_pending, callback);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5054
	if (avl_is_empty(&cp->cache_defrag->kmd_moves_pending)) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5055
		list_t *deadlist = &cp->cache_defrag->kmd_deadlist;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5056
		kmem_slab_t *sp;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5057
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5058
		/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5059
		 * The last pending move completed. Release all slabs from the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5060
		 * front of the dead list except for any slab at the tail that
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5061
		 * needs to be released from the context of kmem_move_buffers().
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5062
		 * kmem deferred unmapping the buffers on these slabs in order
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5063
		 * to guarantee that buffers passed to the move callback have
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5064
		 * been touched only by kmem or by the client itself.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5065
		 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5066
		while ((sp = list_remove_head(deadlist)) != NULL) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5067
			if (sp->slab_flags & KMEM_SLAB_MOVE_PENDING) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5068
				list_insert_tail(deadlist, sp);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5069
				break;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5070
			}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5071
			cp->cache_defrag->kmd_deadcount--;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5072
			cp->cache_slab_destroy++;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5073
			mutex_exit(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5074
			kmem_slab_destroy(cp, sp);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5075
			KMEM_STAT_ADD(kmem_move_stats.kms_dead_slabs_freed);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5076
			mutex_enter(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5077
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5078
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5079
	mutex_exit(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5080
	kmem_cache_free(kmem_move_cache, callback);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5081
}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5082
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5083
/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5084
 * Move buffers from least used slabs first by scanning backwards from the end
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5085
 * of the partial slab list. Scan at most max_scan candidate slabs and move
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5086
 * buffers from at most max_slabs slabs (0 for all partial slabs in both cases).
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5087
 * If desperate to reclaim memory, move buffers from any partial slab, otherwise
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5088
 * skip slabs with a ratio of allocated buffers at or above the current
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5089
 * threshold. Return the number of unskipped slabs (at most max_slabs, -1 if the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5090
 * scan is aborted) so that the caller can adjust the reclaimability threshold
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5091
 * depending on how many reclaimable slabs it finds.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5092
 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5093
 * kmem_move_buffers() drops and reacquires cache_lock every time it issues a
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5094
 * move request, since it is not valid for kmem_move_begin() to call
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5095
 * kmem_cache_alloc() or taskq_dispatch() with cache_lock held.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5096
 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5097
static int
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5098
kmem_move_buffers(kmem_cache_t *cp, size_t max_scan, size_t max_slabs,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5099
    int flags)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5100
{
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5101
	kmem_slab_t *sp;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5102
	void *buf;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5103
	int i, j; /* slab index, buffer index */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5104
	int s; /* reclaimable slabs */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5105
	int b; /* allocated (movable) buffers on reclaimable slab */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5106
	boolean_t success;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5107
	int refcnt;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5108
	int nomove;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5109
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5110
	ASSERT(taskq_member(kmem_taskq, curthread));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5111
	ASSERT(MUTEX_HELD(&cp->cache_lock));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5112
	ASSERT(kmem_move_cache != NULL);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5113
	ASSERT(cp->cache_move != NULL && cp->cache_defrag != NULL);
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5114
	ASSERT((flags & KMM_DEBUG) ? !avl_is_empty(&cp->cache_partial_slabs) :
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5115
	    avl_numnodes(&cp->cache_partial_slabs) > 1);
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5116
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5117
	if (kmem_move_blocked) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5118
		return (0);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5119
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5120
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5121
	if (kmem_move_fulltilt) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5122
		flags |= KMM_DESPERATE;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5123
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5124
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5125
	if (max_scan == 0 || (flags & KMM_DESPERATE)) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5126
		/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5127
		 * Scan as many slabs as needed to find the desired number of
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5128
		 * candidate slabs.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5129
		 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5130
		max_scan = (size_t)-1;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5131
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5132
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5133
	if (max_slabs == 0 || (flags & KMM_DESPERATE)) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5134
		/* Find as many candidate slabs as possible. */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5135
		max_slabs = (size_t)-1;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5136
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5137
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5138
	sp = avl_last(&cp->cache_partial_slabs);
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5139
	ASSERT(KMEM_SLAB_IS_PARTIAL(sp));
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5140
	for (i = 0, s = 0; (i < max_scan) && (s < max_slabs) && (sp != NULL) &&
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5141
	    ((sp != avl_first(&cp->cache_partial_slabs)) ||
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5142
	    (flags & KMM_DEBUG));
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5143
	    sp = AVL_PREV(&cp->cache_partial_slabs, sp), i++) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5144
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5145
		if (!kmem_slab_is_reclaimable(cp, sp, flags)) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5146
			continue;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5147
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5148
		s++;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5149
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5150
		/* Look for allocated buffers to move. */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5151
		for (j = 0, b = 0, buf = sp->slab_base;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5152
		    (j < sp->slab_chunks) && (b < sp->slab_refcnt);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5153
		    buf = (((char *)buf) + cp->cache_chunksize), j++) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5154
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5155
			if (kmem_slab_allocated(cp, sp, buf) == NULL) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5156
				continue;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5157
			}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5158
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5159
			b++;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5160
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5161
			/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5162
			 * Prevent the slab from being destroyed while we drop
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5163
			 * cache_lock and while the pending move is not yet
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5164
			 * registered. Flag the pending move while
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5165
			 * kmd_moves_pending may still be empty, since we can't
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5166
			 * yet rely on a non-zero pending move count to prevent
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5167
			 * the slab from being destroyed.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5168
			 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5169
			ASSERT(!(sp->slab_flags & KMEM_SLAB_MOVE_PENDING));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5170
			sp->slab_flags |= KMEM_SLAB_MOVE_PENDING;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5171
			/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5172
			 * Recheck refcnt and nomove after reacquiring the lock,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5173
			 * since these control the order of partial slabs, and
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5174
			 * we want to know if we can pick up the scan where we
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5175
			 * left off.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5176
			 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5177
			refcnt = sp->slab_refcnt;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5178
			nomove = (sp->slab_flags & KMEM_SLAB_NOMOVE);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5179
			mutex_exit(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5180
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5181
			success = kmem_move_begin(cp, sp, buf, flags);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5182
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5183
			/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5184
			 * Now, before the lock is reacquired, kmem could
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5185
			 * process all pending move requests and purge the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5186
			 * deadlist, so that upon reacquiring the lock, sp has
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5187
			 * been remapped. Or, the client may free all the
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5188
			 * objects on the slab while the pending moves are still
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5189
			 * on the taskq. Therefore, the KMEM_SLAB_MOVE_PENDING
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5190
			 * flag causes the slab to be put at the end of the
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5191
			 * deadlist and prevents it from being destroyed, since
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5192
			 * we plan to destroy it here after reacquiring the
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5193
			 * lock.
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5194
			 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5195
			mutex_enter(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5196
			ASSERT(sp->slab_flags & KMEM_SLAB_MOVE_PENDING);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5197
			sp->slab_flags &= ~KMEM_SLAB_MOVE_PENDING;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5198
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5199
			if (sp->slab_refcnt == 0) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5200
				list_t *deadlist =
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5201
				    &cp->cache_defrag->kmd_deadlist;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5202
				list_remove(deadlist, sp);
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5203
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5204
				if (!avl_is_empty(
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5205
				    &cp->cache_defrag->kmd_moves_pending)) {
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5206
					/*
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5207
					 * A pending move makes it unsafe to
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5208
					 * destroy the slab, because even though
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5209
					 * the move is no longer needed, the
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5210
					 * context where that is determined
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5211
					 * requires the slab to exist.
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5212
					 * Fortunately, a pending move also
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5213
					 * means we don't need to destroy the
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5214
					 * slab here, since it will get
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5215
					 * destroyed along with any other slabs
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5216
					 * on the deadlist after the last
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5217
					 * pending move completes.
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5218
					 */
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5219
					list_insert_head(deadlist, sp);
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5220
					KMEM_STAT_ADD(kmem_move_stats.
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5221
					    kms_endscan_slab_dead);
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5222
					return (-1);
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5223
				}
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5224
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5225
				/*
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5226
				 * Destroy the slab now if it was completely
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5227
				 * freed while we dropped cache_lock and there
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5228
				 * are no pending moves. Since slab_refcnt
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5229
				 * cannot change once it reaches zero, no new
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5230
				 * pending moves from that slab are possible.
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5231
				 */
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5232
				cp->cache_defrag->kmd_deadcount--;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5233
				cp->cache_slab_destroy++;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5234
				mutex_exit(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5235
				kmem_slab_destroy(cp, sp);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5236
				KMEM_STAT_ADD(kmem_move_stats.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5237
				    kms_dead_slabs_freed);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5238
				KMEM_STAT_ADD(kmem_move_stats.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5239
				    kms_endscan_slab_destroyed);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5240
				mutex_enter(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5241
				/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5242
				 * Since we can't pick up the scan where we left
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5243
				 * off, abort the scan and say nothing about the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5244
				 * number of reclaimable slabs.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5245
				 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5246
				return (-1);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5247
			}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5248
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5249
			if (!success) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5250
				/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5251
				 * Abort the scan if there is not enough memory
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5252
				 * for the request and say nothing about the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5253
				 * number of reclaimable slabs.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5254
				 */
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5255
				KMEM_STAT_COND_ADD(s < max_slabs,
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5256
				    kmem_move_stats.kms_endscan_nomem);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5257
				return (-1);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5258
			}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5259
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5260
			/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5261
			 * The slab's position changed while the lock was
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5262
			 * dropped, so we don't know where we are in the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5263
			 * sequence any more.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5264
			 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5265
			if (sp->slab_refcnt != refcnt) {
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5266
				/*
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5267
				 * If this is a KMM_DEBUG move, the slab_refcnt
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5268
				 * may have changed because we allocated a
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5269
				 * destination buffer on the same slab. In that
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5270
				 * case, we're not interested in counting it.
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5271
				 */
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5272
				KMEM_STAT_COND_ADD(!(flags & KMM_DEBUG) &&
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5273
				    (s < max_slabs),
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5274
				    kmem_move_stats.kms_endscan_refcnt_changed);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5275
				return (-1);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5276
			}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5277
			if ((sp->slab_flags & KMEM_SLAB_NOMOVE) != nomove) {
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5278
				KMEM_STAT_COND_ADD(s < max_slabs,
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5279
				    kmem_move_stats.kms_endscan_nomove_changed);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5280
				return (-1);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5281
			}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5282
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5283
			/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5284
			 * Generating a move request allocates a destination
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5285
			 * buffer from the slab layer, bumping the first partial
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5286
			 * slab if it is completely allocated. If the current
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5287
			 * slab becomes the first partial slab as a result, we
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5288
			 * can't continue to scan backwards.
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5289
			 *
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5290
			 * If this is a KMM_DEBUG move and we allocated the
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5291
			 * destination buffer from the last partial slab, then
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5292
			 * the buffer we're moving is on the same slab and our
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5293
			 * slab_refcnt has changed, causing us to return before
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5294
			 * reaching here if there are no partial slabs left.
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5295
			 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5296
			ASSERT(!avl_is_empty(&cp->cache_partial_slabs));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5297
			if (sp == avl_first(&cp->cache_partial_slabs)) {
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5298
				/*
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5299
				 * We're not interested in a second KMM_DEBUG
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5300
				 * move.
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5301
				 */
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5302
				goto end_scan;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5303
			}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5304
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5305
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5306
end_scan:
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5307
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5308
	KMEM_STAT_COND_ADD(!(flags & KMM_DEBUG) &&
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5309
	    (s < max_slabs) &&
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5310
	    (sp == avl_first(&cp->cache_partial_slabs)),
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5311
	    kmem_move_stats.kms_endscan_freelist);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5312
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5313
	return (s);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5314
}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5315
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5316
typedef struct kmem_move_notify_args {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5317
	kmem_cache_t *kmna_cache;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5318
	void *kmna_buf;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5319
} kmem_move_notify_args_t;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5320
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5321
static void
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5322
kmem_cache_move_notify_task(void *arg)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5323
{
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5324
	kmem_move_notify_args_t *args = arg;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5325
	kmem_cache_t *cp = args->kmna_cache;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5326
	void *buf = args->kmna_buf;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5327
	kmem_slab_t *sp;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5328
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5329
	ASSERT(taskq_member(kmem_taskq, curthread));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5330
	ASSERT(list_link_active(&cp->cache_link));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5331
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5332
	kmem_free(args, sizeof (kmem_move_notify_args_t));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5333
	mutex_enter(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5334
	sp = kmem_slab_allocated(cp, NULL, buf);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5335
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5336
	/* Ignore the notification if the buffer is no longer allocated. */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5337
	if (sp == NULL) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5338
		mutex_exit(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5339
		return;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5340
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5341
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5342
	/* Ignore the notification if there's no reason to move the buffer. */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5343
	if (avl_numnodes(&cp->cache_partial_slabs) > 1) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5344
		/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5345
		 * So far the notification is not ignored. Ignore the
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5346
		 * notification if the slab is not marked by an earlier refusal
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5347
		 * to move a buffer.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5348
		 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5349
		if (!(sp->slab_flags & KMEM_SLAB_NOMOVE) &&
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5350
		    (sp->slab_later_count == 0)) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5351
			mutex_exit(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5352
			return;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5353
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5354
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5355
		kmem_slab_move_yes(cp, sp, buf);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5356
		ASSERT(!(sp->slab_flags & KMEM_SLAB_MOVE_PENDING));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5357
		sp->slab_flags |= KMEM_SLAB_MOVE_PENDING;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5358
		mutex_exit(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5359
		/* see kmem_move_buffers() about dropping the lock */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5360
		(void) kmem_move_begin(cp, sp, buf, KMM_NOTIFY);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5361
		mutex_enter(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5362
		ASSERT(sp->slab_flags & KMEM_SLAB_MOVE_PENDING);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5363
		sp->slab_flags &= ~KMEM_SLAB_MOVE_PENDING;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5364
		if (sp->slab_refcnt == 0) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5365
			list_t *deadlist = &cp->cache_defrag->kmd_deadlist;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5366
			list_remove(deadlist, sp);
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5367
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5368
			if (!avl_is_empty(
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5369
			    &cp->cache_defrag->kmd_moves_pending)) {
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5370
				list_insert_head(deadlist, sp);
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5371
				mutex_exit(&cp->cache_lock);
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5372
				KMEM_STAT_ADD(kmem_move_stats.
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5373
				    kms_notify_slab_dead);
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5374
				return;
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5375
			}
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5376
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5377
			cp->cache_defrag->kmd_deadcount--;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5378
			cp->cache_slab_destroy++;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5379
			mutex_exit(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5380
			kmem_slab_destroy(cp, sp);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5381
			KMEM_STAT_ADD(kmem_move_stats.kms_dead_slabs_freed);
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5382
			KMEM_STAT_ADD(kmem_move_stats.
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5383
			    kms_notify_slab_destroyed);
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5384
			return;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5385
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5386
	} else {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5387
		kmem_slab_move_yes(cp, sp, buf);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5388
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5389
	mutex_exit(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5390
}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5391
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5392
void
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5393
kmem_cache_move_notify(kmem_cache_t *cp, void *buf)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5394
{
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5395
	kmem_move_notify_args_t *args;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5396
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5397
	KMEM_STAT_ADD(kmem_move_stats.kms_notify);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5398
	args = kmem_alloc(sizeof (kmem_move_notify_args_t), KM_NOSLEEP);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5399
	if (args != NULL) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5400
		args->kmna_cache = cp;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5401
		args->kmna_buf = buf;
6733
1db40e194d28 6707352 failed taskq_dispatch() in kmem_cache_move_notify() is leaky
tomee
parents: 6712
diff changeset
  5402
		if (!taskq_dispatch(kmem_taskq,
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5403
		    (task_func_t *)kmem_cache_move_notify_task, args,
6733
1db40e194d28 6707352 failed taskq_dispatch() in kmem_cache_move_notify() is leaky
tomee
parents: 6712
diff changeset
  5404
		    TQ_NOSLEEP))
1db40e194d28 6707352 failed taskq_dispatch() in kmem_cache_move_notify() is leaky
tomee
parents: 6712
diff changeset
  5405
			kmem_free(args, sizeof (kmem_move_notify_args_t));
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5406
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5407
}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5408
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5409
static void
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5410
kmem_cache_defrag(kmem_cache_t *cp)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5411
{
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5412
	size_t n;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5413
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5414
	ASSERT(cp->cache_defrag != NULL);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5415
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5416
	mutex_enter(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5417
	n = avl_numnodes(&cp->cache_partial_slabs);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5418
	if (n > 1) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5419
		/* kmem_move_buffers() drops and reacquires cache_lock */
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5420
		KMEM_STAT_ADD(kmem_move_stats.kms_defrags);
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5421
		cp->cache_defrag->kmd_defrags++;
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5422
		(void) kmem_move_buffers(cp, n, 0, KMM_DESPERATE);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5423
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5424
	mutex_exit(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5425
}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5426
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5427
/* Is this cache above the fragmentation threshold? */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5428
static boolean_t
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5429
kmem_cache_frag_threshold(kmem_cache_t *cp, uint64_t nfree)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5430
{
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5431
	/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5432
	 *	nfree		kmem_frag_numer
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5433
	 * ------------------ > ---------------
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5434
	 * cp->cache_buftotal	kmem_frag_denom
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5435
	 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5436
	return ((nfree * kmem_frag_denom) >
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5437
	    (cp->cache_buftotal * kmem_frag_numer));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5438
}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5439
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5440
static boolean_t
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5441
kmem_cache_is_fragmented(kmem_cache_t *cp, boolean_t *doreap)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5442
{
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5443
	boolean_t fragmented;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5444
	uint64_t nfree;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5445
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5446
	ASSERT(MUTEX_HELD(&cp->cache_lock));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5447
	*doreap = B_FALSE;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5448
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5449
	if (kmem_move_fulltilt) {
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5450
		if (avl_numnodes(&cp->cache_partial_slabs) > 1) {
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5451
			return (B_TRUE);
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5452
		}
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5453
	} else {
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5454
		if ((cp->cache_complete_slab_count + avl_numnodes(
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5455
		    &cp->cache_partial_slabs)) < kmem_frag_minslabs) {
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5456
			return (B_FALSE);
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5457
		}
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5458
	}
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5459
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5460
	nfree = cp->cache_bufslab;
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5461
	fragmented = ((avl_numnodes(&cp->cache_partial_slabs) > 1) &&
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5462
	    kmem_cache_frag_threshold(cp, nfree));
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5463
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5464
	/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5465
	 * Free buffers in the magazine layer appear allocated from the point of
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5466
	 * view of the slab layer. We want to know if the slab layer would
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5467
	 * appear fragmented if we included free buffers from magazines that
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5468
	 * have fallen out of the working set.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5469
	 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5470
	if (!fragmented) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5471
		long reap;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5472
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5473
		mutex_enter(&cp->cache_depot_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5474
		reap = MIN(cp->cache_full.ml_reaplimit, cp->cache_full.ml_min);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5475
		reap = MIN(reap, cp->cache_full.ml_total);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5476
		mutex_exit(&cp->cache_depot_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5477
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5478
		nfree += ((uint64_t)reap * cp->cache_magtype->mt_magsize);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5479
		if (kmem_cache_frag_threshold(cp, nfree)) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5480
			*doreap = B_TRUE;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5481
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5482
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5483
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5484
	return (fragmented);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5485
}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5486
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5487
/* Called periodically from kmem_taskq */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5488
static void
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5489
kmem_cache_scan(kmem_cache_t *cp)
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5490
{
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5491
	boolean_t reap = B_FALSE;
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5492
	kmem_defrag_t *kmd;
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5493
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5494
	ASSERT(taskq_member(kmem_taskq, curthread));
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5495
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5496
	mutex_enter(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5497
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5498
	kmd = cp->cache_defrag;
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5499
	if (kmd->kmd_consolidate > 0) {
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5500
		kmd->kmd_consolidate--;
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5501
		mutex_exit(&cp->cache_lock);
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5502
		kmem_cache_reap(cp);
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5503
		return;
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5504
	}
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5505
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5506
	if (kmem_cache_is_fragmented(cp, &reap)) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5507
		size_t slabs_found;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5508
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5509
		/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5510
		 * Consolidate reclaimable slabs from the end of the partial
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5511
		 * slab list (scan at most kmem_reclaim_scan_range slabs to find
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5512
		 * reclaimable slabs). Keep track of how many candidate slabs we
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5513
		 * looked for and how many we actually found so we can adjust
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5514
		 * the definition of a candidate slab if we're having trouble
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5515
		 * finding them.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5516
		 *
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5517
		 * kmem_move_buffers() drops and reacquires cache_lock.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5518
		 */
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5519
		KMEM_STAT_ADD(kmem_move_stats.kms_scans);
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5520
		kmd->kmd_scans++;
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5521
		slabs_found = kmem_move_buffers(cp, kmem_reclaim_scan_range,
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5522
		    kmem_reclaim_max_slabs, 0);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5523
		if (slabs_found >= 0) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5524
			kmd->kmd_slabs_sought += kmem_reclaim_max_slabs;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5525
			kmd->kmd_slabs_found += slabs_found;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5526
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5527
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5528
		if (++kmd->kmd_tries >= kmem_reclaim_scan_range) {
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5529
			kmd->kmd_tries = 0;
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5530
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5531
			/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5532
			 * If we had difficulty finding candidate slabs in
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5533
			 * previous scans, adjust the threshold so that
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5534
			 * candidates are easier to find.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5535
			 */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5536
			if (kmd->kmd_slabs_found == kmd->kmd_slabs_sought) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5537
				kmem_adjust_reclaim_threshold(kmd, -1);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5538
			} else if ((kmd->kmd_slabs_found * 2) <
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5539
			    kmd->kmd_slabs_sought) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5540
				kmem_adjust_reclaim_threshold(kmd, 1);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5541
			}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5542
			kmd->kmd_slabs_sought = 0;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5543
			kmd->kmd_slabs_found = 0;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5544
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5545
	} else {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5546
		kmem_reset_reclaim_threshold(cp->cache_defrag);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5547
#ifdef	DEBUG
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5548
		if (!avl_is_empty(&cp->cache_partial_slabs)) {
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5549
			/*
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5550
			 * In a debug kernel we want the consolidator to
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5551
			 * run occasionally even when there is plenty of
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5552
			 * memory.
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5553
			 */
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5554
			uint16_t debug_rand;
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5555
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5556
			(void) random_get_bytes((uint8_t *)&debug_rand, 2);
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5557
			if (!kmem_move_noreap &&
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5558
			    ((debug_rand % kmem_mtb_reap) == 0)) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5559
				mutex_exit(&cp->cache_lock);
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5560
				KMEM_STAT_ADD(kmem_move_stats.kms_debug_reaps);
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5561
				kmem_cache_reap(cp);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5562
				return;
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5563
			} else if ((debug_rand % kmem_mtb_move) == 0) {
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5564
				KMEM_STAT_ADD(kmem_move_stats.kms_scans);
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5565
				KMEM_STAT_ADD(kmem_move_stats.kms_debug_scans);
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5566
				kmd->kmd_scans++;
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5567
				(void) kmem_move_buffers(cp,
10217
38c40fa7246e 6861590 assertion failed: KMEM_SLAB_MEMBER(sp, callback->kmm_from_buf)
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 9694
diff changeset
  5568
				    kmem_reclaim_scan_range, 1, KMM_DEBUG);
6712
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5569
			}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5570
		}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5571
#endif	/* DEBUG */
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5572
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5573
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5574
	mutex_exit(&cp->cache_lock);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5575
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5576
	if (reap) {
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5577
		KMEM_STAT_ADD(kmem_move_stats.kms_scan_depot_ws_reaps);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5578
		kmem_depot_ws_reap(cp);
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5579
	}
79afecec3f3c 6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents: 6306
diff changeset
  5580
}