4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
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
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
27 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Use is subject to license terms.
31 * This file is part of Lustre, http://www.lustre.org/
32 * Lustre is a trademark of Sun Microsystems, Inc.
35 #ifndef __LIBCFS_DARWIN_CFS_MEM_H__
36 #define __LIBCFS_DARWIN_CFS_MEM_H__
38 #ifndef __LIBCFS_LIBCFS_H__
39 #error Do not #include this file directly. #include <libcfs/libcfs.h> instead
44 #include <sys/types.h>
45 #include <sys/systm.h>
48 #include <sys/kernel.h>
51 #include <sys/malloc.h>
53 #include <sys/lockf.h>
55 #include <mach/mach_types.h>
56 #include <mach/vm_types.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>
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>
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)
74 /* Variable sized pages are not supported */
77 #define CFS_PAGE_SHIFT PAGE_SHIFT
79 #define CFS_PAGE_SHIFT 12
82 #define CFS_PAGE_SIZE (1UL << CFS_PAGE_SHIFT)
84 #define CFS_PAGE_MASK (~((__u64)CFS_PAGE_SIZE - 1))
92 typedef __u32 page_off_t;
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:
98 * - "raw" pages (XNU_PAGE_RAW): these are just buffers mapped into KVM,
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.
104 * cfs_page_t 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
108 * To achieve this, all types of pages supported on XNU has to start from
109 * common header that contains only "page type". Common cfs_page_t operations
110 * dispatch through operation vector based on page type.
113 typedef struct xnu_page {
117 struct xnu_page_ops {
118 void *(*page_map) (cfs_page_t *);
119 void (*page_unmap) (cfs_page_t *);
120 void *(*page_address) (cfs_page_t *);
123 void xnu_page_ops_register(int type, struct xnu_page_ops *ops);
124 void xnu_page_ops_unregister(int type);
127 * raw page, no cache object, just like buffer
129 struct xnu_raw_page {
130 struct xnu_page header;
133 struct list_head link;
137 * Public interface to lustre
139 * - cfs_alloc_page(f)
143 * - cfs_page_address(p)
147 * Of all functions above only cfs_kmap(), cfs_kunmap(), and
148 * cfs_page_address() can be called on file system pages. The rest is for raw
152 cfs_page_t *cfs_alloc_page(u_int32_t flags);
153 void cfs_free_page(cfs_page_t *page);
154 void cfs_get_page(cfs_page_t *page);
155 int cfs_put_page_testzero(cfs_page_t *page);
156 int cfs_page_count(cfs_page_t *page);
157 #define cfs_page_index(pg) (0)
159 void *cfs_page_address(cfs_page_t *pg);
160 void *cfs_kmap(cfs_page_t *pg);
161 void cfs_kunmap(cfs_page_t *pg);
167 void *cfs_alloc(size_t nr_bytes, u_int32_t flags);
168 void cfs_free(void *addr);
170 void *cfs_alloc_large(size_t nr_bytes);
171 void cfs_free_large(void *addr);
173 extern int get_preemption_level(void);
175 #define CFS_ALLOC_ATOMIC_TRY \
176 (get_preemption_level() != 0 ? CFS_ALLOC_ATOMIC : 0)
181 * No slab in OSX, use zone allocator to simulate slab
183 #define SLAB_HWCACHE_ALIGN 0
187 * In Darwin8, we cannot use zalloc_noblock(not exported by kernel),
188 * also, direct using of zone allocator is not recommended.
190 #define CFS_INDIVIDUAL_ZONE (0)
192 #if !CFS_INDIVIDUAL_ZONE
193 #include <libkern/OSMalloc.h>
194 typedef OSMallocTag mem_cache_t;
196 typedef void* zone_t;
197 typedef zone_t mem_cache_t;
200 #else /* !__DARWIN8__ */
202 #define CFS_INDIVIDUAL_ZONE (1)
204 typedef zone_t mem_cache_t;
206 #endif /* !__DARWIN8__ */
208 #define MC_NAME_MAX_LEN 64
210 typedef struct cfs_mem_cache {
212 mem_cache_t mc_cache;
213 struct list_head mc_link;
214 char mc_name [MC_NAME_MAX_LEN];
217 #define KMEM_CACHE_MAX_COUNT 64
218 #define KMEM_MAX_ZONE 8192
220 cfs_mem_cache_t * cfs_mem_cache_create (const char *, size_t, size_t, unsigned long);
221 int cfs_mem_cache_destroy ( cfs_mem_cache_t * );
222 void *cfs_mem_cache_alloc ( cfs_mem_cache_t *, int);
223 void cfs_mem_cache_free ( cfs_mem_cache_t *, void *);
228 /* XXX Liang: num_physpages... fix me */
229 #define num_physpages (64 * 1024)
230 #define CFS_NUM_CACHEPAGES num_physpages
232 #define CFS_DECL_MMSPACE
233 #define CFS_MMSPACE_OPEN do {} while(0)
234 #define CFS_MMSPACE_CLOSE do {} while(0)
236 #define copy_from_user(kaddr, uaddr, size) copyin(CAST_USER_ADDR_T(uaddr), (caddr_t)kaddr, size)
237 #define copy_to_user(uaddr, kaddr, size) copyout((caddr_t)kaddr, CAST_USER_ADDR_T(uaddr), size)
240 static inline int strncpy_from_user(char *kaddr, char *uaddr, int size)
243 return copyinstr((const user_addr_t)uaddr, (void *)kaddr, size, &count);
247 #if defined (__ppc__)
248 #define mb() __asm__ __volatile__ ("sync" : : : "memory")
249 #define rmb() __asm__ __volatile__ ("sync" : : : "memory")
250 #define wmb() __asm__ __volatile__ ("eieio" : : : "memory")
251 #elif defined (__i386__)
252 #define mb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory")
254 #define wmb() __asm__ __volatile__ ("": : :"memory")
256 #error architecture not supported
259 #else /* !__KERNEL__ */
261 #define CFS_CACHE_SHIFT 12
262 #define PAGE_CACHE_SIZE (1 << CFS_CACHE_SHIFT)
263 #include <libcfs/user-prim.h>
265 #endif /* __KERNEL__ */
267 #endif /* __XNU_CFS_MEM_H__ */