5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright (c) 2012, 2017 by Delphix. All rights reserved.
24 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
25 */
26
27 /*
28 * Kernel memory allocator, as described in the following two papers and a
29 * statement about the consolidator:
30 *
31 * Jeff Bonwick,
32 * The Slab Allocator: An Object-Caching Kernel Memory Allocator.
33 * Proceedings of the Summer 1994 Usenix Conference.
34 * Available as /shared/sac/PSARC/1994/028/materials/kmem.pdf.
35 *
36 * Jeff Bonwick and Jonathan Adams,
37 * Magazines and vmem: Extending the Slab Allocator to Many CPUs and
38 * Arbitrary Resources.
39 * Proceedings of the 2001 Usenix Conference.
40 * Available as /shared/sac/PSARC/2000/550/materials/vmem.pdf.
41 *
42 * kmem Slab Consolidator Big Theory Statement:
43 *
44 * 1. Motivation
3232 * Enable per-cpu magazines on a cache.
3233 */
3234 static void
3235 kmem_cache_magazine_enable(kmem_cache_t *cp)
3236 {
3237 int cpu_seqid;
3238
3239 if (cp->cache_flags & KMF_NOMAGAZINE)
3240 return;
3241
3242 for (cpu_seqid = 0; cpu_seqid < max_ncpus; cpu_seqid++) {
3243 kmem_cpu_cache_t *ccp = &cp->cache_cpu[cpu_seqid];
3244 mutex_enter(&ccp->cc_lock);
3245 ccp->cc_magsize = cp->cache_magtype->mt_magsize;
3246 mutex_exit(&ccp->cc_lock);
3247 }
3248
3249 }
3250
3251 /*
3252 * Reap (almost) everything right now.
3253 */
3254 void
3255 kmem_cache_reap_now(kmem_cache_t *cp)
3256 {
3257 ASSERT(list_link_active(&cp->cache_link));
3258
3259 kmem_depot_ws_zero(cp);
3260
3261 (void) taskq_dispatch(kmem_taskq,
3262 (task_func_t *)kmem_depot_ws_reap, cp, TQ_SLEEP);
3263 taskq_wait(kmem_taskq);
3264 }
3265
3266 /*
3267 * Recompute a cache's magazine size. The trade-off is that larger magazines
3268 * provide a higher transfer rate with the depot, while smaller magazines
3269 * reduce memory consumption. Magazine resizing is an expensive operation;
3270 * it should not be done frequently.
3271 *
3272 * Changes to the magazine size are serialized by the kmem_taskq lock.
3273 *
3274 * Note: at present this only grows the magazine size. It might be useful
3275 * to allow shrinkage too.
3276 */
3277 static void
3278 kmem_cache_magazine_resize(kmem_cache_t *cp)
3279 {
3280 kmem_magtype_t *mtp = cp->cache_magtype;
3281
3282 ASSERT(taskq_member(kmem_taskq, curthread));
3283
|
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright (c) 2012, 2017 by Delphix. All rights reserved.
24 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
25 * Copyright 2018, Joyent, Inc.
26 */
27
28 /*
29 * Kernel memory allocator, as described in the following two papers and a
30 * statement about the consolidator:
31 *
32 * Jeff Bonwick,
33 * The Slab Allocator: An Object-Caching Kernel Memory Allocator.
34 * Proceedings of the Summer 1994 Usenix Conference.
35 * Available as /shared/sac/PSARC/1994/028/materials/kmem.pdf.
36 *
37 * Jeff Bonwick and Jonathan Adams,
38 * Magazines and vmem: Extending the Slab Allocator to Many CPUs and
39 * Arbitrary Resources.
40 * Proceedings of the 2001 Usenix Conference.
41 * Available as /shared/sac/PSARC/2000/550/materials/vmem.pdf.
42 *
43 * kmem Slab Consolidator Big Theory Statement:
44 *
45 * 1. Motivation
3233 * Enable per-cpu magazines on a cache.
3234 */
3235 static void
3236 kmem_cache_magazine_enable(kmem_cache_t *cp)
3237 {
3238 int cpu_seqid;
3239
3240 if (cp->cache_flags & KMF_NOMAGAZINE)
3241 return;
3242
3243 for (cpu_seqid = 0; cpu_seqid < max_ncpus; cpu_seqid++) {
3244 kmem_cpu_cache_t *ccp = &cp->cache_cpu[cpu_seqid];
3245 mutex_enter(&ccp->cc_lock);
3246 ccp->cc_magsize = cp->cache_magtype->mt_magsize;
3247 mutex_exit(&ccp->cc_lock);
3248 }
3249
3250 }
3251
3252 /*
3253 * Allow our caller to determine if there are running reaps.
3254 *
3255 * This call is very conservative and may return B_TRUE even when
3256 * reaping activity isn't active. If it returns B_FALSE, then reaping
3257 * activity is definitely inactive.
3258 */
3259 boolean_t
3260 kmem_cache_reap_active(void)
3261 {
3262 return (!taskq_empty(kmem_taskq));
3263 }
3264
3265 /*
3266 * Reap (almost) everything soon.
3267 *
3268 * Note: this does not wait for the reap-tasks to complete. Caller
3269 * should use kmem_cache_reap_active() (above) and/or moderation to
3270 * avoid scheduling too many reap-tasks.
3271 */
3272 void
3273 kmem_cache_reap_soon(kmem_cache_t *cp)
3274 {
3275 ASSERT(list_link_active(&cp->cache_link));
3276
3277 kmem_depot_ws_zero(cp);
3278
3279 (void) taskq_dispatch(kmem_taskq,
3280 (task_func_t *)kmem_depot_ws_reap, cp, TQ_SLEEP);
3281 }
3282
3283 /*
3284 * Recompute a cache's magazine size. The trade-off is that larger magazines
3285 * provide a higher transfer rate with the depot, while smaller magazines
3286 * reduce memory consumption. Magazine resizing is an expensive operation;
3287 * it should not be done frequently.
3288 *
3289 * Changes to the magazine size are serialized by the kmem_taskq lock.
3290 *
3291 * Note: at present this only grows the magazine size. It might be useful
3292 * to allow shrinkage too.
3293 */
3294 static void
3295 kmem_cache_magazine_resize(kmem_cache_t *cp)
3296 {
3297 kmem_magtype_t *mtp = cp->cache_magtype;
3298
3299 ASSERT(taskq_member(kmem_taskq, curthread));
3300
|