1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see
20 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright 2008 Sun Microsystems, Inc. All rights reserved
30 * Use is subject to license terms.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
37 #define DEBUG_SUBSYSTEM S_LNET
39 #include <libcfs/libcfs.h>
42 cfs_mem_cache_t *cfs_page_t_slab = NULL;
43 cfs_mem_cache_t *cfs_page_p_slab = NULL;
47 * To allocate the cfs_page_t and also 1 page of memory
50 * flags: the allocation options
53 * pointer to the cfs_page_t strcture in success or
54 * NULL in failure case
60 cfs_page_t * cfs_alloc_page(int flags)
63 pg = cfs_mem_cache_alloc(cfs_page_t_slab, 0);
70 memset(pg, 0, sizeof(cfs_page_t));
71 pg->addr = cfs_mem_cache_alloc(cfs_page_p_slab, 0);
72 atomic_set(&pg->count, 1);
75 if (cfs_is_flag_set(flags, CFS_ALLOC_ZERO)) {
76 memset(pg->addr, 0, CFS_PAGE_SIZE);
80 cfs_mem_cache_free(cfs_page_t_slab, pg);
89 * To free the cfs_page_t including the page
92 * pg: pointer to the cfs_page_t strcture
100 void cfs_free_page(cfs_page_t *pg)
103 ASSERT(pg->addr != NULL);
104 ASSERT(atomic_read(&pg->count) <= 1);
106 cfs_mem_cache_free(cfs_page_p_slab, pg->addr);
107 cfs_mem_cache_free(cfs_page_t_slab, pg);
113 * To allocate memory from system pool
116 * nr_bytes: length in bytes of the requested buffer
117 * flags: flags indiction
120 * NULL: if there's no enough memory space in system
121 * the address of the allocated memory in success.
124 * This operation can be treated as atomic.
128 cfs_alloc(size_t nr_bytes, u_int32_t flags)
132 /* Ignore the flags: always allcoate from NonPagedPool */
134 ptr = ExAllocatePoolWithTag(NonPagedPool, nr_bytes, 'Lufs');
136 if (ptr != NULL && (flags & CFS_ALLOC_ZERO)) {
137 memset(ptr, 0, nr_bytes);
141 cfs_enter_debugger();
149 * To free the sepcified memory to system pool
152 * addr: pointer to the buffer to be freed
158 * This operation can be treated as atomic.
169 * To allocate large block of memory from system pool
172 * nr_bytes: length in bytes of the requested buffer
175 * NULL: if there's no enough memory space in system
176 * the address of the allocated memory in success.
183 cfs_alloc_large(size_t nr_bytes)
185 return cfs_alloc(nr_bytes, 0);
190 * To free the sepcified memory to system pool
193 * addr: pointer to the buffer to be freed
203 cfs_free_large(void *addr)
210 * cfs_mem_cache_create
211 * To create a SLAB cache
214 * name: name string of the SLAB cache to be created
215 * size: size in bytes of SLAB entry buffer
216 * offset: offset in the page
217 * flags: SLAB creation flags
220 * The poitner of cfs_memory_cache structure in success.
221 * NULL pointer in failure case.
224 * 1, offset won't be used here.
225 * 2, it could be better to induce a lock to protect the access of the
226 * SLAB structure on SMP if there's not outside lock protection.
227 * 3, parameters C/D are removed.
231 cfs_mem_cache_create(
238 cfs_mem_cache_t * kmc = NULL;
240 /* The name of the SLAB could not exceed 20 chars */
242 if (name && strlen(name) >= 20) {
246 /* Allocate and initialize the SLAB strcture */
248 kmc = cfs_alloc (sizeof(cfs_mem_cache_t), 0);
254 memset(kmc, 0, sizeof(cfs_mem_cache_t));
259 strcpy(&kmc->name[0], name);
262 /* Initialize the corresponding LookAside list */
264 ExInitializeNPagedLookasideList(
279 * cfs_mem_cache_destroy
280 * To destroy the unused SLAB cache
283 * kmc: the SLAB cache to be destroied.
286 * 0: in success case.
287 * 1: in failure case.
293 int cfs_mem_cache_destroy (cfs_mem_cache_t * kmc)
297 ExDeleteNPagedLookasideList(&(kmc->npll));
305 * cfs_mem_cache_alloc
306 * To allocate an object (LookAside entry) from the SLAB
309 * kmc: the SLAB cache to be allocated from.
310 * flags: flags for allocation options
313 * object buffer address: in success case.
314 * NULL: in failure case.
320 void *cfs_mem_cache_alloc(cfs_mem_cache_t * kmc, int flags)
324 buf = ExAllocateFromNPagedLookasideList(&(kmc->npll));
331 * To free an object (LookAside entry) to the SLAB cache
334 * kmc: the SLAB cache to be freed to.
335 * buf: the pointer to the object to be freed.
344 void cfs_mem_cache_free(cfs_mem_cache_t * kmc, void * buf)
346 ExFreeToNPagedLookasideList(&(kmc->npll), buf);