Whamcloud - gitweb
Landing b_hd_newconfig on HEAD
[fs/lustre-release.git] / lnet / libcfs / winnt / winnt-mem.c
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=4:tabstop=4:
3  *
4  * Copyright (C) 2001, 2002 Cluster File Systems, Inc.
5  *
6  *   This file is part of Lustre, http://www.lustre.org.
7  *
8  *   Lustre is free software; you can redistribute it and/or
9  *   modify it under the terms of version 2 of the GNU General Public
10  *   License as published by the Free Software Foundation.
11  *
12  *   Lustre is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  *
17  *   You should have received a copy of the GNU General Public License
18  *   along with Lustre; if not, write to the Free Software
19  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21
22 #define DEBUG_SUBSYSTEM S_LNET
23
24 #include <libcfs/libcfs.h>
25
26
27 cfs_mem_cache_t *cfs_page_t_slab = NULL;
28 cfs_mem_cache_t *cfs_page_p_slab = NULL;
29
30 /*
31  * cfs_alloc_page
32  *   To allocate the cfs_page_t and also 1 page of memory
33  *
34  * Arguments:
35  *   flags:  the allocation options
36  *
37  * Return Value:
38  *   pointer to the cfs_page_t strcture in success or
39  *   NULL in failure case
40  *
41  * Notes: 
42  *   N/A
43  */
44
45 cfs_page_t * cfs_alloc_page(int flags)
46 {
47     cfs_page_t *pg;
48     pg = cfs_mem_cache_alloc(cfs_page_t_slab, 0);
49     
50     if (NULL == pg) {
51         cfs_enter_debugger();
52         return NULL;
53     }
54
55     memset(pg, 0, sizeof(cfs_page_t));
56     pg->addr = cfs_mem_cache_alloc(cfs_page_p_slab, 0);
57     atomic_set(&pg->count, 1);
58
59     if (pg->addr) {
60         if (cfs_is_flag_set(flags, CFS_ALLOC_ZERO)) {
61             memset(pg->addr, 0, CFS_PAGE_SIZE);
62         }
63     } else {
64         cfs_enter_debugger();
65         cfs_mem_cache_free(cfs_page_t_slab, pg);
66         pg = NULL;
67     }
68
69     return pg;
70 }
71
72 /*
73  * cfs_free_page
74  *   To free the cfs_page_t including the page
75  *
76  * Arguments:
77  *   pg:  pointer to the cfs_page_t strcture
78  *
79  * Return Value:
80  *   N/A
81  *
82  * Notes: 
83  *   N/A
84  */
85 void cfs_free_page(cfs_page_t *pg)
86 {
87     ASSERT(pg != NULL);
88     ASSERT(pg->addr  != NULL);
89     ASSERT(atomic_read(&pg->count) <= 1);
90
91     cfs_mem_cache_free(cfs_page_p_slab, pg->addr);
92     cfs_mem_cache_free(cfs_page_t_slab, pg);
93 }
94
95
96 /*
97  * cfs_alloc
98  *   To allocate memory from system pool
99  *
100  * Arguments:
101  *   nr_bytes:  length in bytes of the requested buffer
102  *   flags:     flags indiction
103  *
104  * Return Value:
105  *   NULL: if there's no enough memory space in system
106  *   the address of the allocated memory in success.
107  *
108  * Notes: 
109  *   This operation can be treated as atomic.
110  */
111
112 void *
113 cfs_alloc(size_t nr_bytes, u_int32_t flags)
114 {
115         void *ptr;
116
117     /* Ignore the flags: always allcoate from NonPagedPool */
118
119         ptr = ExAllocatePoolWithTag(NonPagedPool, nr_bytes, 'Lufs');
120
121         if (ptr != NULL && (flags & CFS_ALLOC_ZERO)) {
122                 memset(ptr, 0, nr_bytes);
123     }
124
125     if (!ptr) {
126         cfs_enter_debugger();
127     }
128
129         return ptr;
130 }
131
132 /*
133  * cfs_free
134  *   To free the sepcified memory to system pool
135  *
136  * Arguments:
137  *   addr:   pointer to the buffer to be freed
138  *
139  * Return Value:
140  *   N/A
141  *
142  * Notes: 
143  *    This operation can be treated as atomic.
144  */
145
146 void
147 cfs_free(void *addr)
148 {
149         ExFreePool(addr);
150 }
151
152 /*
153  * cfs_alloc_large
154  *   To allocate large block of memory from system pool
155  *
156  * Arguments:
157  *   nr_bytes:  length in bytes of the requested buffer
158  *
159  * Return Value:
160  *   NULL: if there's no enough memory space in system
161  *   the address of the allocated memory in success.
162  *
163  * Notes: 
164  *   N/A
165  */
166
167 void *
168 cfs_alloc_large(size_t nr_bytes)
169 {
170         return cfs_alloc(nr_bytes, 0);
171 }
172
173 /*
174  * cfs_free_large
175  *   To free the sepcified memory to system pool
176  *
177  * Arguments:
178  *   addr:   pointer to the buffer to be freed
179  *
180  * Return Value:
181  *   N/A
182  *
183  * Notes: 
184  *   N/A
185  */
186
187 void
188 cfs_free_large(void *addr)
189 {
190         cfs_free(addr);
191 }
192
193
194 /*
195  * cfs_mem_cache_create
196  *   To create a SLAB cache
197  *
198  * Arguments:
199  *   name:   name string of the SLAB cache to be created
200  *   size:   size in bytes of SLAB entry buffer
201  *   offset: offset in the page
202  *   flags:  SLAB creation flags
203 *
204  * Return Value:
205  *   The poitner of cfs_memory_cache structure in success.
206  *   NULL pointer in failure case.
207  *
208  * Notes: 
209  *   1, offset won't be used here.
210  *   2, it could be better to induce a lock to protect the access of the
211  *       SLAB structure on SMP if there's not outside lock protection.
212  *   3, parameters C/D are removed.
213  */
214
215 cfs_mem_cache_t *
216 cfs_mem_cache_create(
217     const char * name,
218     size_t size,
219     size_t offset,
220     unsigned long flags
221     )
222 {
223     cfs_mem_cache_t * kmc = NULL;
224
225     /*  The name of the SLAB could not exceed 20 chars */
226
227     if (name && strlen(name) >= 20) {
228         goto errorout;
229     }
230
231     /* Allocate and initialize the SLAB strcture */
232
233     kmc = cfs_alloc (sizeof(cfs_mem_cache_t), 0);
234
235     if (NULL == kmc) {
236         goto errorout;
237     }
238
239     memset(kmc, 0, sizeof(cfs_mem_cache_t));
240
241     kmc->flags = flags;
242
243     if (name) {
244         strcpy(&kmc->name[0], name);
245     }
246
247     /* Initialize the corresponding LookAside list */
248
249     ExInitializeNPagedLookasideList(
250             &(kmc->npll),
251             NULL,
252             NULL,
253             0,
254             size,
255             'pnmk',
256             0);
257  
258 errorout:
259
260     return kmc;
261 }
262
263 /*
264  * cfs_mem_cache_destroy
265  *   To destroy the unused SLAB cache
266  *
267  * Arguments:
268  *   kmc: the SLAB cache to be destroied.
269  *
270  * Return Value:
271  *   0: in success case.
272  *   1: in failure case.
273  *
274  * Notes: 
275  *   N/A
276  */
277
278 int cfs_mem_cache_destroy (cfs_mem_cache_t * kmc)
279 {
280     ASSERT(kmc != NULL);
281
282     ExDeleteNPagedLookasideList(&(kmc->npll));
283
284     cfs_free(kmc);
285
286     return 0;
287 }
288
289 /*
290  * cfs_mem_cache_alloc
291  *   To allocate an object (LookAside entry) from the SLAB
292  *
293  * Arguments:
294  *   kmc:   the SLAB cache to be allocated from.
295  *   flags: flags for allocation options
296  *
297  * Return Value:
298  *   object buffer address: in success case.
299  *   NULL: in failure case.
300  *
301  * Notes: 
302  *   N/A
303  */
304
305 void *cfs_mem_cache_alloc(cfs_mem_cache_t * kmc, int flags)
306 {
307     void *buf = NULL;
308
309     buf = ExAllocateFromNPagedLookasideList(&(kmc->npll));
310
311     return buf;
312 }
313
314 /*
315  * cfs_mem_cache_free
316  *   To free an object (LookAside entry) to the SLAB cache
317  *
318  * Arguments:
319  *   kmc: the SLAB cache to be freed to.
320  *   buf: the pointer to the object to be freed.
321  *
322  * Return Value:
323  *   N/A
324  *
325  * Notes: 
326  *   N/A
327  */
328
329 void cfs_mem_cache_free(cfs_mem_cache_t * kmc, void * buf)
330 {
331     ExFreeToNPagedLookasideList(&(kmc->npll), buf);
332 }