This source file includes following definitions.
- kmalloc_init
- get_order
- kmalloc
- kfree
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 #include <linux/mm.h>
18 #include <linux/delay.h>
19 #include <asm/system.h>
20 #include <asm/dma.h>
21
22
23 #undef SADISTIC_KMALLOC
24
25
26
27 #define MF_USED 0xffaa0055
28 #define MF_DMA 0xff00aa55
29 #define MF_FREE 0x0055ffaa
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 struct block_header {
47 unsigned long bh_flags;
48 union {
49 unsigned long ubh_length;
50 struct block_header *fbh_next;
51 } vp;
52 };
53
54
55 #define bh_length vp.ubh_length
56 #define bh_next vp.fbh_next
57 #define BH(p) ((struct block_header *)(p))
58
59
60
61
62
63 struct page_descriptor {
64 struct page_descriptor *next;
65 struct block_header *firstfree;
66 int order;
67 int nfree;
68 };
69
70
71 #define PAGE_DESC(p) ((struct page_descriptor *)(((unsigned long)(p)) & PAGE_MASK))
72
73
74
75
76
77
78 struct size_descriptor {
79 struct page_descriptor *firstfree;
80 struct page_descriptor *dmafree;
81 int size;
82 int nblocks;
83
84 int nmallocs;
85 int nfrees;
86 int nbytesmalloced;
87 int npages;
88 unsigned long gfporder;
89 };
90
91
92
93
94
95 #if PAGE_SIZE == 4096
96 struct size_descriptor sizes[] =
97 {
98 {NULL, NULL, 32, 127, 0, 0, 0, 0, 0},
99 {NULL, NULL, 64, 63, 0, 0, 0, 0, 0},
100 {NULL, NULL, 128, 31, 0, 0, 0, 0, 0},
101 {NULL, NULL, 252, 16, 0, 0, 0, 0, 0},
102 {NULL, NULL, 508, 8, 0, 0, 0, 0, 0},
103 {NULL, NULL, 1020, 4, 0, 0, 0, 0, 0},
104 {NULL, NULL, 2040, 2, 0, 0, 0, 0, 0},
105 {NULL, NULL, 4096 - 16, 1, 0, 0, 0, 0, 0},
106 {NULL, NULL, 8192 - 16, 1, 0, 0, 0, 0, 1},
107 {NULL, NULL, 16384 - 16, 1, 0, 0, 0, 0, 2},
108 {NULL, NULL, 32768 - 16, 1, 0, 0, 0, 0, 3},
109 {NULL, NULL, 65536 - 16, 1, 0, 0, 0, 0, 4},
110 {NULL, NULL, 131072 - 16, 1, 0, 0, 0, 0, 5},
111 {NULL, NULL, 0, 0, 0, 0, 0, 0, 0}
112 };
113 #elif PAGE_SIZE == 8192
114 struct size_descriptor sizes[] =
115 {
116 {NULL, NULL, 64, 127, 0, 0, 0, 0, 0},
117 {NULL, NULL, 128, 63, 0, 0, 0, 0, 0},
118 {NULL, NULL, 248, 31, 0, 0, 0, 0, 0},
119 {NULL, NULL, 504, 16, 0, 0, 0, 0, 0},
120 {NULL, NULL, 1016, 8, 0, 0, 0, 0, 0},
121 {NULL, NULL, 2040, 4, 0, 0, 0, 0, 0},
122 {NULL, NULL, 4080, 2, 0, 0, 0, 0, 0},
123 {NULL, NULL, 8192 - 32, 1, 0, 0, 0, 0, 0},
124 {NULL, NULL, 16384 - 32, 1, 0, 0, 0, 0, 1},
125 {NULL, NULL, 32768 - 32, 1, 0, 0, 0, 0, 2},
126 {NULL, NULL, 65536 - 32, 1, 0, 0, 0, 0, 3},
127 {NULL, NULL, 131072 - 32, 1, 0, 0, 0, 0, 4},
128 {NULL, NULL, 262144 - 32, 1, 0, 0, 0, 0, 5},
129 {NULL, NULL, 0, 0, 0, 0, 0, 0, 0}
130 };
131 #else
132 #error you need to make a version for your pagesize
133 #endif
134
135 #define NBLOCKS(order) (sizes[order].nblocks)
136 #define BLOCKSIZE(order) (sizes[order].size)
137 #define AREASIZE(order) (PAGE_SIZE<<(sizes[order].gfporder))
138
139
140 long kmalloc_init(long start_mem, long end_mem)
141 {
142 int order;
143
144
145
146
147
148 for (order = 0; BLOCKSIZE(order); order++) {
149 if ((NBLOCKS(order) * BLOCKSIZE(order) + sizeof(struct page_descriptor)) >
150 AREASIZE(order)) {
151 printk("Cannot use %d bytes out of %d in order = %d block mallocs\n",
152 (int) (NBLOCKS(order) * BLOCKSIZE(order) +
153 sizeof(struct page_descriptor)),
154 (int) AREASIZE(order),
155 BLOCKSIZE(order));
156 panic("This only happens if someone messes with kmalloc");
157 }
158 }
159 return start_mem;
160 }
161
162
163
164 int get_order(int size)
165 {
166 int order;
167
168
169 size += sizeof(struct block_header);
170 for (order = 0; BLOCKSIZE(order); order++)
171 if (size <= BLOCKSIZE(order))
172 return order;
173 return -1;
174 }
175
176 void *kmalloc(size_t size, int priority)
177 {
178 unsigned long flags;
179 unsigned long type;
180 int order, i, sz;
181 struct block_header *p;
182 struct page_descriptor *page, **pg;
183
184 order = get_order(size);
185 if (order < 0) {
186 printk("kmalloc of too large a block (%d bytes).\n", (int) size);
187 return (NULL);
188 }
189
190 type = MF_USED;
191 pg = &sizes[order].firstfree;
192 if (priority & GFP_DMA) {
193 type = MF_DMA;
194 pg = &sizes[order].dmafree;
195 }
196
197 priority &= GFP_LEVEL_MASK;
198
199
200 if (intr_count && priority != GFP_ATOMIC) {
201 static int count = 0;
202 if (++count < 5) {
203 printk("kmalloc called nonatomically from interrupt %p\n",
204 __builtin_return_address(0));
205 priority = GFP_ATOMIC;
206 }
207 }
208
209 save_flags(flags);
210 cli();
211 page = *pg;
212 if (page) {
213 p = page->firstfree;
214 if (p->bh_flags != MF_FREE) {
215 restore_flags(flags);
216 printk("Problem: block on freelist at %08lx isn't free.\n", (long) p);
217 return NULL;
218 }
219 goto found_it;
220 }
221
222
223
224 restore_flags(flags);
225
226
227 sz = BLOCKSIZE(order);
228
229 page = (struct page_descriptor *) __get_free_pages(priority,
230 sizes[order].gfporder, priority & GFP_DMA);
231
232 if (!page) {
233 static unsigned long last = 0;
234 if (priority != GFP_BUFFER && (last + 10 * HZ < jiffies)) {
235 last = jiffies;
236 printk("Couldn't get a free page.....\n");
237 }
238 return NULL;
239 }
240 sizes[order].npages++;
241
242
243 for (i = NBLOCKS(order), p = BH(page + 1); i > 1; i--, p = p->bh_next) {
244 p->bh_flags = MF_FREE;
245 p->bh_next = BH(((long) p) + sz);
246 }
247
248 p->bh_flags = MF_FREE;
249 p->bh_next = NULL;
250
251 page->order = order;
252 page->nfree = NBLOCKS(order);
253 p = BH(page+1);
254
255
256
257
258
259 cli();
260 page->next = *pg;
261 *pg = page;
262
263 found_it:
264 page->firstfree = p->bh_next;
265 page->nfree--;
266 if (!page->nfree)
267 *pg = page->next;
268 restore_flags(flags);
269 sizes[order].nmallocs++;
270 sizes[order].nbytesmalloced += size;
271 p->bh_flags = type;
272 p->bh_length = size;
273 #ifdef SADISTIC_KMALLOC
274 memset(p+1, 0xf0, size);
275 #endif
276 return p + 1;
277 }
278
279 void kfree(void *ptr)
280 {
281 int size;
282 unsigned long flags;
283 int order;
284 register struct block_header *p;
285 struct page_descriptor *page, **pg;
286
287 if (!ptr)
288 return;
289 p = ((struct block_header *) ptr) - 1;
290 page = PAGE_DESC(p);
291 order = page->order;
292 pg = &sizes[order].firstfree;
293 if (p->bh_flags == MF_DMA) {
294 p->bh_flags = MF_USED;
295 pg = &sizes[order].dmafree;
296 }
297
298 if ((order < 0) ||
299 (order >= sizeof(sizes) / sizeof(sizes[0])) ||
300 (((long) (page->next)) & ~PAGE_MASK) ||
301 (p->bh_flags != MF_USED)) {
302 printk("kfree of non-kmalloced memory: %p, next= %p, order=%d\n",
303 p, page->next, page->order);
304 return;
305 }
306 size = p->bh_length;
307 p->bh_flags = MF_FREE;
308 #ifdef SADISTIC_KMALLOC
309 memset(p+1, 0xe0, size);
310 #endif
311 save_flags(flags);
312 cli();
313 p->bh_next = page->firstfree;
314 page->firstfree = p;
315 page->nfree++;
316
317 if (page->nfree == 1) {
318
319 page->next = *pg;
320 *pg = page;
321 }
322
323 if (page->nfree == NBLOCKS(order)) {
324 for (;;) {
325 struct page_descriptor *tmp = *pg;
326 if (!tmp) {
327 printk("Ooops. page %p doesn't show on freelist.\n", page);
328 break;
329 }
330 if (tmp == page) {
331 *pg = page->next;
332 break;
333 }
334 pg = &tmp->next;
335 }
336 sizes[order].npages--;
337 free_pages((long) page, sizes[order].gfporder);
338 }
339 sizes[order].nfrees++;
340 sizes[order].nbytesmalloced -= size;
341 restore_flags(flags);
342 }