Whamcloud - gitweb
b=16098
[fs/lustre-release.git] / libcfs / include / libcfs / darwin / darwin-mem.h
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * GPL HEADER START
5  *
6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7  *
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.
11  *
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).
17  *
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
21  *
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
24  * have any questions.
25  *
26  * GPL HEADER END
27  */
28 /*
29  * Copyright  2008 Sun Microsystems, Inc. All rights reserved
30  * Use is subject to license terms.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  */
36
37 #ifndef __LIBCFS_DARWIN_CFS_MEM_H__
38 #define __LIBCFS_DARWIN_CFS_MEM_H__
39
40 #ifndef __LIBCFS_LIBCFS_H__
41 #error Do not #include this file directly. #include <libcfs/libcfs.h> instead
42 #endif
43
44 #ifdef __KERNEL__
45
46 #include <sys/types.h>
47 #include <sys/systm.h>
48
49 #include <sys/vm.h>
50 #include <sys/kernel.h>
51 #include <sys/ubc.h>
52 #include <sys/uio.h>
53 #include <sys/malloc.h>
54 #include <sys/mbuf.h>
55 #include <sys/lockf.h>
56
57 #include <mach/mach_types.h>
58 #include <mach/vm_types.h>
59 #include <vm/pmap.h>
60 #include <vm/vm_kern.h>
61 #include <mach/machine/vm_param.h>
62 #include <kern/thread_call.h>
63 #include <sys/param.h>
64 #include <sys/vm.h>
65
66 #include <libcfs/darwin/darwin-types.h>
67 #include <libcfs/darwin/darwin-sync.h>
68 #include <libcfs/darwin/darwin-lock.h>
69 #include <libcfs/list.h>
70
71 /*
72  * Basic xnu_page struct, should be binary compatibility with
73  * all page types in xnu (we have only xnu_raw_page, xll_page now)
74  */
75
76 /* Variable sized pages are not supported */
77
78 #ifdef PAGE_SHIFT
79 #define CFS_PAGE_SHIFT  PAGE_SHIFT
80 #else
81 #define CFS_PAGE_SHIFT  12
82 #endif
83
84 #define CFS_PAGE_SIZE   (1UL << CFS_PAGE_SHIFT)
85
86 #define CFS_PAGE_MASK   (~((__u64)CFS_PAGE_SIZE - 1))
87
88 enum {
89         XNU_PAGE_RAW,
90         XNU_PAGE_XLL,
91         XNU_PAGE_NTYPES
92 };
93
94 typedef __u32 page_off_t;
95
96 /*
97  * For XNU we have our own page cache built on top of underlying BSD/MACH
98  * infrastructure. In particular, we have two disjoint types of pages:
99  *
100  *    - "raw" pages (XNU_PAGE_RAW): these are just buffers mapped into KVM,
101  *    based on UPLs, and
102  *
103  *    - "xll" pages (XNU_PAGE_XLL): these are used by file system to cache
104  *    file data, owned by file system objects, hashed, lrued, etc.
105  *
106  * cfs_page_t has to cover both of them, because core Lustre code is based on
107  * the Linux assumption that page is _both_ memory buffer and file system
108  * caching entity.
109  *
110  * To achieve this, all types of pages supported on XNU has to start from
111  * common header that contains only "page type". Common cfs_page_t operations
112  * dispatch through operation vector based on page type.
113  *
114  */
115 typedef struct xnu_page {
116         int type;
117 } cfs_page_t;
118
119 struct xnu_page_ops {
120         void *(*page_map)        (cfs_page_t *);
121         void  (*page_unmap)      (cfs_page_t *);
122         void *(*page_address)    (cfs_page_t *);
123 };
124
125 void xnu_page_ops_register(int type, struct xnu_page_ops *ops);
126 void xnu_page_ops_unregister(int type);
127
128 /*
129  * raw page, no cache object, just like buffer
130  */
131 struct xnu_raw_page {
132         struct xnu_page  header;
133         void            *virtual;
134         atomic_t         count;
135         struct list_head link;
136 };
137
138 /*
139  * Public interface to lustre
140  *
141  * - cfs_alloc_page(f)
142  * - cfs_free_page(p)
143  * - cfs_kmap(p)
144  * - cfs_kunmap(p)
145  * - cfs_page_address(p)
146  */
147
148 /*
149  * Of all functions above only cfs_kmap(), cfs_kunmap(), and
150  * cfs_page_address() can be called on file system pages. The rest is for raw
151  * pages only.
152  */
153
154 cfs_page_t *cfs_alloc_page(u_int32_t flags);
155 void cfs_free_page(cfs_page_t *page);
156 void cfs_get_page(cfs_page_t *page);
157 int cfs_put_page_testzero(cfs_page_t *page);
158 int cfs_page_count(cfs_page_t *page);
159 #define cfs_page_index(pg)      (0)
160
161 void *cfs_page_address(cfs_page_t *pg);
162 void *cfs_kmap(cfs_page_t *pg);
163 void cfs_kunmap(cfs_page_t *pg);
164
165 /*
166  * Memory allocator
167  */
168
169 void *cfs_alloc(size_t nr_bytes, u_int32_t flags);
170 void  cfs_free(void *addr);
171
172 void *cfs_alloc_large(size_t nr_bytes);
173 void  cfs_free_large(void *addr);
174
175 extern int get_preemption_level(void);
176
177 #define CFS_ALLOC_ATOMIC_TRY                                    \
178         (get_preemption_level() != 0 ? CFS_ALLOC_ATOMIC : 0)
179
180 /*
181  * Slab:
182  *
183  * No slab in OSX, use zone allocator to simulate slab
184  */
185 #define SLAB_HWCACHE_ALIGN              0
186
187 #ifdef __DARWIN8__
188 /* 
189  * In Darwin8, we cannot use zalloc_noblock(not exported by kernel),
190  * also, direct using of zone allocator is not recommended.
191  */
192 #define CFS_INDIVIDUAL_ZONE     (0)
193
194 #if !CFS_INDIVIDUAL_ZONE
195 #include <libkern/OSMalloc.h>
196 typedef         OSMallocTag     mem_cache_t;
197 #else
198 typedef         void*           zone_t;
199 typedef         zone_t          mem_cache_t;
200 #endif
201
202 #else /* !__DARWIN8__ */
203
204 #define CFS_INDIVIDUAL_ZONE     (1)
205
206 typedef         zone_t          mem_cache_t;
207
208 #endif /* !__DARWIN8__ */
209
210 #define MC_NAME_MAX_LEN         64
211
212 typedef struct cfs_mem_cache {
213         int                     mc_size;
214         mem_cache_t             mc_cache;
215         struct list_head        mc_link;
216         char                    mc_name [MC_NAME_MAX_LEN];
217 } cfs_mem_cache_t;
218
219 #define KMEM_CACHE_MAX_COUNT    64
220 #define KMEM_MAX_ZONE           8192
221
222 cfs_mem_cache_t * cfs_mem_cache_create (const char *, size_t, size_t, unsigned long);
223 int cfs_mem_cache_destroy ( cfs_mem_cache_t * );
224 void *cfs_mem_cache_alloc ( cfs_mem_cache_t *, int);
225 void cfs_mem_cache_free ( cfs_mem_cache_t *, void *);
226
227 /*
228  * Misc
229  */
230 /* XXX Liang: num_physpages... fix me */
231 #define num_physpages                   (64 * 1024)
232
233 #define CFS_DECL_MMSPACE                
234 #define CFS_MMSPACE_OPEN                do {} while(0)
235 #define CFS_MMSPACE_CLOSE               do {} while(0)
236
237 #define copy_from_user(kaddr, uaddr, size)      copyin(CAST_USER_ADDR_T(uaddr), (caddr_t)kaddr, size)
238 #define copy_to_user(uaddr, kaddr, size)        copyout((caddr_t)kaddr, CAST_USER_ADDR_T(uaddr), size)
239
240 #if 0
241 static inline int strncpy_from_user(char *kaddr, char *uaddr, int size)
242 {
243         size_t count;
244         return copyinstr((const user_addr_t)uaddr, (void *)kaddr, size, &count);
245 }
246 #endif
247
248 #if defined (__ppc__)
249 #define mb()  __asm__ __volatile__ ("sync" : : : "memory")
250 #define rmb()  __asm__ __volatile__ ("sync" : : : "memory")
251 #define wmb()  __asm__ __volatile__ ("eieio" : : : "memory")
252 #elif defined (__i386__)
253 #define mb()    __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
254 #define rmb()   mb()
255 #define wmb()   __asm__ __volatile__ ("": : :"memory")
256 #else
257 #error architecture not supported
258 #endif
259
260 #else   /* !__KERNEL__ */
261
262 #define CFS_CACHE_SHIFT 12
263 #define PAGE_CACHE_SIZE (1 << CFS_CACHE_SHIFT)
264 #include <libcfs/user-prim.h>
265
266 #endif  /* __KERNEL__ */
267
268 #endif  /* __XNU_CFS_MEM_H__ */