Whamcloud - gitweb
LU-2456 lnet: DLC Feature dynamic net config
[fs/lustre-release.git] / libcfs / include / libcfs / darwin / darwin-mem.h
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  */
30 /*
31  * This file is part of Lustre, http://www.lustre.org/
32  * Lustre is a trademark of Sun Microsystems, Inc.
33  */
34
35 #ifndef __LIBCFS_DARWIN_CFS_MEM_H__
36 #define __LIBCFS_DARWIN_CFS_MEM_H__
37
38 #ifndef __LIBCFS_LIBCFS_H__
39 #error Do not #include this file directly. #include <libcfs/libcfs.h> instead
40 #endif
41
42 #ifdef __KERNEL__
43
44 #include <sys/types.h>
45 #include <sys/systm.h>
46
47 #include <sys/vm.h>
48 #include <sys/kernel.h>
49 #include <sys/ubc.h>
50 #include <sys/uio.h>
51 #include <sys/malloc.h>
52 #include <sys/mbuf.h>
53 #include <sys/lockf.h>
54
55 #include <mach/mach_types.h>
56 #include <mach/vm_types.h>
57 #include <vm/pmap.h>
58 #include <vm/vm_kern.h>
59 #include <mach/machine/vm_param.h>
60 #include <kern/thread_call.h>
61 #include <sys/param.h>
62 #include <sys/vm.h>
63
64 #include <libcfs/darwin/darwin-types.h>
65 #include <libcfs/darwin/darwin-sync.h>
66 #include <libcfs/darwin/darwin-lock.h>
67 #include <libcfs/list.h>
68
69 /*
70  * Basic xnu_page struct, should be binary compatibility with
71  * all page types in xnu (we have only xnu_raw_page, xll_page now)
72  */
73
74 /* Variable sized pages are not supported */
75
76 #ifdef PAGE_SHIFT
77 #define PAGE_CACHE_SHIFT        PAGE_SHIFT
78 #else
79 #define PAGE_CACHE_SHIFT        12
80 #endif
81
82 #define PAGE_CACHE_SIZE (1UL << PAGE_CACHE_SHIFT)
83
84 #define CFS_PAGE_MASK   (~((__u64)PAGE_CACHE_SIZE - 1))
85
86 enum {
87         XNU_PAGE_RAW,
88         XNU_PAGE_XLL,
89         XNU_PAGE_NTYPES
90 };
91
92 typedef __u32 page_off_t;
93
94 /*
95  * For XNU we have our own page cache built on top of underlying BSD/MACH
96  * infrastructure. In particular, we have two disjoint types of pages:
97  *
98  *    - "raw" pages (XNU_PAGE_RAW): these are just buffers mapped into KVM,
99  *    based on UPLs, and
100  *
101  *    - "xll" pages (XNU_PAGE_XLL): these are used by file system to cache
102  *    file data, owned by file system objects, hashed, lrued, etc.
103  *
104  * struct page has to cover both of them, because core Lustre code is based on
105  * the Linux assumption that page is _both_ memory buffer and file system
106  * caching entity.
107  *
108  * To achieve this, all types of pages supported on XNU has to start from
109  * common header that contains only "page type". Common struct page operations
110  * dispatch through operation vector based on page type.
111  *
112  */
113 typedef struct xnu_page {
114         int type;
115 } struct page;
116
117 struct xnu_page_ops {
118         void *(*page_map)        (struct page *);
119         void  (*page_unmap)      (struct page *);
120         void *(*page_address)    (struct page *);
121 };
122
123 void xnu_page_ops_register(int type, struct xnu_page_ops *ops);
124 void xnu_page_ops_unregister(int type);
125
126 /*
127  * raw page, no cache object, just like buffer
128  */
129 struct xnu_raw_page {
130         struct xnu_page  header;
131         void            *virtual;
132         atomic_t         count;
133         struct list_head link;
134 };
135
136 /*
137  * Public interface to lustre
138  *
139  * - alloc_page(f)
140  * - __free_page(p)
141  * - kmap(p)
142  * - kunmap(p)
143  * - page_address(p)
144  */
145
146 /*
147  * Of all functions above only kmap(), kunmap(), and
148  * page_address() can be called on file system pages. The rest is for raw
149  * pages only.
150  */
151
152 struct page *alloc_page(u_int32_t flags);
153 void __free_page(struct page *page);
154 void get_page(struct page *page);
155 int cfs_put_page_testzero(struct page *page);
156 int page_count(struct page *page);
157 #define page_index(pg)  (0)
158
159 void *page_address(struct page *pg);
160 void *kmap(struct page *pg);
161 void kunmap(struct page *pg);
162
163 /*
164  * Memory allocator
165  */
166
167 void *kmalloc(size_t nr_bytes, u_int32_t flags);
168 void  kfree(void *addr);
169
170 void *vmalloc(size_t nr_bytes);
171 void  vfree(void *addr);
172
173 extern int get_preemption_level(void);
174
175 /*
176  * Universal memory allocator API
177  */
178 enum cfs_alloc_flags {
179         /* allocation is not allowed to block */
180         GFP_ATOMIC = 0x1,
181         /* allocation is allowed to block */
182         __GFP_WAIT   = 0x2,
183         /* allocation should return zeroed memory */
184         __GFP_ZERO   = 0x4,
185         /* allocation is allowed to call file-system code to free/clean
186          * memory */
187         __GFP_FS     = 0x8,
188         /* allocation is allowed to do io to free/clean memory */
189         __GFP_IO     = 0x10,
190         /* don't report allocation failure to the console */
191         __GFP_NOWARN = 0x20,
192         /* standard allocator flag combination */
193         GFP_IOFS    = __GFP_FS | __GFP_IO,
194         GFP_USER   = __GFP_WAIT | __GFP_FS | __GFP_IO,
195         GFP_NOFS   = __GFP_WAIT | __GFP_IO,
196         GFP_KERNEL = __GFP_WAIT | __GFP_IO | __GFP_FS,
197 };
198
199 /* flags for cfs_page_alloc() in addition to enum cfs_alloc_flags */
200 enum cfs_alloc_page_flags {
201         /* allow to return page beyond KVM. It has to be mapped into KVM by
202          * kmap() and unmapped with kunmap(). */
203         __GFP_HIGHMEM  = 0x40,
204         GFP_HIGHUSER = __GFP_WAIT | __GFP_FS | __GFP_IO |
205                              __GFP_HIGHMEM,
206 };
207
208 #define ALLOC_ATOMIC_TRY                                    \
209         (get_preemption_level() != 0 ? GFP_ATOMIC : 0)
210
211 #define memory_pressure_get() (0)
212 #define memory_pressure_set() do {} while (0)
213 #define memory_pressure_clr() do {} while (0)
214
215 /*
216  * Slab:
217  *
218  * No slab in OSX, use zone allocator to simulate slab
219  */
220 #define SLAB_HWCACHE_ALIGN              0
221
222 #ifdef __DARWIN8__
223 /* 
224  * In Darwin8, we cannot use zalloc_noblock(not exported by kernel),
225  * also, direct using of zone allocator is not recommended.
226  */
227 #define CFS_INDIVIDUAL_ZONE     (0)
228
229 #if !CFS_INDIVIDUAL_ZONE
230 #include <libkern/OSMalloc.h>
231 typedef         OSMallocTag     mem_cache_t;
232 #else
233 typedef         void*           zone_t;
234 typedef         zone_t          mem_cache_t;
235 #endif
236
237 #else /* !__DARWIN8__ */
238
239 #define CFS_INDIVIDUAL_ZONE     (1)
240
241 typedef         zone_t          mem_cache_t;
242
243 #endif /* !__DARWIN8__ */
244
245 #define MC_NAME_MAX_LEN         64
246
247 struct kmem_cache {
248         int                     mc_size;
249         mem_cache_t             mc_cache;
250         struct list_head        mc_link;
251         char                    mc_name [MC_NAME_MAX_LEN];
252 };
253
254 #define KMEM_CACHE_MAX_COUNT    64
255 #define KMEM_MAX_ZONE           8192
256
257 struct kmem_cache *kmem_cache_create(const char *, size_t, size_t,
258                                      unsigned long, void *);
259 void kmem_cache_destroy(struct kmem_cache *);
260 void *kmem_cache_alloc(struct kmem_cache *, int);
261 void kmem_cache_free(struct kmem_cache *, void *);
262
263 /*
264  * Misc
265  */
266 /* XXX Liang: totalram_pages... fix me */
267 #define totalram_pages                  (64 * 1024)
268 #define NUM_CACHEPAGES          totalram_pages
269
270 #define DECL_MMSPACE
271 #define MMSPACE_OPEN            do {} while (0)
272 #define MMSPACE_CLOSE           do {} while (0)
273
274 #define copy_from_user(kaddr, uaddr, size)      copyin(CAST_USER_ADDR_T(uaddr), (caddr_t)kaddr, size)
275 #define copy_to_user(uaddr, kaddr, size)        copyout((caddr_t)kaddr, CAST_USER_ADDR_T(uaddr), size)
276
277 #if 0
278 static inline int strncpy_from_user(char *kaddr, char *uaddr, int size)
279 {
280         size_t count;
281         return copyinstr((const user_addr_t)uaddr, (void *)kaddr, size, &count);
282 }
283 #endif
284
285 #if defined (__ppc__)
286 #define mb()  __asm__ __volatile__ ("sync" : : : "memory")
287 #define rmb()  __asm__ __volatile__ ("sync" : : : "memory")
288 #define wmb()  __asm__ __volatile__ ("eieio" : : : "memory")
289 #elif defined (__i386__)
290 #define mb()    __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
291 #define rmb()   mb()
292 #define wmb()   __asm__ __volatile__ ("": : :"memory")
293 #else
294 #error architecture not supported
295 #endif
296
297 #else   /* !__KERNEL__ */
298
299 #define CFS_CACHE_SHIFT 12
300 #define PAGE_CACHE_SIZE (1 << CFS_CACHE_SHIFT)
301 #include <libcfs/user-prim.h>
302
303 #endif  /* __KERNEL__ */
304
305 #endif  /* __XNU_CFS_MEM_H__ */