1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103#include <linux/mm.h>
104#include <linux/slab.h>
105#include <linux/interrupt.h>
106#include <linux/config.h>
107#include <linux/init.h>
108#include <linux/smp.h>
109
110#include <asm/system.h>
111#include <asm/atomic.h>
112#include <asm/smp_lock.h>
113#include <asm/spinlock.h>
114
115
116
117
118#if (PAGE_SIZE != 8192 && PAGE_SIZE != 4096)
119#error Your page size is probably not correctly supported - please check
120#endif
121
122
123
124
125
126
127
128
129
130
131
132
133
134#define SLAB_MGMT_CHECKS 1
135#define SLAB_DEBUG_SUPPORT 0
136#define SLAB_STATS 0
137#define SLAB_SELFTEST 0
138
139
140#define BYTES_PER_WORD sizeof(void *)
141
142
143#if SLAB_DEBUG_SUPPORT
144#if 0
145#define SLAB_C_MASK (SLAB_DEBUG_FREE|SLAB_DEBUG_INITIAL|SLAB_RED_ZONE| \
146 SLAB_POISON|SLAB_HWCACHE_ALIGN|SLAB_NO_REAP| \
147 SLAB_HIGH_PACK)
148#endif
149#define SLAB_C_MASK (SLAB_DEBUG_FREE|SLAB_DEBUG_INITIAL|SLAB_RED_ZONE| \
150 SLAB_POISON|SLAB_HWCACHE_ALIGN|SLAB_NO_REAP)
151#else
152#if 0
153#define SLAB_C_MASK (SLAB_HWCACHE_ALIGN|SLAB_NO_REAP|SLAB_HIGH_PACK)
154#endif
155#define SLAB_C_MASK (SLAB_HWCACHE_ALIGN|SLAB_NO_REAP)
156#endif
157
158
159
160
161
162
163
164
165
166
167
168#define SLAB_OFFSET_BITS 16
169
170typedef struct kmem_slab_s {
171 struct kmem_bufctl_s *s_freep;
172 struct kmem_bufctl_s *s_index;
173 unsigned long s_magic;
174 unsigned long s_inuse;
175
176 struct kmem_slab_s *s_nextp;
177 struct kmem_slab_s *s_prevp;
178 void *s_mem;
179 unsigned long s_offset:SLAB_OFFSET_BITS,
180 s_dma:1;
181} kmem_slab_t;
182
183
184#define slab_align_size (L1_CACHE_ALIGN(sizeof(kmem_slab_t)))
185
186
187#define kmem_slab_end(x) ((kmem_slab_t*)&((x)->c_offset))
188
189
190#define SLAB_MAGIC_ALLOC 0xA5C32F2BUL
191#define SLAB_MAGIC_DESTROYED 0xB2F23C5AUL
192
193
194
195
196
197
198typedef struct kmem_bufctl_s {
199 union {
200 struct kmem_bufctl_s *buf_nextp;
201 kmem_slab_t *buf_slabp;
202 void * buf_objp;
203 } u;
204} kmem_bufctl_t;
205
206
207#define buf_nextp u.buf_nextp
208#define buf_slabp u.buf_slabp
209#define buf_objp u.buf_objp
210
211#if SLAB_DEBUG_SUPPORT
212
213
214
215#define SLAB_RED_MAGIC1 0x5A2CF071UL
216#define SLAB_RED_MAGIC2 0x170FC2A5UL
217
218
219#define SLAB_POISON_BYTE 0x5a
220#define SLAB_POISON_END 0xa5
221
222#endif
223
224
225
226
227struct kmem_cache_s {
228 kmem_slab_t *c_freep;
229 unsigned long c_flags;
230 unsigned long c_offset;
231 unsigned long c_num;
232
233 unsigned long c_magic;
234 unsigned long c_inuse;
235 kmem_slab_t *c_firstp;
236 kmem_slab_t *c_lastp;
237
238 spinlock_t c_spinlock;
239 unsigned long c_growing;
240 unsigned long c_dflags;
241 size_t c_org_size;
242 unsigned long c_gfporder;
243 void (*c_ctor)(void *, kmem_cache_t *, unsigned long);
244 void (*c_dtor)(void *, kmem_cache_t *, unsigned long);
245 unsigned long c_align;
246 size_t c_colour;
247 size_t c_colour_next;
248 unsigned long c_failures;
249 const char *c_name;
250 struct kmem_cache_s *c_nextp;
251 kmem_cache_t *c_index_cachep;
252#if SLAB_STATS
253 unsigned long c_num_active;
254 unsigned long c_num_allocations;
255 unsigned long c_high_mark;
256 unsigned long c_grown;
257 unsigned long c_reaped;
258 atomic_t c_errors;
259#endif
260};
261
262
263#define SLAB_CFLGS_OFF_SLAB 0x010000UL
264#define SLAB_CFLGS_BUFCTL 0x020000UL
265#define SLAB_CFLGS_GENERAL 0x080000UL
266
267
268#define SLAB_CFLGS_GROWN 0x000002UL
269
270#define SLAB_OFF_SLAB(x) ((x) & SLAB_CFLGS_OFF_SLAB)
271#define SLAB_BUFCTL(x) ((x) & SLAB_CFLGS_BUFCTL)
272#define SLAB_GROWN(x) ((x) & SLAB_CFLGS_GROWN)
273
274#if SLAB_STATS
275#define SLAB_STATS_INC_ACTIVE(x) ((x)->c_num_active++)
276#define SLAB_STATS_DEC_ACTIVE(x) ((x)->c_num_active--)
277#define SLAB_STATS_INC_ALLOCED(x) ((x)->c_num_allocations++)
278#define SLAB_STATS_INC_GROWN(x) ((x)->c_grown++)
279#define SLAB_STATS_INC_REAPED(x) ((x)->c_reaped++)
280#define SLAB_STATS_SET_HIGH(x) do { if ((x)->c_num_active > (x)->c_high_mark) \
281 (x)->c_high_mark = (x)->c_num_active; \
282 } while (0)
283#define SLAB_STATS_INC_ERR(x) (atomic_inc(&(x)->c_errors))
284#else
285#define SLAB_STATS_INC_ACTIVE(x)
286#define SLAB_STATS_DEC_ACTIVE(x)
287#define SLAB_STATS_INC_ALLOCED(x)
288#define SLAB_STATS_INC_GROWN(x)
289#define SLAB_STATS_INC_REAPED(x)
290#define SLAB_STATS_SET_HIGH(x)
291#define SLAB_STATS_INC_ERR(x)
292#endif
293
294#if SLAB_SELFTEST
295#if !SLAB_DEBUG_SUPPORT
296#error Debug support needed for self-test
297#endif
298static void kmem_self_test(void);
299#endif
300
301
302#define SLAB_C_MAGIC 0x4F17A36DUL
303
304
305#define SLAB_OBJ_MAX_ORDER 5
306
307
308#define SLAB_MAX_GFP_ORDER 5
309
310
311#define SLAB_MIN_OBJS_PER_SLAB 4
312
313
314
315
316#define SLAB_BREAK_GFP_ORDER 2
317
318
319
320
321
322
323#define SLAB_SET_PAGE_CACHE(pg, x) ((pg)->next = (struct page *)(x))
324#define SLAB_GET_PAGE_CACHE(pg) ((kmem_cache_t *)(pg)->next)
325#define SLAB_SET_PAGE_SLAB(pg, x) ((pg)->prev = (struct page *)(x))
326#define SLAB_GET_PAGE_SLAB(pg) ((kmem_slab_t *)(pg)->prev)
327
328
329typedef struct cache_sizes {
330 size_t cs_size;
331 kmem_cache_t *cs_cachep;
332} cache_sizes_t;
333
334static cache_sizes_t cache_sizes[] = {
335#if PAGE_SIZE == 4096
336 { 32, NULL},
337#endif
338 { 64, NULL},
339 { 128, NULL},
340 { 256, NULL},
341 { 512, NULL},
342 {1024, NULL},
343 {2048, NULL},
344 {4096, NULL},
345 {8192, NULL},
346 {16384, NULL},
347 {32768, NULL},
348 {65536, NULL},
349 {131072, NULL},
350 {0, NULL}
351};
352
353
354
355
356
357static char *cache_sizes_name[] = {
358#if PAGE_SIZE == 4096
359 "size-32",
360#endif
361 "size-64",
362 "size-128",
363 "size-256",
364 "size-512",
365 "size-1024",
366 "size-2048",
367 "size-4096",
368 "size-8192",
369 "size-16384",
370 "size-32768",
371 "size-65536",
372 "size-131072"
373};
374
375
376static kmem_cache_t cache_cache = {
377 kmem_slab_end(&cache_cache), SLAB_NO_REAP,
378 sizeof(kmem_cache_t), 0,
379 SLAB_C_MAGIC, 0,
380 kmem_slab_end(&cache_cache), kmem_slab_end(&cache_cache),
381 SPIN_LOCK_UNLOCKED,
382 0,
383 0,
384 0, 0,
385 NULL, NULL, L1_CACHE_BYTES,
386 0, 0,
387 0,
388 "kmem_cache",
389 &cache_cache,
390 NULL,
391};
392
393
394static struct semaphore cache_chain_sem;
395
396
397static kmem_cache_t *clock_searchp = &cache_cache;
398
399
400static kmem_cache_t *cache_slabp = NULL;
401
402
403
404
405static unsigned long bufctl_limit = 0;
406
407
408__initfunc(long kmem_cache_init(long start, long end))
409{
410 size_t size, i;
411
412#define kmem_slab_offset(x) ((unsigned long)&((kmem_slab_t *)0)->x)
413#define kmem_slab_diff(a,b) (kmem_slab_offset(a) - kmem_slab_offset(b))
414#define kmem_cache_offset(x) ((unsigned long)&((kmem_cache_t *)0)->x)
415#define kmem_cache_diff(a,b) (kmem_cache_offset(a) - kmem_cache_offset(b))
416
417
418 if (kmem_cache_diff(c_firstp, c_magic) != kmem_slab_diff(s_nextp, s_magic) ||
419 kmem_cache_diff(c_firstp, c_inuse) != kmem_slab_diff(s_nextp, s_inuse) ||
420 ((kmem_cache_offset(c_lastp) -
421 ((unsigned long) kmem_slab_end((kmem_cache_t*)NULL))) !=
422 kmem_slab_offset(s_prevp)) ||
423 kmem_cache_diff(c_lastp, c_firstp) != kmem_slab_diff(s_prevp, s_nextp)) {
424
425
426
427
428 panic("kmem_cache_init(): Offsets are wrong - I've been messed with!");
429
430 }
431#undef kmem_cache_offset
432#undef kmem_cache_diff
433#undef kmem_slab_offset
434#undef kmem_slab_diff
435
436 cache_chain_sem = MUTEX;
437
438 size = cache_cache.c_offset + sizeof(kmem_bufctl_t);
439 size += (L1_CACHE_BYTES-1);
440 size &= ~(L1_CACHE_BYTES-1);
441 cache_cache.c_offset = size-sizeof(kmem_bufctl_t);
442
443 i = (PAGE_SIZE<<cache_cache.c_gfporder)-slab_align_size;
444 cache_cache.c_num = i / size;
445
446
447 cache_cache.c_colour = (i-(cache_cache.c_num*size))/L1_CACHE_BYTES;
448 cache_cache.c_colour_next = cache_cache.c_colour;
449
450 return start;
451}
452
453
454
455
456__initfunc(void kmem_cache_sizes_init(void))
457{
458 unsigned int found = 0;
459
460 cache_slabp = kmem_cache_create("slab_cache", sizeof(kmem_slab_t),
461 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
462 if (cache_slabp) {
463 char **names = cache_sizes_name;
464 cache_sizes_t *sizes = cache_sizes;
465 do {
466
467
468
469
470
471 if (!(sizes->cs_cachep =
472 kmem_cache_create(*names++, sizes->cs_size,
473 0, SLAB_HWCACHE_ALIGN, NULL, NULL)))
474 goto panic_time;
475 if (!found) {
476
477 if (SLAB_BUFCTL(sizes->cs_cachep->c_flags))
478 found++;
479 else
480 bufctl_limit =
481 (sizes->cs_size/sizeof(kmem_bufctl_t));
482 }
483 sizes->cs_cachep->c_flags |= SLAB_CFLGS_GENERAL;
484 sizes++;
485 } while (sizes->cs_size);
486#if SLAB_SELFTEST
487 kmem_self_test();
488#endif
489 return;
490 }
491panic_time:
492 panic("kmem_cache_sizes_init: Error creating caches");
493
494}
495
496
497
498
499static inline void *
500kmem_getpages(kmem_cache_t *cachep, unsigned long flags, unsigned int *dma)
501{
502 void *addr;
503
504 *dma = flags & SLAB_DMA;
505 addr = (void*) __get_free_pages(flags & SLAB_LEVEL_MASK,
506 cachep->c_gfporder, *dma);
507
508
509
510
511
512
513 if (!*dma && addr) {
514
515 struct page *page = mem_map + MAP_NR(addr);
516 *dma = 1<<cachep->c_gfporder;
517 while ((*dma)--) {
518 if (!PageDMA(page)) {
519 *dma = 0;
520 break;
521 }
522 page++;
523 }
524 }
525 return addr;
526}
527
528
529static inline void
530kmem_freepages(kmem_cache_t *cachep, void *addr)
531{
532 unsigned long i = (1<<cachep->c_gfporder);
533 struct page *page = &mem_map[MAP_NR(addr)];
534
535
536
537
538
539
540 while (i--) {
541 PageClearSlab(page);
542 page++;
543 }
544 free_pages((unsigned long)addr, cachep->c_gfporder);
545}
546
547#if SLAB_DEBUG_SUPPORT
548static inline void
549kmem_poison_obj(kmem_cache_t *cachep, void *addr)
550{
551 memset(addr, SLAB_POISON_BYTE, cachep->c_org_size);
552 *(unsigned char *)(addr+cachep->c_org_size-1) = SLAB_POISON_END;
553}
554
555static inline int
556kmem_check_poison_obj(kmem_cache_t *cachep, void *addr)
557{
558 void *end;
559 end = memchr(addr, SLAB_POISON_END, cachep->c_org_size);
560 if (end != (addr+cachep->c_org_size-1))
561 return 1;
562 return 0;
563}
564#endif
565
566
567
568
569static inline void
570kmem_slab_unlink(kmem_slab_t *slabp)
571{
572 kmem_slab_t *prevp = slabp->s_prevp;
573 kmem_slab_t *nextp = slabp->s_nextp;
574 prevp->s_nextp = nextp;
575 nextp->s_prevp = prevp;
576}
577
578static inline void
579kmem_slab_link_end(kmem_cache_t *cachep, kmem_slab_t *slabp)
580{
581 kmem_slab_t *lastp = cachep->c_lastp;
582 slabp->s_nextp = kmem_slab_end(cachep);
583 slabp->s_prevp = lastp;
584 cachep->c_lastp = slabp;
585 lastp->s_nextp = slabp;
586}
587
588static inline void
589kmem_slab_link_free(kmem_cache_t *cachep, kmem_slab_t *slabp)
590{
591 kmem_slab_t *nextp = cachep->c_freep;
592 kmem_slab_t *prevp = nextp->s_prevp;
593 slabp->s_nextp = nextp;
594 slabp->s_prevp = prevp;
595 nextp->s_prevp = slabp;
596 slabp->s_prevp->s_nextp = slabp;
597}
598
599
600
601
602
603static void
604kmem_slab_destroy(kmem_cache_t *cachep, kmem_slab_t *slabp)
605{
606 if (cachep->c_dtor
607#if SLAB_DEBUG_SUPPORT
608 || cachep->c_flags & (SLAB_POISON || SLAB_RED_ZONE)
609#endif
610 ) {
611
612 unsigned long num = cachep->c_num;
613 void *objp = slabp->s_mem;
614 do {
615#if SLAB_DEBUG_SUPPORT
616 if (cachep->c_flags & SLAB_RED_ZONE) {
617 if (*((unsigned long*)(objp)) != SLAB_RED_MAGIC1)
618 printk(KERN_ERR "kmem_slab_destroy: "
619 "Bad front redzone - %s\n",
620 cachep->c_name);
621 objp += BYTES_PER_WORD;
622 if (*((unsigned long*)(objp+cachep->c_org_size)) !=
623 SLAB_RED_MAGIC1)
624 printk(KERN_ERR "kmem_slab_destroy: "
625 "Bad rear redzone - %s\n",
626 cachep->c_name);
627 }
628 if (cachep->c_dtor)
629#endif
630 (cachep->c_dtor)(objp, cachep, 0);
631#if SLAB_DEBUG_SUPPORT
632 else if (cachep->c_flags & SLAB_POISON) {
633 if (kmem_check_poison_obj(cachep, objp))
634 printk(KERN_ERR "kmem_slab_destory: "
635 "Bad poison - %s\n", cachep->c_name);
636 }
637 if (cachep->c_flags & SLAB_RED_ZONE)
638 objp -= BYTES_PER_WORD;
639#endif
640 objp += cachep->c_offset;
641 if (!slabp->s_index)
642 objp += sizeof(kmem_bufctl_t);
643 } while (--num);
644 }
645
646 slabp->s_magic = SLAB_MAGIC_DESTROYED;
647 kmem_freepages(cachep, slabp->s_mem-slabp->s_offset);
648 if (slabp->s_index)
649 kmem_cache_free(cachep->c_index_cachep, slabp->s_index);
650 if (SLAB_OFF_SLAB(cachep->c_flags))
651 kmem_cache_free(cache_slabp, slabp);
652}
653
654
655static inline size_t
656kmem_cache_cal_waste(unsigned long gfporder, size_t size, size_t extra,
657 unsigned long flags, size_t *left_over, unsigned long *num)
658{
659 size_t wastage = PAGE_SIZE<<gfporder;
660
661 if (SLAB_OFF_SLAB(flags))
662 gfporder = 0;
663 else
664 gfporder = slab_align_size;
665 wastage -= gfporder;
666 *num = wastage / size;
667 wastage -= (*num * size);
668 *left_over = wastage;
669
670 return (wastage + gfporder + (extra * *num));
671}
672
673
674
675
676
677
678kmem_cache_t *
679kmem_cache_create(const char *name, size_t size, size_t offset,
680 unsigned long flags, void (*ctor)(void*, kmem_cache_t *, unsigned long),
681 void (*dtor)(void*, kmem_cache_t *, unsigned long))
682{
683 const char *func_nm= KERN_ERR "kmem_create: ";
684 kmem_cache_t *searchp;
685 kmem_cache_t *cachep=NULL;
686 size_t extra;
687 size_t left_over;
688 size_t align;
689
690
691#if SLAB_MGMT_CHECKS
692 if (!name) {
693 printk("%sNULL ptr\n", func_nm);
694 goto opps;
695 }
696 if (in_interrupt()) {
697 printk("%sCalled during int - %s\n", func_nm, name);
698 goto opps;
699 }
700
701 if (size < BYTES_PER_WORD) {
702 printk("%sSize too small %d - %s\n", func_nm, (int) size, name);
703 size = BYTES_PER_WORD;
704 }
705
706 if (size > ((1<<SLAB_OBJ_MAX_ORDER)*PAGE_SIZE)) {
707 printk("%sSize too large %d - %s\n", func_nm, (int) size, name);
708 goto opps;
709 }
710
711 if (dtor && !ctor) {
712
713 printk("%sDecon but no con - %s\n", func_nm, name);
714 goto opps;
715 }
716
717 if (offset < 0 || offset > size) {
718 printk("%sOffset weired %d - %s\n", func_nm, (int) offset, name);
719 offset = 0;
720 }
721
722#if SLAB_DEBUG_SUPPORT
723 if ((flags & SLAB_DEBUG_INITIAL) && !ctor) {
724
725 printk("%sNo con, but init state check requested - %s\n", func_nm, name);
726 flags &= ~SLAB_DEBUG_INITIAL;
727 }
728
729 if ((flags & SLAB_POISON) && ctor) {
730
731 printk("%sPoisoning requested, but con given - %s\n", func_nm, name);
732 flags &= ~SLAB_POISON;
733 }
734#if 0
735 if ((flags & SLAB_HIGH_PACK) && ctor) {
736 printk("%sHigh pack requested, but con given - %s\n", func_nm, name);
737 flags &= ~SLAB_HIGH_PACK;
738 }
739 if ((flags & SLAB_HIGH_PACK) && (flags & (SLAB_POISON|SLAB_RED_ZONE))) {
740 printk("%sHigh pack requested, but with poisoning/red-zoning - %s\n",
741 func_nm, name);
742 flags &= ~SLAB_HIGH_PACK;
743 }
744#endif
745#endif
746#endif
747
748
749
750
751 if (flags & ~SLAB_C_MASK) {
752 printk("%sIllgl flg %lX - %s\n", func_nm, flags, name);
753 flags &= SLAB_C_MASK;
754 }
755
756
757 cachep = (kmem_cache_t *) kmem_cache_alloc(&cache_cache, SLAB_KERNEL);
758 if (!cachep)
759 goto opps;
760 memset(cachep, 0, sizeof(kmem_cache_t));
761
762
763
764
765
766 if (size & (BYTES_PER_WORD-1)) {
767 size += (BYTES_PER_WORD-1);
768 size &= ~(BYTES_PER_WORD-1);
769 printk("%sForcing size word alignment - %s\n", func_nm, name);
770 }
771
772 cachep->c_org_size = size;
773#if SLAB_DEBUG_SUPPORT
774 if (flags & SLAB_RED_ZONE) {
775
776 flags &= ~SLAB_HWCACHE_ALIGN;
777 size += 2*BYTES_PER_WORD;
778 }
779#endif
780
781 align = BYTES_PER_WORD;
782 if (flags & SLAB_HWCACHE_ALIGN)
783 align = L1_CACHE_BYTES;
784
785
786 extra = sizeof(kmem_bufctl_t);
787 if (size < (PAGE_SIZE>>3)) {
788
789
790
791#if 0
792 if ((flags & SLAB_HIGH_PACK)) {
793
794
795
796
797 if (size == (L1_CACHE_BYTES/4) || size == (L1_CACHE_BYTES/2) ||
798 size == L1_CACHE_BYTES) {
799
800 extra = 0;
801 } else
802 flags &= ~SLAB_HIGH_PACK;
803 }
804#endif
805 } else {
806
807
808
809 flags |= SLAB_CFLGS_OFF_SLAB;
810 if (!(size & ~PAGE_MASK) || size == (PAGE_SIZE/2)
811 || size == (PAGE_SIZE/4) || size == (PAGE_SIZE/8)) {
812
813 flags |= SLAB_CFLGS_BUFCTL;
814 extra = 0;
815 }
816 }
817 size += extra;
818
819 if (flags & SLAB_HWCACHE_ALIGN) {
820
821 if (size > (L1_CACHE_BYTES/2)) {
822 size_t words = size % L1_CACHE_BYTES;
823 if (words)
824 size += (L1_CACHE_BYTES-words);
825 } else {
826
827 int num_per_line = L1_CACHE_BYTES/size;
828 left_over = L1_CACHE_BYTES - (num_per_line*size);
829 if (left_over) {
830
831 if (left_over%num_per_line) {
832
833 num_per_line--;
834 left_over += size;
835 }
836 size += (left_over/num_per_line);
837 }
838 }
839 } else if (!(size%L1_CACHE_BYTES)) {
840
841 flags |= SLAB_HWCACHE_ALIGN;
842 align = L1_CACHE_BYTES;
843 }
844
845
846
847
848
849
850 do {
851 size_t wastage;
852 unsigned int break_flag = 0;
853cal_wastage:
854 wastage = kmem_cache_cal_waste(cachep->c_gfporder, size, extra,
855 flags, &left_over, &cachep->c_num);
856 if (!cachep->c_num)
857 goto next;
858 if (break_flag)
859 break;
860 if (SLAB_BUFCTL(flags) && cachep->c_num > bufctl_limit) {
861
862 cachep->c_gfporder--;
863 break_flag++;
864 goto cal_wastage;
865 }
866 if (cachep->c_gfporder == SLAB_MAX_GFP_ORDER)
867 break;
868
869
870
871
872 if (cachep->c_num <= SLAB_MIN_OBJS_PER_SLAB) {
873 if (cachep->c_gfporder < SLAB_BREAK_GFP_ORDER)
874 goto next;
875 }
876
877
878 if (left_over <= slab_align_size)
879 break;
880 if ((wastage*8) <= (PAGE_SIZE<<cachep->c_gfporder))
881 break;
882next:
883 cachep->c_gfporder++;
884 } while (1);
885
886
887
888
889 if ((flags & SLAB_CFLGS_OFF_SLAB) && !SLAB_BUFCTL(flags) &&
890 left_over >= slab_align_size) {
891 flags &= ~SLAB_CFLGS_OFF_SLAB;
892 left_over -= slab_align_size;
893 }
894
895
896 offset += (align-1);
897 offset &= ~(align-1);
898
899
900 if (!left_over) {
901 offset = 0;
902 } else if (left_over < offset) {
903 offset = align;
904 if (flags & SLAB_HWCACHE_ALIGN) {
905 if (left_over < offset)
906 offset = 0;
907 } else {
908
909
910
911 if (left_over >= (BYTES_PER_WORD*2)) {
912 offset >>= 1;
913 if (left_over >= (BYTES_PER_WORD*4))
914 offset >>= 1;
915 }
916 }
917 } else if (!offset) {
918
919 offset = left_over/align;
920 if (flags & SLAB_HWCACHE_ALIGN) {
921 if (offset >= 8) {
922
923 align <<= 1;
924 }
925 } else {
926 if (offset >= 10) {
927 align <<= 1;
928 if (offset >= 16)
929 align <<= 1;
930 }
931 }
932 offset = align;
933 }
934
935#if 0
936printk("%s: Left_over:%d Align:%d Size:%d\n", name, left_over, offset, size);
937#endif
938
939 if ((cachep->c_align = (unsigned long) offset))
940 cachep->c_colour = (left_over/offset);
941 cachep->c_colour_next = cachep->c_colour;
942
943
944 if (!SLAB_BUFCTL(flags))
945 size -= sizeof(kmem_bufctl_t);
946 else
947 cachep->c_index_cachep =
948 kmem_find_general_cachep(cachep->c_num*sizeof(kmem_bufctl_t));
949 cachep->c_offset = (unsigned long) size;
950 cachep->c_freep = kmem_slab_end(cachep);
951 cachep->c_firstp = kmem_slab_end(cachep);
952 cachep->c_lastp = kmem_slab_end(cachep);
953 cachep->c_flags = flags;
954 cachep->c_ctor = ctor;
955 cachep->c_dtor = dtor;
956 cachep->c_magic = SLAB_C_MAGIC;
957 cachep->c_name = name;
958 spin_lock_init(&cachep->c_spinlock);
959
960
961 down(&cache_chain_sem);
962 searchp = &cache_cache;
963 do {
964
965 if (!strcmp(searchp->c_name, name)) {
966 printk("%sDup name - %s\n", func_nm, name);
967 break;
968 }
969 searchp = searchp->c_nextp;
970 } while (searchp != &cache_cache);
971
972
973
974
975 cachep->c_nextp = cache_cache.c_nextp;
976 cache_cache.c_nextp = cachep;
977 up(&cache_chain_sem);
978opps:
979 return cachep;
980}
981
982
983
984
985
986
987
988
989
990int
991kmem_cache_shrink(kmem_cache_t *cachep)
992{
993 kmem_cache_t *searchp;
994 kmem_slab_t *slabp;
995 int ret;
996
997 if (!cachep) {
998 printk(KERN_ERR "kmem_shrink: NULL ptr\n");
999 return 2;
1000 }
1001 if (in_interrupt()) {
1002 printk(KERN_ERR "kmem_shrink: Called during int - %s\n", cachep->c_name);
1003 return 2;
1004 }
1005
1006
1007 down(&cache_chain_sem);
1008 searchp = &cache_cache;
1009 for (;searchp->c_nextp != &cache_cache; searchp = searchp->c_nextp) {
1010 if (searchp->c_nextp != cachep)
1011 continue;
1012
1013
1014 if (cachep == clock_searchp)
1015 clock_searchp = cachep->c_nextp;
1016 goto found;
1017 }
1018 up(&cache_chain_sem);
1019 printk(KERN_ERR "kmem_shrink: Invalid cache addr %p\n", cachep);
1020 return 2;
1021found:
1022
1023
1024
1025 up(&cache_chain_sem);
1026 spin_lock_irq(&cachep->c_spinlock);
1027
1028
1029 while (!cachep->c_growing) {
1030 slabp = cachep->c_lastp;
1031 if (slabp->s_inuse || slabp == kmem_slab_end(cachep))
1032 break;
1033 kmem_slab_unlink(slabp);
1034 spin_unlock_irq(&cachep->c_spinlock);
1035 kmem_slab_destroy(cachep, slabp);
1036 spin_lock_irq(&cachep->c_spinlock);
1037 }
1038 ret = 1;
1039 if (cachep->c_lastp == kmem_slab_end(cachep))
1040 ret--;
1041 spin_unlock_irq(&cachep->c_spinlock);
1042 return ret;
1043}
1044
1045
1046static inline kmem_slab_t *
1047kmem_cache_slabmgmt(kmem_cache_t *cachep, void *objp, int local_flags)
1048{
1049 kmem_slab_t *slabp;
1050
1051 if (SLAB_OFF_SLAB(cachep->c_flags)) {
1052
1053 slabp = kmem_cache_alloc(cache_slabp, local_flags);
1054 } else {
1055
1056
1057
1058 void *end;
1059 end = objp + (cachep->c_num * cachep->c_offset);
1060 if (!SLAB_BUFCTL(cachep->c_flags))
1061 end += (cachep->c_num * sizeof(kmem_bufctl_t));
1062 slabp = (kmem_slab_t *) L1_CACHE_ALIGN((unsigned long)end);
1063 }
1064
1065 if (slabp) {
1066 slabp->s_inuse = 0;
1067 slabp->s_dma = 0;
1068 slabp->s_index = NULL;
1069 }
1070
1071 return slabp;
1072}
1073
1074static inline void
1075kmem_cache_init_objs(kmem_cache_t * cachep, kmem_slab_t * slabp, void *objp,
1076 unsigned long ctor_flags)
1077{
1078 kmem_bufctl_t **bufpp = &slabp->s_freep;
1079 unsigned long num = cachep->c_num-1;
1080
1081 do {
1082#if SLAB_DEBUG_SUPPORT
1083 if (cachep->c_flags & SLAB_RED_ZONE) {
1084 *((unsigned long*)(objp)) = SLAB_RED_MAGIC1;
1085 objp += BYTES_PER_WORD;
1086 *((unsigned long*)(objp+cachep->c_org_size)) = SLAB_RED_MAGIC1;
1087 }
1088#endif
1089
1090
1091
1092
1093
1094 if (cachep->c_ctor)
1095 cachep->c_ctor(objp, cachep, ctor_flags);
1096#if SLAB_DEBUG_SUPPORT
1097 else if (cachep->c_flags & SLAB_POISON) {
1098
1099 kmem_poison_obj(cachep, objp);
1100 }
1101
1102 if (cachep->c_flags & SLAB_RED_ZONE) {
1103 if (*((unsigned long*)(objp+cachep->c_org_size)) !=
1104 SLAB_RED_MAGIC1) {
1105 *((unsigned long*)(objp+cachep->c_org_size)) =
1106 SLAB_RED_MAGIC1;
1107 printk(KERN_ERR "kmem_init_obj: Bad rear redzone "
1108 "after constructor - %s\n", cachep->c_name);
1109 }
1110 objp -= BYTES_PER_WORD;
1111 if (*((unsigned long*)(objp)) != SLAB_RED_MAGIC1) {
1112 *((unsigned long*)(objp)) = SLAB_RED_MAGIC1;
1113 printk(KERN_ERR "kmem_init_obj: Bad front redzone "
1114 "after constructor - %s\n", cachep->c_name);
1115 }
1116 }
1117#endif
1118
1119 objp += cachep->c_offset;
1120 if (!slabp->s_index) {
1121 *bufpp = objp;
1122 objp += sizeof(kmem_bufctl_t);
1123 } else
1124 *bufpp = &slabp->s_index[num];
1125 bufpp = &(*bufpp)->buf_nextp;
1126 } while (num--);
1127
1128 *bufpp = NULL;
1129}
1130
1131
1132
1133
1134static int
1135kmem_cache_grow(kmem_cache_t * cachep, int flags)
1136{
1137 kmem_slab_t *slabp;
1138 struct page *page;
1139 void *objp;
1140 size_t offset;
1141 unsigned int dma, local_flags;
1142 unsigned long ctor_flags;
1143 unsigned long save_flags;
1144
1145
1146
1147
1148 if (flags & ~(SLAB_DMA|SLAB_LEVEL_MASK|SLAB_NO_GROW)) {
1149 printk(KERN_WARNING "kmem_grow: Illegal flgs %X (correcting) - %s\n",
1150 flags, cachep->c_name);
1151 flags &= (SLAB_DMA|SLAB_LEVEL_MASK|SLAB_NO_GROW);
1152 }
1153
1154 if (flags & SLAB_NO_GROW)
1155 return 0;
1156
1157
1158
1159
1160
1161
1162 if (in_interrupt() && (flags & SLAB_LEVEL_MASK) != SLAB_ATOMIC) {
1163 printk(KERN_ERR "kmem_grow: Called nonatomically from int - %s\n",
1164 cachep->c_name);
1165 flags &= ~SLAB_LEVEL_MASK;
1166 flags |= SLAB_ATOMIC;
1167 }
1168 ctor_flags = SLAB_CTOR_CONSTRUCTOR;
1169 local_flags = (flags & SLAB_LEVEL_MASK);
1170 if (local_flags == SLAB_ATOMIC) {
1171
1172
1173
1174 ctor_flags |= SLAB_CTOR_ATOMIC;
1175 }
1176
1177
1178 spin_lock_irqsave(&cachep->c_spinlock, save_flags);
1179
1180
1181 if (!(offset = cachep->c_colour_next--))
1182 cachep->c_colour_next = cachep->c_colour;
1183 offset *= cachep->c_align;
1184 cachep->c_dflags = SLAB_CFLGS_GROWN;
1185
1186 cachep->c_growing++;
1187re_try:
1188 spin_unlock_irqrestore(&cachep->c_spinlock, save_flags);
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200 if (!(objp = kmem_getpages(cachep, flags, &dma)))
1201 goto failed;
1202
1203
1204 if (!(slabp = kmem_cache_slabmgmt(cachep, objp+offset, local_flags)))
1205 goto opps1;
1206 if (dma)
1207 slabp->s_dma = 1;
1208 if (SLAB_BUFCTL(cachep->c_flags)) {
1209 slabp->s_index = kmem_cache_alloc(cachep->c_index_cachep, local_flags);
1210 if (!slabp->s_index)
1211 goto opps2;
1212 }
1213
1214
1215 dma = 1 << cachep->c_gfporder;
1216 page = &mem_map[MAP_NR(objp)];
1217 do {
1218 SLAB_SET_PAGE_CACHE(page, cachep);
1219 SLAB_SET_PAGE_SLAB(page, slabp);
1220 PageSetSlab(page);
1221 page++;
1222 } while (--dma);
1223
1224 slabp->s_offset = offset;
1225 objp += offset;
1226 slabp->s_mem = objp;
1227
1228
1229
1230
1231
1232 kmem_cache_init_objs(cachep, slabp, objp, ctor_flags);
1233
1234 spin_lock_irq(&cachep->c_spinlock);
1235
1236
1237 slabp->s_magic = SLAB_MAGIC_ALLOC;
1238 kmem_slab_link_end(cachep, slabp);
1239 if (cachep->c_freep == kmem_slab_end(cachep))
1240 cachep->c_freep = slabp;
1241 SLAB_STATS_INC_GROWN(cachep);
1242 cachep->c_failures = 0;
1243 cachep->c_growing--;
1244
1245 spin_unlock_irqrestore(&cachep->c_spinlock, save_flags);
1246 return 1;
1247opps2:
1248 if (SLAB_OFF_SLAB(cachep->c_flags))
1249 kmem_cache_free(cache_slabp, slabp);
1250opps1:
1251 kmem_freepages(cachep, objp);
1252failed:
1253 spin_lock_irq(&cachep->c_spinlock);
1254 if (local_flags != SLAB_ATOMIC && cachep->c_gfporder) {
1255
1256
1257
1258
1259 if (cachep->c_failures++ < 4 && cachep->c_freep == kmem_slab_end(cachep))
1260 goto re_try;
1261 cachep->c_failures = 1;
1262 }
1263 cachep->c_growing--;
1264 spin_unlock_irqrestore(&cachep->c_spinlock, save_flags);
1265 return 0;
1266}
1267
1268static void
1269kmem_report_alloc_err(const char *str, kmem_cache_t * cachep)
1270{
1271 if (cachep)
1272 SLAB_STATS_INC_ERR(cachep);
1273 printk(KERN_ERR "kmem_alloc: %s (name=%s)\n",
1274 str, cachep ? cachep->c_name : "unknown");
1275}
1276
1277static void
1278kmem_report_free_err(const char *str, const void *objp, kmem_cache_t * cachep)
1279{
1280 if (cachep)
1281 SLAB_STATS_INC_ERR(cachep);
1282 printk(KERN_ERR "kmem_free: %s (objp=%p, name=%s)\n",
1283 str, objp, cachep ? cachep->c_name : "unknown");
1284}
1285
1286
1287
1288
1289
1290static inline kmem_slab_t *
1291kmem_cache_search_dma(kmem_cache_t * cachep)
1292{
1293 kmem_slab_t *slabp = cachep->c_freep->s_nextp;
1294
1295 for (; slabp != kmem_slab_end(cachep); slabp = slabp->s_nextp) {
1296 if (!(slabp->s_dma))
1297 continue;
1298 kmem_slab_unlink(slabp);
1299 kmem_slab_link_free(cachep, slabp);
1300 cachep->c_freep = slabp;
1301 break;
1302 }
1303 return slabp;
1304}
1305
1306#if SLAB_DEBUG_SUPPORT
1307
1308
1309
1310
1311
1312static void *
1313kmem_extra_free_checks(kmem_cache_t * cachep, kmem_bufctl_t *search_bufp,
1314 kmem_bufctl_t *bufp, void * objp)
1315{
1316 if (SLAB_BUFCTL(cachep->c_flags))
1317 return objp;
1318
1319
1320 for (; search_bufp; search_bufp = search_bufp->buf_nextp) {
1321 if (search_bufp != bufp)
1322 continue;
1323 return NULL;
1324 }
1325 return objp;
1326}
1327#endif
1328
1329
1330static inline void
1331kmem_cache_full_free(kmem_cache_t *cachep, kmem_slab_t *slabp)
1332{
1333 if (slabp->s_nextp->s_inuse) {
1334
1335 if (cachep->c_freep == slabp)
1336 cachep->c_freep = slabp->s_nextp;
1337 kmem_slab_unlink(slabp);
1338 kmem_slab_link_end(cachep, slabp);
1339 }
1340}
1341
1342
1343static inline void
1344kmem_cache_one_free(kmem_cache_t *cachep, kmem_slab_t *slabp)
1345{
1346 if (slabp->s_nextp->s_inuse == cachep->c_num) {
1347 kmem_slab_unlink(slabp);
1348 kmem_slab_link_free(cachep, slabp);
1349 }
1350 cachep->c_freep = slabp;
1351}
1352
1353
1354static inline void *
1355__kmem_cache_alloc(kmem_cache_t *cachep, int flags)
1356{
1357 kmem_slab_t *slabp;
1358 kmem_bufctl_t *bufp;
1359 void *objp;
1360 unsigned long save_flags;
1361
1362
1363 if (!cachep)
1364 goto nul_ptr;
1365 spin_lock_irqsave(&cachep->c_spinlock, save_flags);
1366try_again:
1367
1368 slabp = cachep->c_freep;
1369
1370
1371 if (slabp->s_magic != SLAB_MAGIC_ALLOC)
1372 goto alloc_new_slab;
1373
1374 if (flags & SLAB_DMA)
1375 goto search_dma;
1376try_again_dma:
1377 SLAB_STATS_INC_ALLOCED(cachep);
1378 SLAB_STATS_INC_ACTIVE(cachep);
1379 SLAB_STATS_SET_HIGH(cachep);
1380 slabp->s_inuse++;
1381 bufp = slabp->s_freep;
1382 slabp->s_freep = bufp->buf_nextp;
1383 if (slabp->s_freep) {
1384ret_obj:
1385 if (!slabp->s_index) {
1386 bufp->buf_slabp = slabp;
1387 objp = ((void*)bufp) - cachep->c_offset;
1388finished:
1389
1390
1391
1392
1393 spin_unlock_irqrestore(&cachep->c_spinlock, save_flags);
1394#if SLAB_DEBUG_SUPPORT
1395 if (cachep->c_flags & SLAB_RED_ZONE)
1396 goto red_zone;
1397ret_red:
1398 if ((cachep->c_flags & SLAB_POISON) && kmem_check_poison_obj(cachep, objp))
1399 kmem_report_alloc_err("Bad poison", cachep);
1400#endif
1401 return objp;
1402 }
1403
1404 objp = ((bufp-slabp->s_index)*cachep->c_offset) + slabp->s_mem;
1405 bufp->buf_objp = objp;
1406 goto finished;
1407 }
1408 cachep->c_freep = slabp->s_nextp;
1409 goto ret_obj;
1410
1411#if SLAB_DEBUG_SUPPORT
1412red_zone:
1413
1414 if (xchg((unsigned long *)objp, SLAB_RED_MAGIC2) != SLAB_RED_MAGIC1)
1415 kmem_report_alloc_err("Bad front redzone", cachep);
1416 objp += BYTES_PER_WORD;
1417 if (xchg((unsigned long *)(objp+cachep->c_org_size), SLAB_RED_MAGIC2) != SLAB_RED_MAGIC1)
1418 kmem_report_alloc_err("Bad rear redzone", cachep);
1419 goto ret_red;
1420#endif
1421
1422search_dma:
1423 if (slabp->s_dma || (slabp = kmem_cache_search_dma(cachep))!=kmem_slab_end(cachep))
1424 goto try_again_dma;
1425alloc_new_slab:
1426
1427 if (slabp == kmem_slab_end(cachep)) {
1428
1429
1430
1431 spin_unlock_irqrestore(&cachep->c_spinlock, save_flags);
1432 if (kmem_cache_grow(cachep, flags)) {
1433
1434
1435
1436 spin_lock_irq(&cachep->c_spinlock);
1437 goto try_again;
1438 }
1439
1440 spin_lock_irq(&cachep->c_spinlock);
1441 if (cachep->c_freep != kmem_slab_end(cachep))
1442 goto try_again;
1443 } else {
1444
1445 kmem_report_alloc_err("Bad slab magic (corrupt)", cachep);
1446 }
1447 spin_unlock_irqrestore(&cachep->c_spinlock, save_flags);
1448err_exit:
1449 return NULL;
1450nul_ptr:
1451 kmem_report_alloc_err("NULL ptr", NULL);
1452 goto err_exit;
1453}
1454
1455
1456
1457
1458static inline void
1459__kmem_cache_free(kmem_cache_t *cachep, const void *objp)
1460{
1461 kmem_slab_t *slabp;
1462 kmem_bufctl_t *bufp;
1463 unsigned long save_flags;
1464
1465
1466 if (!cachep || !objp)
1467 goto null_addr;
1468
1469#if SLAB_DEBUG_SUPPORT
1470
1471 if (cachep->c_flags & SLAB_DEBUG_INITIAL)
1472 goto init_state_check;
1473finished_initial:
1474
1475 if (cachep->c_flags & SLAB_RED_ZONE)
1476 goto red_zone;
1477return_red:
1478#endif
1479
1480 spin_lock_irqsave(&cachep->c_spinlock, save_flags);
1481
1482 if (SLAB_BUFCTL(cachep->c_flags))
1483 goto bufctl;
1484 bufp = (kmem_bufctl_t *)(objp+cachep->c_offset);
1485
1486
1487#if 0
1488
1489
1490
1491 if (cachep->c_flags & SLAB_HIGH_PACK)
1492 slabp = SLAB_GET_PAGE_SLAB(&mem_map[MAP_NR(bufp)]);
1493 else
1494#endif
1495 slabp = bufp->buf_slabp;
1496
1497check_magic:
1498 if (slabp->s_magic != SLAB_MAGIC_ALLOC)
1499 goto bad_slab;
1500
1501#if SLAB_DEBUG_SUPPORT
1502 if (cachep->c_flags & SLAB_DEBUG_FREE)
1503 goto extra_checks;
1504passed_extra:
1505#endif
1506
1507 if (slabp->s_inuse) {
1508 SLAB_STATS_DEC_ACTIVE(cachep);
1509 slabp->s_inuse--;
1510 bufp->buf_nextp = slabp->s_freep;
1511 slabp->s_freep = bufp;
1512 if (bufp->buf_nextp) {
1513 if (slabp->s_inuse) {
1514
1515finished:
1516#if SLAB_DEBUG_SUPPORT
1517 if (cachep->c_flags & SLAB_POISON) {
1518 if (cachep->c_flags & SLAB_RED_ZONE)
1519 objp += BYTES_PER_WORD;
1520 kmem_poison_obj(cachep, objp);
1521 }
1522#endif
1523 spin_unlock_irqrestore(&cachep->c_spinlock, save_flags);
1524 return;
1525 }
1526 kmem_cache_full_free(cachep, slabp);
1527 goto finished;
1528 }
1529 kmem_cache_one_free(cachep, slabp);
1530 goto finished;
1531 }
1532
1533
1534 spin_unlock_irqrestore(&cachep->c_spinlock, save_flags);
1535 kmem_report_free_err("free with no active objs", objp, cachep);
1536 return;
1537bufctl:
1538
1539
1540
1541 slabp = SLAB_GET_PAGE_SLAB(&mem_map[MAP_NR(objp)]);
1542 bufp = &slabp->s_index[(objp - slabp->s_mem)/cachep->c_offset];
1543 if (bufp->buf_objp == objp)
1544 goto check_magic;
1545 spin_unlock_irqrestore(&cachep->c_spinlock, save_flags);
1546 kmem_report_free_err("Either bad obj addr or double free", objp, cachep);
1547 return;
1548#if SLAB_DEBUG_SUPPORT
1549init_state_check:
1550
1551
1552
1553 cachep->c_ctor(objp, cachep, SLAB_CTOR_CONSTRUCTOR|SLAB_CTOR_VERIFY);
1554 goto finished_initial;
1555extra_checks:
1556 if (!kmem_extra_free_checks(cachep, slabp->s_freep, bufp, objp)) {
1557 spin_unlock_irqrestore(&cachep->c_spinlock, save_flags);
1558 kmem_report_free_err("Double free detected during checks", objp, cachep);
1559 return;
1560 }
1561 goto passed_extra;
1562red_zone:
1563
1564
1565 objp -= BYTES_PER_WORD;
1566 if (xchg((unsigned long *)objp, SLAB_RED_MAGIC1) != SLAB_RED_MAGIC2) {
1567
1568 kmem_report_free_err("Bad front redzone", objp, cachep);
1569 }
1570 if (xchg((unsigned long *)(objp+cachep->c_org_size+BYTES_PER_WORD), SLAB_RED_MAGIC1) != SLAB_RED_MAGIC2) {
1571
1572 kmem_report_free_err("Bad rear redzone", objp, cachep);
1573 }
1574 goto return_red;
1575#endif
1576
1577bad_slab:
1578
1579 if (slabp->s_magic == SLAB_MAGIC_DESTROYED) {
1580
1581 kmem_report_free_err("free from inactive slab", objp, cachep);
1582 } else
1583 kmem_report_free_err("Bad obj addr", objp, cachep);
1584 spin_unlock_irqrestore(&cachep->c_spinlock, save_flags);
1585
1586#if 1
1587
1588*(int *) 0 = 0;
1589#endif
1590
1591 return;
1592null_addr:
1593 kmem_report_free_err("NULL ptr", objp, cachep);
1594 return;
1595}
1596
1597void *
1598kmem_cache_alloc(kmem_cache_t *cachep, int flags)
1599{
1600 return __kmem_cache_alloc(cachep, flags);
1601}
1602
1603void
1604kmem_cache_free(kmem_cache_t *cachep, void *objp)
1605{
1606 __kmem_cache_free(cachep, objp);
1607}
1608
1609void *
1610kmalloc(size_t size, int flags)
1611{
1612 cache_sizes_t *csizep = cache_sizes;
1613
1614 for (; csizep->cs_size; csizep++) {
1615 if (size > csizep->cs_size)
1616 continue;
1617 return __kmem_cache_alloc(csizep->cs_cachep, flags);
1618 }
1619 printk(KERN_ERR "kmalloc: Size (%lu) too large\n", (unsigned long) size);
1620 return NULL;
1621}
1622
1623void
1624kfree(const void *objp)
1625{
1626 struct page *page;
1627 int nr;
1628
1629 if (!objp)
1630 goto null_ptr;
1631 nr = MAP_NR(objp);
1632 if (nr >= max_mapnr)
1633 goto bad_ptr;
1634
1635
1636
1637
1638
1639
1640
1641 page = &mem_map[nr];
1642 if (PageSlab(page)) {
1643 kmem_cache_t *cachep;
1644
1645
1646
1647
1648
1649
1650 cachep = SLAB_GET_PAGE_CACHE(page);
1651 if (cachep && (cachep->c_flags & SLAB_CFLGS_GENERAL)) {
1652 __kmem_cache_free(cachep, objp);
1653 return;
1654 }
1655 }
1656bad_ptr:
1657 printk(KERN_ERR "kfree: Bad obj %p\n", objp);
1658
1659#if 1
1660
1661*(int *) 0 = 0;
1662#endif
1663
1664null_ptr:
1665 return;
1666}
1667
1668void
1669kfree_s(const void *objp, size_t size)
1670{
1671 struct page *page;
1672 int nr;
1673
1674 if (!objp)
1675 goto null_ptr;
1676 nr = MAP_NR(objp);
1677 if (nr >= max_mapnr)
1678 goto null_ptr;
1679
1680 page = &mem_map[nr];
1681 if (PageSlab(page)) {
1682 kmem_cache_t *cachep;
1683
1684 cachep = SLAB_GET_PAGE_CACHE(page);
1685 if (cachep && cachep->c_flags & SLAB_CFLGS_GENERAL) {
1686 if (size <= cachep->c_org_size) {
1687 __kmem_cache_free(cachep, objp);
1688 return;
1689 }
1690 }
1691 }
1692null_ptr:
1693 printk(KERN_ERR "kfree_s: Bad obj %p\n", objp);
1694 return;
1695}
1696
1697kmem_cache_t *
1698kmem_find_general_cachep(size_t size)
1699{
1700 cache_sizes_t *csizep = cache_sizes;
1701
1702
1703
1704
1705
1706 for (; csizep->cs_size; csizep++) {
1707 if (size > csizep->cs_size)
1708 continue;
1709 break;
1710 }
1711 return csizep->cs_cachep;
1712}
1713
1714
1715
1716
1717
1718
1719int
1720kmem_cache_reap(int pri, int dma, int wait)
1721{
1722 kmem_slab_t *slabp;
1723 kmem_cache_t *searchp;
1724 kmem_cache_t *best_cachep;
1725 unsigned int scan;
1726 unsigned int reap_level;
1727 static unsigned long call_count = 0;
1728
1729 if (in_interrupt()) {
1730 printk("kmem_cache_reap() called within int!\n");
1731 return 0;
1732 }
1733
1734
1735
1736
1737 down(&cache_chain_sem);
1738
1739 scan = 10-pri;
1740 if (pri == 6 && !dma) {
1741 if (++call_count == 199) {
1742
1743
1744
1745 call_count = 0UL;
1746 reap_level = 0;
1747 scan += 2;
1748 } else
1749 reap_level = 3;
1750 } else {
1751 if (pri >= 5) {
1752
1753
1754
1755
1756
1757 reap_level = 2;
1758 } else
1759 reap_level = 0;
1760 }
1761
1762 best_cachep = NULL;
1763 searchp = clock_searchp;
1764 do {
1765 unsigned int full_free;
1766 unsigned int dma_flag;
1767
1768
1769 if (searchp->c_flags & SLAB_NO_REAP)
1770 goto next;
1771 spin_lock_irq(&searchp->c_spinlock);
1772 if (searchp->c_growing)
1773 goto next_unlock;
1774 if (searchp->c_dflags & SLAB_CFLGS_GROWN) {
1775 searchp->c_dflags &= ~SLAB_CFLGS_GROWN;
1776 goto next_unlock;
1777 }
1778
1779 if (searchp->c_inuse || searchp->c_magic != SLAB_C_MAGIC) {
1780 spin_unlock_irq(&searchp->c_spinlock);
1781 printk(KERN_ERR "kmem_reap: Corrupted cache struct for %s\n", searchp->c_name);
1782 goto next;
1783 }
1784 dma_flag = 0;
1785 full_free = 0;
1786
1787
1788
1789
1790 slabp = searchp->c_lastp;
1791 while (!slabp->s_inuse && slabp != kmem_slab_end(searchp)) {
1792 slabp = slabp->s_prevp;
1793 full_free++;
1794 if (slabp->s_dma)
1795 dma_flag++;
1796 }
1797 spin_unlock_irq(&searchp->c_spinlock);
1798
1799 if (dma && !dma_flag)
1800 goto next;
1801
1802 if (full_free) {
1803 if (full_free >= 10) {
1804 best_cachep = searchp;
1805 break;
1806 }
1807
1808
1809
1810
1811
1812 if (pri == 6) {
1813 if (searchp->c_gfporder || searchp->c_ctor)
1814 full_free--;
1815 }
1816 if (full_free >= reap_level) {
1817 reap_level = full_free;
1818 best_cachep = searchp;
1819 }
1820 }
1821 goto next;
1822next_unlock:
1823 spin_unlock_irq(&searchp->c_spinlock);
1824next:
1825 searchp = searchp->c_nextp;
1826 } while (--scan && searchp != clock_searchp);
1827
1828 clock_searchp = searchp;
1829 up(&cache_chain_sem);
1830
1831 if (!best_cachep) {
1832
1833 return 0;
1834 }
1835
1836 spin_lock_irq(&best_cachep->c_spinlock);
1837 if (!best_cachep->c_growing && !(slabp = best_cachep->c_lastp)->s_inuse && slabp != kmem_slab_end(best_cachep)) {
1838 if (dma) {
1839 do {
1840 if (slabp->s_dma)
1841 goto good_dma;
1842 slabp = slabp->s_prevp;
1843 } while (!slabp->s_inuse && slabp != kmem_slab_end(best_cachep));
1844
1845
1846
1847
1848 goto dma_fail;
1849good_dma:
1850 }
1851 if (slabp == best_cachep->c_freep)
1852 best_cachep->c_freep = slabp->s_nextp;
1853 kmem_slab_unlink(slabp);
1854 SLAB_STATS_INC_REAPED(best_cachep);
1855
1856
1857
1858
1859 spin_unlock_irq(&best_cachep->c_spinlock);
1860 kmem_slab_destroy(best_cachep, slabp);
1861 return 1;
1862 }
1863dma_fail:
1864 spin_unlock_irq(&best_cachep->c_spinlock);
1865 return 0;
1866}
1867
1868#if SLAB_SELFTEST
1869
1870static void
1871kmem_self_test(void)
1872{
1873 kmem_cache_t *test_cachep;
1874
1875 printk(KERN_INFO "kmem_test() - start\n");
1876 test_cachep = kmem_cache_create("test-cachep", 16, 0, SLAB_RED_ZONE|SLAB_POISON, NULL, NULL);
1877 if (test_cachep) {
1878 char *objp = kmem_cache_alloc(test_cachep, SLAB_KERNEL);
1879 if (objp) {
1880
1881 *(objp-1) = 1;
1882 *(objp+16) = 1;
1883 kmem_cache_free(test_cachep, objp);
1884
1885
1886 *objp = 10;
1887 objp = kmem_cache_alloc(test_cachep, SLAB_KERNEL);
1888 kmem_cache_free(test_cachep, objp);
1889
1890
1891 *objp = 10;
1892 kmem_cache_shrink(test_cachep);
1893 }
1894 }
1895 printk(KERN_INFO "kmem_test() - finished\n");
1896}
1897#endif
1898
1899#if defined(CONFIG_PROC_FS)
1900
1901
1902
1903int
1904get_slabinfo(char *buf)
1905{
1906 kmem_cache_t *cachep;
1907 kmem_slab_t *slabp;
1908 unsigned long active_objs;
1909 unsigned long save_flags;
1910 unsigned long num_slabs;
1911 unsigned long num_objs;
1912 int len=0;
1913#if SLAB_STATS
1914 unsigned long active_slabs;
1915#endif
1916
1917 __save_flags(save_flags);
1918
1919
1920
1921
1922#if SLAB_STATS
1923 len = sprintf(buf, "slabinfo - version: 1.0 (statistics)\n");
1924#else
1925 len = sprintf(buf, "slabinfo - version: 1.0\n");
1926#endif
1927 down(&cache_chain_sem);
1928 cachep = &cache_cache;
1929 do {
1930#if SLAB_STATS
1931 active_slabs = 0;
1932#endif
1933 num_slabs = active_objs = 0;
1934 spin_lock_irq(&cachep->c_spinlock);
1935 for (slabp = cachep->c_firstp; slabp != kmem_slab_end(cachep); slabp = slabp->s_nextp) {
1936 active_objs += slabp->s_inuse;
1937 num_slabs++;
1938#if SLAB_STATS
1939 if (slabp->s_inuse)
1940 active_slabs++;
1941#endif
1942 }
1943 num_objs = cachep->c_num*num_slabs;
1944#if SLAB_STATS
1945 {
1946 unsigned long errors;
1947 unsigned long high = cachep->c_high_mark;
1948 unsigned long grown = cachep->c_grown;
1949 unsigned long reaped = cachep->c_reaped;
1950 unsigned long allocs = cachep->c_num_allocations;
1951 errors = (unsigned long) atomic_read(&cachep->c_errors);
1952 spin_unlock_irqrestore(&cachep->c_spinlock, save_flags);
1953 len += sprintf(buf+len, "%-16s %6lu %6lu %4lu %4lu %4lu %6lu %7lu %5lu %4lu %4lu\n",
1954 cachep->c_name, active_objs, num_objs, active_slabs, num_slabs,
1955 (1<<cachep->c_gfporder)*num_slabs,
1956 high, allocs, grown, reaped, errors);
1957 }
1958#else
1959 spin_unlock_irqrestore(&cachep->c_spinlock, save_flags);
1960 len += sprintf(buf+len, "%-17s %6lu %6lu\n", cachep->c_name, active_objs, num_objs);
1961#endif
1962 } while ((cachep = cachep->c_nextp) != &cache_cache);
1963 up(&cache_chain_sem);
1964
1965 return len;
1966}
1967#endif
1968