]>
Commit | Line | Data |
---|---|---|
b34b9563 | 1 | /* |
e5b9b344 BB |
2 | * Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC. |
3 | * Copyright (C) 2007 The Regents of the University of California. | |
4 | * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER). | |
5 | * Written by Brian Behlendorf <behlendorf1@llnl.gov>. | |
6 | * UCRL-CODE-235197 | |
7 | * | |
8 | * This file is part of the SPL, Solaris Porting Layer. | |
9 | * For details, see <http://zfsonlinux.org/>. | |
10 | * | |
11 | * The SPL is free software; you can redistribute it and/or modify it | |
12 | * under the terms of the GNU General Public License as published by the | |
13 | * Free Software Foundation; either version 2 of the License, or (at your | |
14 | * option) any later version. | |
15 | * | |
16 | * The SPL is distributed in the hope that it will be useful, but WITHOUT | |
17 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
18 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
19 | * for more details. | |
20 | * | |
21 | * You should have received a copy of the GNU General Public License along | |
22 | * with the SPL. If not, see <http://www.gnu.org/licenses/>. | |
b34b9563 | 23 | */ |
e5b9b344 BB |
24 | |
25 | #ifndef _SPL_VMEM_H | |
26 | #define _SPL_VMEM_H | |
27 | ||
28 | #include <sys/kmem.h> | |
29 | #include <linux/sched.h> | |
30 | #include <linux/vmalloc.h> | |
31 | ||
32 | typedef struct vmem { } vmem_t; | |
33 | ||
34 | extern vmem_t *heap_arena; | |
35 | extern vmem_t *zio_alloc_arena; | |
36 | extern vmem_t *zio_arena; | |
37 | ||
38 | extern size_t vmem_size(vmem_t *vmp, int typemask); | |
39 | ||
40 | /* | |
41 | * Memory allocation interfaces | |
42 | */ | |
b34b9563 BB |
43 | #define VMEM_ALLOC 0x01 |
44 | #define VMEM_FREE 0x02 | |
e5b9b344 BB |
45 | |
46 | #ifndef VMALLOC_TOTAL | |
b34b9563 | 47 | #define VMALLOC_TOTAL (VMALLOC_END - VMALLOC_START) |
e5b9b344 BB |
48 | #endif |
49 | ||
e5b9b344 | 50 | /* |
c3eabc75 BB |
51 | * vmem_* is an interface to a low level arena-based memory allocator on |
52 | * Illumos that is used to allocate virtual address space. The kmem SLAB | |
53 | * allocator allocates slabs from it. Then the generic allocation functions | |
54 | * kmem_{alloc,zalloc,free}() are layered on top of SLAB allocators. | |
e5b9b344 | 55 | * |
c3eabc75 BB |
56 | * On Linux, the primary means of doing allocations is via kmalloc(), which |
57 | * is similarly layered on top of something called the buddy allocator. The | |
58 | * buddy allocator is not available to kernel modules, it uses physical | |
59 | * memory addresses rather than virtual memory addresses and is prone to | |
60 | * fragmentation. | |
e5b9b344 | 61 | * |
c3eabc75 BB |
62 | * Linux sets aside a relatively small address space for in-kernel virtual |
63 | * memory from which allocations can be done using vmalloc(). It might seem | |
64 | * like a good idea to use vmalloc() to implement something similar to | |
65 | * Illumos' allocator. However, this has the following problems: | |
66 | * | |
67 | * 1. Page directory table allocations are hard coded to use GFP_KERNEL. | |
68 | * Consequently, any KM_PUSHPAGE or KM_NOSLEEP allocations done using | |
69 | * vmalloc() will not have proper semantics. | |
70 | * | |
71 | * 2. Address space exhaustion is a real issue on 32-bit platforms where | |
72 | * only a few 100MB are available. The kernel will handle it by spinning | |
73 | * when it runs out of address space. | |
74 | * | |
75 | * 3. All vmalloc() allocations and frees are protected by a single global | |
76 | * lock which serializes all allocations. | |
e5b9b344 | 77 | * |
c3eabc75 BB |
78 | * 4. Accessing /proc/meminfo and /proc/vmallocinfo will iterate the entire |
79 | * list. The former will sum the allocations while the latter will print | |
80 | * them to user space in a way that user space can keep the lock held | |
81 | * indefinitely. When the total number of mapped allocations is large | |
82 | * (several 100,000) a large amount of time will be spent waiting on locks. | |
83 | * | |
84 | * 5. Linux has a wait_on_bit() locking primitive that assumes physical | |
85 | * memory is used, it simply does not work on virtual memory. Certain | |
86 | * Linux structures (e.g. the superblock) use them and might be embedded | |
87 | * into a structure from Illumos. This makes using Linux virtual memory | |
88 | * unsafe in certain situations. | |
89 | * | |
90 | * It follows that we cannot obtain identical semantics to those on Illumos. | |
91 | * Consequently, we implement the kmem_{alloc,zalloc,free}() functions in | |
92 | * such a way that they can be used as drop-in replacements for small vmem_* | |
93 | * allocations (8MB in size or smaller) and map vmem_{alloc,zalloc,free}() | |
94 | * to them. | |
e5b9b344 | 95 | */ |
e5b9b344 | 96 | |
c3eabc75 BB |
97 | #define vmem_alloc(sz, fl) spl_vmem_alloc((sz), (fl), __func__, __LINE__) |
98 | #define vmem_zalloc(sz, fl) spl_vmem_zalloc((sz), (fl), __func__, __LINE__) | |
99 | #define vmem_free(ptr, sz) spl_vmem_free((ptr), (sz)) | |
77ab5dd3 | 100 | #define vmem_qcache_reap(ptr) ((void)0) |
c3eabc75 BB |
101 | |
102 | extern void *spl_vmem_alloc(size_t sz, int fl, const char *func, int line); | |
103 | extern void *spl_vmem_zalloc(size_t sz, int fl, const char *func, int line); | |
104 | extern void spl_vmem_free(const void *ptr, size_t sz); | |
e5b9b344 BB |
105 | |
106 | int spl_vmem_init(void); | |
107 | void spl_vmem_fini(void); | |
108 | ||
109 | #endif /* _SPL_VMEM_H */ |