3 *
4 * The contents of this file are subject to the terms of the
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) 2017, Joyent, Inc.
24 * Copyright (c) 2012, 2017 by Delphix. All rights reserved.
25 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
26 * Copyright 2018, Joyent, Inc.
27 * Copyright 2020 Oxide Computer Company
28 */
29
30 /*
31 * Kernel memory allocator, as described in the following two papers and a
32 * statement about the consolidator:
33 *
34 * Jeff Bonwick,
35 * The Slab Allocator: An Object-Caching Kernel Memory Allocator.
36 * Proceedings of the Summer 1994 Usenix Conference.
37 * Available as /shared/sac/PSARC/1994/028/materials/kmem.pdf.
38 *
39 * Jeff Bonwick and Jonathan Adams,
40 * Magazines and vmem: Extending the Slab Allocator to Many CPUs and
41 * Arbitrary Resources.
42 * Proceedings of the 2001 Usenix Conference.
43 * Available as /shared/sac/PSARC/2000/550/materials/vmem.pdf.
44 *
45 * kmem Slab Consolidator Big Theory Statement:
46 *
47 * 1. Motivation
2803 ASSERT(head != NULL);
2804
2805 /*
2806 * If there was a failure, return remaining objects to
2807 * the slab
2808 */
2809 while (head != NULL) {
2810 ASSERT(nbufs != 0);
2811 next = head->bc_next;
2812 head->bc_next = NULL;
2813 kmem_slab_free(cp, KMEM_BUF(cp, head));
2814 head = next;
2815 nbufs--;
2816 }
2817 }
2818 ASSERT(head == NULL);
2819 ASSERT(nbufs == 0);
2820 mutex_enter(&cp->cache_lock);
2821 }
2822
2823 void *
2824 kmem_zalloc(size_t size, int kmflag)
2825 {
2826 size_t index;
2827 void *buf;
2828
2829 if ((index = ((size - 1) >> KMEM_ALIGN_SHIFT)) < KMEM_ALLOC_TABLE_MAX) {
2830 kmem_cache_t *cp = kmem_alloc_table[index];
2831 buf = kmem_cache_alloc(cp, kmflag);
2832 if (buf != NULL) {
2833 if ((cp->cache_flags & KMF_BUFTAG) && !KMEM_DUMP(cp)) {
2834 kmem_buftag_t *btp = KMEM_BUFTAG(cp, buf);
2835 ((uint8_t *)buf)[size] = KMEM_REDZONE_BYTE;
2836 ((uint32_t *)btp)[1] = KMEM_SIZE_ENCODE(size);
2837
2838 if (cp->cache_flags & KMF_LITE) {
2839 KMEM_BUFTAG_LITE_ENTER(btp,
2840 kmem_lite_count, caller());
2841 }
2842 }
|
3 *
4 * The contents of this file are subject to the terms of the
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 * Copyright 2023 Oxide Computer Company
27 */
28
29 /*
30 * Kernel memory allocator, as described in the following two papers and a
31 * statement about the consolidator:
32 *
33 * Jeff Bonwick,
34 * The Slab Allocator: An Object-Caching Kernel Memory Allocator.
35 * Proceedings of the Summer 1994 Usenix Conference.
36 * Available as /shared/sac/PSARC/1994/028/materials/kmem.pdf.
37 *
38 * Jeff Bonwick and Jonathan Adams,
39 * Magazines and vmem: Extending the Slab Allocator to Many CPUs and
40 * Arbitrary Resources.
41 * Proceedings of the 2001 Usenix Conference.
42 * Available as /shared/sac/PSARC/2000/550/materials/vmem.pdf.
43 *
44 * kmem Slab Consolidator Big Theory Statement:
45 *
46 * 1. Motivation
2802 ASSERT(head != NULL);
2803
2804 /*
2805 * If there was a failure, return remaining objects to
2806 * the slab
2807 */
2808 while (head != NULL) {
2809 ASSERT(nbufs != 0);
2810 next = head->bc_next;
2811 head->bc_next = NULL;
2812 kmem_slab_free(cp, KMEM_BUF(cp, head));
2813 head = next;
2814 nbufs--;
2815 }
2816 }
2817 ASSERT(head == NULL);
2818 ASSERT(nbufs == 0);
2819 mutex_enter(&cp->cache_lock);
2820 }
2821
2822 /*
2823 * kmem_rezalloc() is currently considered private until we sort out how we want
2824 * to handle realloc vs. reallocf style interfaces.
2825 */
2826 void *
2827 kmem_rezalloc(void *oldbuf, size_t oldsize, size_t newsize, int kmflag)
2828 {
2829 void *newbuf = kmem_alloc(newsize, kmflag);
2830 if (newbuf == NULL) {
2831 return (NULL);
2832 }
2833
2834 bcopy(oldbuf, newbuf, MIN(oldsize, newsize));
2835 if (newsize > oldsize) {
2836 void *start = (void *)((uintptr_t)newbuf + oldsize);
2837 bzero(start, newsize - oldsize);
2838 }
2839
2840 if (oldbuf != NULL) {
2841 ASSERT3U(oldsize, !=, 0);
2842 kmem_free(oldbuf, oldsize);
2843 }
2844
2845 return (newbuf);
2846 }
2847
2848 void *
2849 kmem_zalloc(size_t size, int kmflag)
2850 {
2851 size_t index;
2852 void *buf;
2853
2854 if ((index = ((size - 1) >> KMEM_ALIGN_SHIFT)) < KMEM_ALLOC_TABLE_MAX) {
2855 kmem_cache_t *cp = kmem_alloc_table[index];
2856 buf = kmem_cache_alloc(cp, kmflag);
2857 if (buf != NULL) {
2858 if ((cp->cache_flags & KMF_BUFTAG) && !KMEM_DUMP(cp)) {
2859 kmem_buftag_t *btp = KMEM_BUFTAG(cp, buf);
2860 ((uint8_t *)buf)[size] = KMEM_REDZONE_BYTE;
2861 ((uint32_t *)btp)[1] = KMEM_SIZE_ENCODE(size);
2862
2863 if (cp->cache_flags & KMF_LITE) {
2864 KMEM_BUFTAG_LITE_ENTER(btp,
2865 kmem_lite_count, caller());
2866 }
2867 }
|