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