00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 #include <linux/config.h>
00078 #include <linux/slab.h>
00079 #include <linux/interrupt.h>
00080 #include <linux/init.h>
00081 #include <linux/compiler.h>
00082 #include <asm/uaccess.h>
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 #define CONFIG_DEBUG_SLAB
00096 #ifdef CONFIG_DEBUG_SLAB
00097 #define DEBUG 1
00098 #define STATS 1
00099 #define FORCED_DEBUG 1
00100 #else
00101 #define DEBUG 0
00102 #define STATS 0
00103 #define FORCED_DEBUG 0
00104 #endif
00105
00106
00107
00108
00109 #define REAP_SCANLEN 10
00110 #define REAP_PERFECT 10
00111
00112
00113 #define BYTES_PER_WORD sizeof(void *)
00114
00115
00116 #if DEBUG
00117 # define CREATE_MASK (SLAB_DEBUG_INITIAL | SLAB_RED_ZONE | \
00118 SLAB_POISON | SLAB_HWCACHE_ALIGN | \
00119 SLAB_NO_REAP | SLAB_CACHE_DMA | \
00120 SLAB_MUST_HWCACHE_ALIGN)
00121 #else
00122 # define CREATE_MASK (SLAB_HWCACHE_ALIGN | SLAB_NO_REAP | \
00123 SLAB_CACHE_DMA | SLAB_MUST_HWCACHE_ALIGN)
00124 #endif
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 #define BUFCTL_END 0xffffFFFF
00146 #define SLAB_LIMIT 0xffffFFFE
00147 typedef unsigned int kmem_bufctl_t;
00148
00149
00150
00151
00152 static unsigned long offslab_limit;
00153
00154
00155
00156
00157
00158
00159
00160
00161 typedef struct slab_s {
00162 struct list_head list;
00163 unsigned long colouroff;
00164 void *s_mem;
00165 unsigned int inuse;
00166 kmem_bufctl_t free;
00167 } slab_t;
00168
00169 #define slab_bufctl(slabp) \
00170 ((kmem_bufctl_t *)(((slab_t*)slabp)+1))
00171
00172
00173
00174
00175
00176
00177
00178
00179 typedef struct cpucache_s {
00180 unsigned int avail;
00181 unsigned int limit;
00182 } cpucache_t;
00183
00184 #define cc_entry(cpucache) \
00185 ((void **)(((cpucache_t*)(cpucache))+1))
00186 #define cc_data(cachep) \
00187 ((cachep)->cpudata[smp_processor_id()])
00188
00189
00190
00191
00192
00193
00194 #define CACHE_NAMELEN 20
00195
00196 struct kmem_cache_s {
00197
00198
00199 struct list_head slabs_full;
00200 struct list_head slabs_partial;
00201 struct list_head slabs_free;
00202 unsigned int objsize;
00203 unsigned int flags;
00204 unsigned int num;
00205 spinlock_t spinlock;
00206 #ifdef CONFIG_SMP
00207 unsigned int batchcount;
00208 #endif
00209
00210
00211
00212 unsigned int gfporder;
00213
00214
00215 unsigned int gfpflags;
00216
00217 size_t colour;
00218 unsigned int colour_off;
00219 unsigned int colour_next;
00220 kmem_cache_t *slabp_cache;
00221 unsigned int growing;
00222 unsigned int dflags;
00223
00224
00225 void (*ctor)(void *, kmem_cache_t *, unsigned long);
00226
00227
00228 void (*dtor)(void *, kmem_cache_t *, unsigned long);
00229
00230 unsigned long failures;
00231
00232
00233 char name[CACHE_NAMELEN];
00234 struct list_head next;
00235 #ifdef CONFIG_SMP
00236
00237 cpucache_t *cpudata[NR_CPUS];
00238 #endif
00239 #if STATS
00240 unsigned long num_active;
00241 unsigned long num_allocations;
00242 unsigned long high_mark;
00243 unsigned long grown;
00244 unsigned long reaped;
00245 unsigned long errors;
00246 #ifdef CONFIG_SMP
00247 atomic_t allochit;
00248 atomic_t allocmiss;
00249 atomic_t freehit;
00250 atomic_t freemiss;
00251 #endif
00252 #endif
00253 };
00254
00255
00256 #define CFLGS_OFF_SLAB 0x010000UL
00257 #define CFLGS_OPTIMIZE 0x020000UL
00258
00259
00260 #define DFLGS_GROWN 0x000001UL
00261
00262 #define OFF_SLAB(x) ((x)->flags & CFLGS_OFF_SLAB)
00263 #define OPTIMIZE(x) ((x)->flags & CFLGS_OPTIMIZE)
00264 #define GROWN(x) ((x)->dlags & DFLGS_GROWN)
00265
00266 #if STATS
00267 #define STATS_INC_ACTIVE(x) ((x)->num_active++)
00268 #define STATS_DEC_ACTIVE(x) ((x)->num_active--)
00269 #define STATS_INC_ALLOCED(x) ((x)->num_allocations++)
00270 #define STATS_INC_GROWN(x) ((x)->grown++)
00271 #define STATS_INC_REAPED(x) ((x)->reaped++)
00272 #define STATS_SET_HIGH(x) do { if ((x)->num_active > (x)->high_mark) \
00273 (x)->high_mark = (x)->num_active; \
00274 } while (0)
00275 #define STATS_INC_ERR(x) ((x)->errors++)
00276 #else
00277 #define STATS_INC_ACTIVE(x) do { } while (0)
00278 #define STATS_DEC_ACTIVE(x) do { } while (0)
00279 #define STATS_INC_ALLOCED(x) do { } while (0)
00280 #define STATS_INC_GROWN(x) do { } while (0)
00281 #define STATS_INC_REAPED(x) do { } while (0)
00282 #define STATS_SET_HIGH(x) do { } while (0)
00283 #define STATS_INC_ERR(x) do { } while (0)
00284 #endif
00285
00286 #if STATS && defined(CONFIG_SMP)
00287 #define STATS_INC_ALLOCHIT(x) atomic_inc(&(x)->allochit)
00288 #define STATS_INC_ALLOCMISS(x) atomic_inc(&(x)->allocmiss)
00289 #define STATS_INC_FREEHIT(x) atomic_inc(&(x)->freehit)
00290 #define STATS_INC_FREEMISS(x) atomic_inc(&(x)->freemiss)
00291 #else
00292 #define STATS_INC_ALLOCHIT(x) do { } while (0)
00293 #define STATS_INC_ALLOCMISS(x) do { } while (0)
00294 #define STATS_INC_FREEHIT(x) do { } while (0)
00295 #define STATS_INC_FREEMISS(x) do { } while (0)
00296 #endif
00297
00298 #if DEBUG
00299
00300
00301
00302 #define RED_MAGIC1 0x5A2CF071UL
00303 #define RED_MAGIC2 0x170FC2A5UL
00304
00305
00306 #define POISON_BYTE 0x5a
00307 #define POISON_END 0xa5
00308
00309 #endif
00310
00311
00312 #define MAX_OBJ_ORDER 5
00313
00314
00315
00316
00317 #define BREAK_GFP_ORDER_HI 2
00318 #define BREAK_GFP_ORDER_LO 1
00319 static int slab_break_gfp_order = BREAK_GFP_ORDER_LO;
00320
00321
00322
00323
00324 #define MAX_GFP_ORDER 5
00325
00326
00327
00328
00329
00330
00331 #define SET_PAGE_CACHE(pg,x) ((pg)->list.next = (struct list_head *)(x))
00332 #define GET_PAGE_CACHE(pg) ((kmem_cache_t *)(pg)->list.next)
00333 #define SET_PAGE_SLAB(pg,x) ((pg)->list.prev = (struct list_head *)(x))
00334 #define GET_PAGE_SLAB(pg) ((slab_t *)(pg)->list.prev)
00335
00336
00337 typedef struct cache_sizes {
00338 size_t cs_size;
00339 kmem_cache_t *cs_cachep;
00340 kmem_cache_t *cs_dmacachep;
00341 } cache_sizes_t;
00342
00343 static cache_sizes_t cache_sizes[] = {
00344 #if PAGE_SIZE == 4096
00345 { 32, NULL, NULL},
00346 #endif
00347 { 64, NULL, NULL},
00348 { 128, NULL, NULL},
00349 { 256, NULL, NULL},
00350 { 512, NULL, NULL},
00351 { 1024, NULL, NULL},
00352 { 2048, NULL, NULL},
00353 { 4096, NULL, NULL},
00354 { 8192, NULL, NULL},
00355 { 16384, NULL, NULL},
00356 { 32768, NULL, NULL},
00357 { 65536, NULL, NULL},
00358 {131072, NULL, NULL},
00359 { 0, NULL, NULL}
00360 };
00361
00362
00363 static kmem_cache_t cache_cache = {
00364 slabs_full: LIST_HEAD_INIT(cache_cache.slabs_full),
00365 slabs_partial: LIST_HEAD_INIT(cache_cache.slabs_partial),
00366 slabs_free: LIST_HEAD_INIT(cache_cache.slabs_free),
00367 objsize: sizeof(kmem_cache_t),
00368 flags: SLAB_NO_REAP,
00369 spinlock: SPIN_LOCK_UNLOCKED,
00370 colour_off: L1_CACHE_BYTES,
00371 name: "kmem_cache",
00372 };
00373
00374
00375 static struct semaphore cache_chain_sem;
00376
00377
00378 static kmem_cache_t *clock_searchp = &cache_cache;
00379
00380 #define cache_chain (cache_cache.next)
00381
00382 #ifdef CONFIG_SMP
00383
00384
00385
00386
00387 static int g_cpucache_up;
00388
00389 static void enable_cpucache (kmem_cache_t *cachep);
00390 static void enable_all_cpucaches (void);
00391 #endif
00392
00393
00394 static void kmem_cache_estimate (unsigned long gfporder, size_t size,
00395 int flags, size_t *left_over, unsigned int *num)
00396 {
00397 int i;
00398 size_t wastage = PAGE_SIZE<<gfporder;
00399 size_t extra = 0;
00400 size_t base = 0;
00401
00402 if (!(flags & CFLGS_OFF_SLAB)) {
00403 base = sizeof(slab_t);
00404 extra = sizeof(kmem_bufctl_t);
00405 }
00406 i = 0;
00407 while (i*size + L1_CACHE_ALIGN(base+i*extra) <= wastage)
00408 i++;
00409 if (i > 0)
00410 i--;
00411
00412 if (i > SLAB_LIMIT)
00413 i = SLAB_LIMIT;
00414
00415 *num = i;
00416 wastage -= i*size;
00417 wastage -= L1_CACHE_ALIGN(base+i*extra);
00418 *left_over = wastage;
00419 }
00420
00421
00422 void __init kmem_cache_init(void)
00423 {
00424 size_t left_over;
00425
00426 init_MUTEX(&cache_chain_sem);
00427 INIT_LIST_HEAD(&cache_chain);
00428
00429 kmem_cache_estimate(0, cache_cache.objsize, 0,
00430 &left_over, &cache_cache.num);
00431 if (!cache_cache.num)
00432 BUG();
00433
00434 cache_cache.colour = left_over/cache_cache.colour_off;
00435 cache_cache.colour_next = 0;
00436 }
00437
00438
00439
00440
00441
00442 void __init kmem_cache_sizes_init(void)
00443 {
00444 cache_sizes_t *sizes = cache_sizes;
00445 char name[20];
00446
00447
00448
00449
00450 if (num_physpages > (32 << 20) >> PAGE_SHIFT)
00451 slab_break_gfp_order = BREAK_GFP_ORDER_HI;
00452 do {
00453
00454
00455
00456
00457
00458 sprintf(name,"size-%Zd",sizes->cs_size);
00459 if (!(sizes->cs_cachep =
00460 kmem_cache_create(name, sizes->cs_size,
00461 0, SLAB_HWCACHE_ALIGN, NULL, NULL))) {
00462 BUG();
00463 }
00464
00465
00466 if (!(OFF_SLAB(sizes->cs_cachep))) {
00467 offslab_limit = sizes->cs_size-sizeof(slab_t);
00468 offslab_limit /= 2;
00469 }
00470 sprintf(name, "size-%Zd(DMA)",sizes->cs_size);
00471 sizes->cs_dmacachep = kmem_cache_create(name, sizes->cs_size, 0,
00472 SLAB_CACHE_DMA|SLAB_HWCACHE_ALIGN, NULL, NULL);
00473 if (!sizes->cs_dmacachep)
00474 BUG();
00475 sizes++;
00476 } while (sizes->cs_size);
00477 }
00478
00479 int __init kmem_cpucache_init(void)
00480 {
00481 #ifdef CONFIG_SMP
00482 g_cpucache_up = 1;
00483 enable_all_cpucaches();
00484 #endif
00485 return 0;
00486 }
00487
00488 __initcall(kmem_cpucache_init);
00489
00490
00491
00492 static inline void * kmem_getpages (kmem_cache_t *cachep, unsigned long flags)
00493 {
00494 void *addr;
00495
00496
00497
00498
00499
00500
00501 flags |= cachep->gfpflags;
00502 addr = (void*) __get_free_pages(flags, cachep->gfporder);
00503
00504
00505
00506
00507
00508
00509 return addr;
00510 }
00511
00512
00513 static inline void kmem_freepages (kmem_cache_t *cachep, void *addr)
00514 {
00515 unsigned long i = (1<<cachep->gfporder);
00516 struct page *page = virt_to_page(addr);
00517
00518
00519
00520
00521
00522
00523 while (i--) {
00524 PageClearSlab(page);
00525 page++;
00526 }
00527 free_pages((unsigned long)addr, cachep->gfporder);
00528 }
00529
00530 #if DEBUG
00531 static inline void kmem_poison_obj (kmem_cache_t *cachep, void *addr)
00532 {
00533 int size = cachep->objsize;
00534 if (cachep->flags & SLAB_RED_ZONE) {
00535 addr += BYTES_PER_WORD;
00536 size -= 2*BYTES_PER_WORD;
00537 }
00538 memset(addr, POISON_BYTE, size);
00539 *(unsigned char *)(addr+size-1) = POISON_END;
00540 }
00541
00542 static inline int kmem_check_poison_obj (kmem_cache_t *cachep, void *addr)
00543 {
00544 int size = cachep->objsize;
00545 void *end;
00546 if (cachep->flags & SLAB_RED_ZONE) {
00547 addr += BYTES_PER_WORD;
00548 size -= 2*BYTES_PER_WORD;
00549 }
00550 #ifdef __x86_64__
00551 #define memchr kernel_memchr
00552 void *kernel_memchr(const void *s, int c, size_t n);
00553 #endif
00554 end = memchr(addr, POISON_END, size);
00555 if (end != (addr+size-1))
00556 return 1;
00557 return 0;
00558 }
00559 #endif
00560
00561
00562
00563
00564
00565 static void kmem_slab_destroy (kmem_cache_t *cachep, slab_t *slabp)
00566 {
00567 if (cachep->dtor
00568 #if DEBUG
00569 || cachep->flags & (SLAB_POISON | SLAB_RED_ZONE)
00570 #endif
00571 ) {
00572 int i;
00573 for (i = 0; i < cachep->num; i++) {
00574 void* objp = slabp->s_mem+cachep->objsize*i;
00575 #if DEBUG
00576 if (cachep->flags & SLAB_RED_ZONE) {
00577 if (*((unsigned long*)(objp)) != RED_MAGIC1)
00578 BUG();
00579 if (*((unsigned long*)(objp + cachep->objsize
00580 -BYTES_PER_WORD)) != RED_MAGIC1)
00581 BUG();
00582 objp += BYTES_PER_WORD;
00583 }
00584 #endif
00585 if (cachep->dtor)
00586 (cachep->dtor)(objp, cachep, 0);
00587 #if DEBUG
00588 if (cachep->flags & SLAB_RED_ZONE) {
00589 objp -= BYTES_PER_WORD;
00590 }
00591 if ((cachep->flags & SLAB_POISON) &&
00592 kmem_check_poison_obj(cachep, objp))
00593 BUG();
00594 #endif
00595 }
00596 }
00597
00598 kmem_freepages(cachep, slabp->s_mem-slabp->colouroff);
00599 if (OFF_SLAB(cachep))
00600 kmem_cache_free(cachep->slabp_cache, slabp);
00601 }
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631 kmem_cache_t *
00632 kmem_cache_create (const char *name, size_t size, size_t offset,
00633 unsigned long flags, void (*ctor)(void*, kmem_cache_t *, unsigned long),
00634 void (*dtor)(void*, kmem_cache_t *, unsigned long))
00635 {
00636 const char *func_nm = KERN_ERR "kmem_create: ";
00637 size_t left_over, align, slab_size;
00638 kmem_cache_t *cachep = NULL;
00639
00640
00641
00642
00643 if ((!name) ||
00644 ((strlen(name) >= CACHE_NAMELEN - 1)) ||
00645 (size < BYTES_PER_WORD) ||
00646 (size > (1<<MAX_OBJ_ORDER)*PAGE_SIZE) ||
00647 (dtor && !ctor) ||
00648 (offset < 0 || offset > size))
00649 BUG();
00650
00651 #if DEBUG
00652 if ((flags & SLAB_DEBUG_INITIAL) && !ctor) {
00653
00654 printk("%sNo con, but init state check requested - %s\n", func_nm, name);
00655 flags &= ~SLAB_DEBUG_INITIAL;
00656 }
00657
00658 if ((flags & SLAB_POISON) && ctor) {
00659
00660 printk("%sPoisoning requested, but con given - %s\n", func_nm, name);
00661 flags &= ~SLAB_POISON;
00662 }
00663 #if FORCED_DEBUG
00664 if ((size < (PAGE_SIZE>>3)) && !(flags & SLAB_MUST_HWCACHE_ALIGN))
00665
00666
00667
00668
00669 flags |= SLAB_RED_ZONE;
00670 if (!ctor)
00671 flags |= SLAB_POISON;
00672 #endif
00673 #endif
00674
00675
00676
00677
00678
00679 if (flags & ~CREATE_MASK)
00680 BUG();
00681
00682
00683 cachep = (kmem_cache_t *) kmem_cache_alloc(&cache_cache, SLAB_KERNEL);
00684 if (!cachep)
00685 goto opps;
00686 memset(cachep, 0, sizeof(kmem_cache_t));
00687
00688
00689
00690
00691
00692 if (size & (BYTES_PER_WORD-1)) {
00693 size += (BYTES_PER_WORD-1);
00694 size &= ~(BYTES_PER_WORD-1);
00695 printk("%sForcing size word alignment - %s\n", func_nm, name);
00696 }
00697
00698 #if DEBUG
00699 if (flags & SLAB_RED_ZONE) {
00700
00701
00702
00703
00704 flags &= ~SLAB_HWCACHE_ALIGN;
00705 size += 2*BYTES_PER_WORD;
00706 }
00707 #endif
00708 align = BYTES_PER_WORD;
00709 if (flags & SLAB_HWCACHE_ALIGN)
00710 align = L1_CACHE_BYTES;
00711
00712
00713 if (size >= (PAGE_SIZE>>3))
00714
00715
00716
00717
00718 flags |= CFLGS_OFF_SLAB;
00719
00720 if (flags & SLAB_HWCACHE_ALIGN) {
00721
00722
00723
00724 while (size < align/2)
00725 align /= 2;
00726 size = (size+align-1)&(~(align-1));
00727 }
00728
00729
00730
00731
00732
00733
00734 do {
00735 unsigned int break_flag = 0;
00736 cal_wastage:
00737 kmem_cache_estimate(cachep->gfporder, size, flags,
00738 &left_over, &cachep->num);
00739 if (break_flag)
00740 break;
00741 if (cachep->gfporder >= MAX_GFP_ORDER)
00742 break;
00743 if (!cachep->num)
00744 goto next;
00745 if (flags & CFLGS_OFF_SLAB && cachep->num > offslab_limit) {
00746
00747 cachep->gfporder--;
00748 break_flag++;
00749 goto cal_wastage;
00750 }
00751
00752
00753
00754
00755
00756 if (cachep->gfporder >= slab_break_gfp_order)
00757 break;
00758
00759 if ((left_over*8) <= (PAGE_SIZE<<cachep->gfporder))
00760 break;
00761 next:
00762 cachep->gfporder++;
00763 } while (1);
00764
00765 if (!cachep->num) {
00766 printk("kmem_cache_create: couldn't create cache %s.\n", name);
00767 kmem_cache_free(&cache_cache, cachep);
00768 cachep = NULL;
00769 goto opps;
00770 }
00771 slab_size = L1_CACHE_ALIGN(cachep->num*sizeof(kmem_bufctl_t)+sizeof(slab_t));
00772
00773
00774
00775
00776
00777 if (flags & CFLGS_OFF_SLAB && left_over >= slab_size) {
00778 flags &= ~CFLGS_OFF_SLAB;
00779 left_over -= slab_size;
00780 }
00781
00782
00783 offset += (align-1);
00784 offset &= ~(align-1);
00785 if (!offset)
00786 offset = L1_CACHE_BYTES;
00787 cachep->colour_off = offset;
00788 cachep->colour = left_over/offset;
00789
00790
00791 if (!cachep->gfporder && !(flags & CFLGS_OFF_SLAB))
00792 flags |= CFLGS_OPTIMIZE;
00793
00794 cachep->flags = flags;
00795 cachep->gfpflags = 0;
00796 if (flags & SLAB_CACHE_DMA)
00797 cachep->gfpflags |= GFP_DMA;
00798 spin_lock_init(&cachep->spinlock);
00799 cachep->objsize = size;
00800 INIT_LIST_HEAD(&cachep->slabs_full);
00801 INIT_LIST_HEAD(&cachep->slabs_partial);
00802 INIT_LIST_HEAD(&cachep->slabs_free);
00803
00804 if (flags & CFLGS_OFF_SLAB)
00805 cachep->slabp_cache = kmem_find_general_cachep(slab_size,0);
00806 cachep->ctor = ctor;
00807 cachep->dtor = dtor;
00808
00809 strcpy(cachep->name, name);
00810
00811 #ifdef CONFIG_SMP
00812 if (g_cpucache_up)
00813 enable_cpucache(cachep);
00814 #endif
00815
00816 down(&cache_chain_sem);
00817 {
00818 struct list_head *p;
00819
00820 list_for_each(p, &cache_chain) {
00821 kmem_cache_t *pc = list_entry(p, kmem_cache_t, next);
00822
00823
00824 if (!strcmp(pc->name, name))
00825 BUG();
00826 }
00827 }
00828
00829
00830
00831
00832 list_add(&cachep->next, &cache_chain);
00833 up(&cache_chain_sem);
00834 opps:
00835 return cachep;
00836 }
00837
00838
00839 #if DEBUG
00840
00841
00842
00843
00844 static int is_chained_kmem_cache(kmem_cache_t * cachep)
00845 {
00846 struct list_head *p;
00847 int ret = 0;
00848
00849
00850 down(&cache_chain_sem);
00851 list_for_each(p, &cache_chain) {
00852 if (p == &cachep->next) {
00853 ret = 1;
00854 break;
00855 }
00856 }
00857 up(&cache_chain_sem);
00858
00859 return ret;
00860 }
00861 #else
00862 #define is_chained_kmem_cache(x) 1
00863 #endif
00864
00865 #ifdef CONFIG_SMP
00866
00867
00868
00869 static void smp_call_function_all_cpus(void (*func) (void *arg), void *arg)
00870 {
00871 local_irq_disable();
00872 func(arg);
00873 local_irq_enable();
00874
00875 if (smp_call_function(func, arg, 1, 1))
00876 BUG();
00877 }
00878 typedef struct ccupdate_struct_s
00879 {
00880 kmem_cache_t *cachep;
00881 cpucache_t *new[NR_CPUS];
00882 } ccupdate_struct_t;
00883
00884 static void do_ccupdate_local(void *info)
00885 {
00886 ccupdate_struct_t *new = (ccupdate_struct_t *)info;
00887 cpucache_t *old = cc_data(new->cachep);
00888
00889 cc_data(new->cachep) = new->new[smp_processor_id()];
00890 new->new[smp_processor_id()] = old;
00891 }
00892
00893 static void free_block (kmem_cache_t* cachep, void** objpp, int len);
00894
00895 static void drain_cpu_caches(kmem_cache_t *cachep)
00896 {
00897 ccupdate_struct_t new;
00898 int i;
00899
00900 memset(&new.new,0,sizeof(new.new));
00901
00902 new.cachep = cachep;
00903
00904 down(&cache_chain_sem);
00905 smp_call_function_all_cpus(do_ccupdate_local, (void *)&new);
00906
00907 for (i = 0; i < smp_num_cpus; i++) {
00908 cpucache_t* ccold = new.new[cpu_logical_map(i)];
00909 if (!ccold || (ccold->avail == 0))
00910 continue;
00911 local_irq_disable();
00912 free_block(cachep, cc_entry(ccold), ccold->avail);
00913 local_irq_enable();
00914 ccold->avail = 0;
00915 }
00916 smp_call_function_all_cpus(do_ccupdate_local, (void *)&new);
00917 up(&cache_chain_sem);
00918 }
00919
00920 #else
00921 #define drain_cpu_caches(cachep) do { } while (0)
00922 #endif
00923
00924 static int __kmem_cache_shrink(kmem_cache_t *cachep)
00925 {
00926 slab_t *slabp;
00927 int ret;
00928
00929 drain_cpu_caches(cachep);
00930
00931 spin_lock_irq(&cachep->spinlock);
00932
00933
00934 while (!cachep->growing) {
00935 struct list_head *p;
00936
00937 p = cachep->slabs_free.prev;
00938 if (p == &cachep->slabs_free)
00939 break;
00940
00941 slabp = list_entry(cachep->slabs_free.prev, slab_t, list);
00942 #if DEBUG
00943 if (slabp->inuse)
00944 BUG();
00945 #endif
00946 list_del(&slabp->list);
00947
00948 spin_unlock_irq(&cachep->spinlock);
00949 kmem_slab_destroy(cachep, slabp);
00950 spin_lock_irq(&cachep->spinlock);
00951 }
00952 ret = !list_empty(&cachep->slabs_full) || !list_empty(&cachep->slabs_partial);
00953 spin_unlock_irq(&cachep->spinlock);
00954 return ret;
00955 }
00956
00957
00958
00959
00960
00961
00962
00963
00964 int kmem_cache_shrink(kmem_cache_t *cachep)
00965 {
00966 if (!cachep || in_interrupt() || !is_chained_kmem_cache(cachep))
00967 BUG();
00968
00969 return __kmem_cache_shrink(cachep);
00970 }
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987 int kmem_cache_destroy (kmem_cache_t * cachep)
00988 {
00989 if (!cachep || in_interrupt() || cachep->growing)
00990 BUG();
00991
00992
00993 down(&cache_chain_sem);
00994
00995 if (clock_searchp == cachep)
00996 clock_searchp = list_entry(cachep->next.next,
00997 kmem_cache_t, next);
00998 list_del(&cachep->next);
00999 up(&cache_chain_sem);
01000
01001 if (__kmem_cache_shrink(cachep)) {
01002 printk(KERN_ERR "kmem_cache_destroy: Can't free all objects %p\n",
01003 cachep);
01004 down(&cache_chain_sem);
01005 list_add(&cachep->next,&cache_chain);
01006 up(&cache_chain_sem);
01007 return 1;
01008 }
01009 #ifdef CONFIG_SMP
01010 {
01011 int i;
01012 for (i = 0; i < NR_CPUS; i++)
01013 kfree(cachep->cpudata[i]);
01014 }
01015 #endif
01016 kmem_cache_free(&cache_cache, cachep);
01017
01018 return 0;
01019 }
01020
01021
01022 static inline slab_t * kmem_cache_slabmgmt (kmem_cache_t *cachep,
01023 void *objp, int colour_off, int local_flags)
01024 {
01025 slab_t *slabp;
01026
01027 if (OFF_SLAB(cachep)) {
01028
01029 slabp = kmem_cache_alloc(cachep->slabp_cache, local_flags);
01030 if (!slabp)
01031 return NULL;
01032 } else {
01033
01034
01035
01036
01037 slabp = objp+colour_off;
01038 colour_off += L1_CACHE_ALIGN(cachep->num *
01039 sizeof(kmem_bufctl_t) + sizeof(slab_t));
01040 }
01041 slabp->inuse = 0;
01042 slabp->colouroff = colour_off;
01043 slabp->s_mem = objp+colour_off;
01044
01045 return slabp;
01046 }
01047
01048 static inline void kmem_cache_init_objs (kmem_cache_t * cachep,
01049 slab_t * slabp, unsigned long ctor_flags)
01050 {
01051 int i;
01052
01053 for (i = 0; i < cachep->num; i++) {
01054 void* objp = slabp->s_mem+cachep->objsize*i;
01055 #if DEBUG
01056 if (cachep->flags & SLAB_RED_ZONE) {
01057 *((unsigned long*)(objp)) = RED_MAGIC1;
01058 *((unsigned long*)(objp + cachep->objsize -
01059 BYTES_PER_WORD)) = RED_MAGIC1;
01060 objp += BYTES_PER_WORD;
01061 }
01062 #endif
01063
01064
01065
01066
01067
01068
01069 if (cachep->ctor)
01070 cachep->ctor(objp, cachep, ctor_flags);
01071 #if DEBUG
01072 if (cachep->flags & SLAB_RED_ZONE)
01073 objp -= BYTES_PER_WORD;
01074 if (cachep->flags & SLAB_POISON)
01075
01076 kmem_poison_obj(cachep, objp);
01077 if (cachep->flags & SLAB_RED_ZONE) {
01078 if (*((unsigned long*)(objp)) != RED_MAGIC1)
01079 BUG();
01080 if (*((unsigned long*)(objp + cachep->objsize -
01081 BYTES_PER_WORD)) != RED_MAGIC1)
01082 BUG();
01083 }
01084 #endif
01085 slab_bufctl(slabp)[i] = i+1;
01086 }
01087 slab_bufctl(slabp)[i-1] = BUFCTL_END;
01088 slabp->free = 0;
01089 }
01090
01091
01092
01093
01094
01095 static int kmem_cache_grow (kmem_cache_t * cachep, int flags)
01096 {
01097 slab_t *slabp;
01098 struct page *page;
01099 void *objp;
01100 size_t offset;
01101 unsigned int i, local_flags;
01102 unsigned long ctor_flags;
01103 unsigned long save_flags;
01104
01105
01106
01107
01108 if (flags & ~(SLAB_DMA|SLAB_LEVEL_MASK|SLAB_NO_GROW))
01109 BUG();
01110 if (flags & SLAB_NO_GROW)
01111 return 0;
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122 ctor_flags = SLAB_CTOR_CONSTRUCTOR;
01123 local_flags = (flags & SLAB_LEVEL_MASK);
01124 if (local_flags == SLAB_ATOMIC)
01125
01126
01127
01128
01129 ctor_flags |= SLAB_CTOR_ATOMIC;
01130
01131
01132 spin_lock_irqsave(&cachep->spinlock, save_flags);
01133
01134
01135 offset = cachep->colour_next;
01136 cachep->colour_next++;
01137 if (cachep->colour_next >= cachep->colour)
01138 cachep->colour_next = 0;
01139 offset *= cachep->colour_off;
01140 cachep->dflags |= DFLGS_GROWN;
01141
01142 cachep->growing++;
01143 spin_unlock_irqrestore(&cachep->spinlock, save_flags);
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155 if (!(objp = kmem_getpages(cachep, flags)))
01156 goto failed;
01157
01158
01159 if (!(slabp = kmem_cache_slabmgmt(cachep, objp, offset, local_flags)))
01160 goto opps1;
01161
01162
01163 i = 1 << cachep->gfporder;
01164 page = virt_to_page(objp);
01165 do {
01166 SET_PAGE_CACHE(page, cachep);
01167 SET_PAGE_SLAB(page, slabp);
01168 PageSetSlab(page);
01169 page++;
01170 } while (--i);
01171
01172 kmem_cache_init_objs(cachep, slabp, ctor_flags);
01173
01174 spin_lock_irqsave(&cachep->spinlock, save_flags);
01175 cachep->growing--;
01176
01177
01178 list_add_tail(&slabp->list, &cachep->slabs_free);
01179 STATS_INC_GROWN(cachep);
01180 cachep->failures = 0;
01181
01182 spin_unlock_irqrestore(&cachep->spinlock, save_flags);
01183 return 1;
01184 opps1:
01185 kmem_freepages(cachep, objp);
01186 failed:
01187 spin_lock_irqsave(&cachep->spinlock, save_flags);
01188 cachep->growing--;
01189 spin_unlock_irqrestore(&cachep->spinlock, save_flags);
01190 return 0;
01191 }
01192
01193
01194
01195
01196
01197
01198
01199
01200 #if DEBUG
01201 static int kmem_extra_free_checks (kmem_cache_t * cachep,
01202 slab_t *slabp, void * objp)
01203 {
01204 int i;
01205 unsigned int objnr = (objp-slabp->s_mem)/cachep->objsize;
01206
01207 if (objnr >= cachep->num)
01208 BUG();
01209 if (objp != slabp->s_mem + objnr*cachep->objsize)
01210 BUG();
01211
01212
01213 for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) {
01214 if (i == objnr)
01215 BUG();
01216 }
01217 return 0;
01218 }
01219 #endif
01220
01221 static inline void kmem_cache_alloc_head(kmem_cache_t *cachep, int flags)
01222 {
01223 if (flags & SLAB_DMA) {
01224 if (!(cachep->gfpflags & GFP_DMA))
01225 BUG();
01226 } else {
01227 if (cachep->gfpflags & GFP_DMA)
01228 BUG();
01229 }
01230 }
01231
01232 static inline void * kmem_cache_alloc_one_tail (kmem_cache_t *cachep,
01233 slab_t *slabp)
01234 {
01235 void *objp;
01236
01237 STATS_INC_ALLOCED(cachep);
01238 STATS_INC_ACTIVE(cachep);
01239 STATS_SET_HIGH(cachep);
01240
01241
01242 slabp->inuse++;
01243 objp = slabp->s_mem + slabp->free*cachep->objsize;
01244 slabp->free=slab_bufctl(slabp)[slabp->free];
01245
01246 if (unlikely(slabp->free == BUFCTL_END)) {
01247 list_del(&slabp->list);
01248 list_add(&slabp->list, &cachep->slabs_full);
01249 }
01250 #if DEBUG
01251 if (cachep->flags & SLAB_POISON)
01252 if (kmem_check_poison_obj(cachep, objp))
01253 BUG();
01254 if (cachep->flags & SLAB_RED_ZONE) {
01255
01256 if (xchg((unsigned long *)objp, RED_MAGIC2) !=
01257 RED_MAGIC1)
01258 BUG();
01259 if (xchg((unsigned long *)(objp+cachep->objsize -
01260 BYTES_PER_WORD), RED_MAGIC2) != RED_MAGIC1)
01261 BUG();
01262 objp += BYTES_PER_WORD;
01263 }
01264 #endif
01265 return objp;
01266 }
01267
01268
01269
01270
01271
01272
01273 #define kmem_cache_alloc_one(cachep) \
01274 ({ \
01275 struct list_head * slabs_partial, * entry; \
01276 slab_t *slabp; \
01277 \
01278 slabs_partial = &(cachep)->slabs_partial; \
01279 entry = slabs_partial->next; \
01280 if (unlikely(entry == slabs_partial)) { \
01281 struct list_head * slabs_free; \
01282 slabs_free = &(cachep)->slabs_free; \
01283 entry = slabs_free->next; \
01284 if (unlikely(entry == slabs_free)) \
01285 goto alloc_new_slab; \
01286 list_del(entry); \
01287 list_add(entry, slabs_partial); \
01288 } \
01289 \
01290 slabp = list_entry(entry, slab_t, list); \
01291 kmem_cache_alloc_one_tail(cachep, slabp); \
01292 })
01293
01294 #ifdef CONFIG_SMP
01295 void* kmem_cache_alloc_batch(kmem_cache_t* cachep, cpucache_t* cc, int flags)
01296 {
01297 int batchcount = cachep->batchcount;
01298
01299 spin_lock(&cachep->spinlock);
01300 while (batchcount--) {
01301 struct list_head * slabs_partial, * entry;
01302 slab_t *slabp;
01303
01304 slabs_partial = &(cachep)->slabs_partial;
01305 entry = slabs_partial->next;
01306 if (unlikely(entry == slabs_partial)) {
01307 struct list_head * slabs_free;
01308 slabs_free = &(cachep)->slabs_free;
01309 entry = slabs_free->next;
01310 if (unlikely(entry == slabs_free))
01311 break;
01312 list_del(entry);
01313 list_add(entry, slabs_partial);
01314 }
01315
01316 slabp = list_entry(entry, slab_t, list);
01317 cc_entry(cc)[cc->avail++] =
01318 kmem_cache_alloc_one_tail(cachep, slabp);
01319 }
01320 spin_unlock(&cachep->spinlock);
01321
01322 if (cc->avail)
01323 return cc_entry(cc)[--cc->avail];
01324 return NULL;
01325 }
01326 #endif
01327
01328 static inline void * __kmem_cache_alloc (kmem_cache_t *cachep, int flags)
01329 {
01330 unsigned long save_flags;
01331 void* objp;
01332
01333 kmem_cache_alloc_head(cachep, flags);
01334 try_again:
01335 local_irq_save(save_flags);
01336 #ifdef CONFIG_SMP
01337 {
01338 cpucache_t *cc = cc_data(cachep);
01339
01340 if (cc) {
01341 if (cc->avail) {
01342 STATS_INC_ALLOCHIT(cachep);
01343 objp = cc_entry(cc)[--cc->avail];
01344 } else {
01345 STATS_INC_ALLOCMISS(cachep);
01346 objp = kmem_cache_alloc_batch(cachep,cc,flags);
01347 if (!objp)
01348 goto alloc_new_slab_nolock;
01349 }
01350 } else {
01351 spin_lock(&cachep->spinlock);
01352 objp = kmem_cache_alloc_one(cachep);
01353 spin_unlock(&cachep->spinlock);
01354 }
01355 }
01356 #else
01357 objp = kmem_cache_alloc_one(cachep);
01358 #endif
01359 local_irq_restore(save_flags);
01360 return objp;
01361 alloc_new_slab:
01362 #ifdef CONFIG_SMP
01363 spin_unlock(&cachep->spinlock);
01364 alloc_new_slab_nolock:
01365 #endif
01366 local_irq_restore(save_flags);
01367 if (kmem_cache_grow(cachep, flags))
01368
01369
01370
01371 goto try_again;
01372 return NULL;
01373 }
01374
01375
01376
01377
01378
01379
01380
01381 #if DEBUG
01382 # define CHECK_NR(pg) \
01383 do { \
01384 if (!VALID_PAGE(pg)) { \
01385 printk(KERN_ERR "kfree: out of range ptr %lxh.\n", \
01386 (unsigned long)objp); \
01387 BUG(); \
01388 } \
01389 } while (0)
01390 # define CHECK_PAGE(page) \
01391 do { \
01392 CHECK_NR(page); \
01393 if (!PageSlab(page)) { \
01394 printk(KERN_ERR "kfree: bad ptr %lxh.\n", \
01395 (unsigned long)objp); \
01396 BUG(); \
01397 } \
01398 } while (0)
01399
01400 #else
01401 # define CHECK_PAGE(pg) do { } while (0)
01402 #endif
01403
01404 static inline void kmem_cache_free_one(kmem_cache_t *cachep, void *objp)
01405 {
01406 slab_t* slabp;
01407
01408 CHECK_PAGE(virt_to_page(objp));
01409
01410
01411
01412
01413
01414
01415 slabp = GET_PAGE_SLAB(virt_to_page(objp));
01416
01417 #if DEBUG
01418 if (cachep->flags & SLAB_DEBUG_INITIAL)
01419
01420
01421
01422
01423 cachep->ctor(objp, cachep, SLAB_CTOR_CONSTRUCTOR|SLAB_CTOR_VERIFY);
01424
01425 if (cachep->flags & SLAB_RED_ZONE) {
01426 objp -= BYTES_PER_WORD;
01427 if (xchg((unsigned long *)objp, RED_MAGIC1) != RED_MAGIC2)
01428
01429 BUG();
01430 if (xchg((unsigned long *)(objp+cachep->objsize -
01431 BYTES_PER_WORD), RED_MAGIC1) != RED_MAGIC2)
01432
01433 BUG();
01434 }
01435 if (cachep->flags & SLAB_POISON)
01436 kmem_poison_obj(cachep, objp);
01437 if (kmem_extra_free_checks(cachep, slabp, objp))
01438 return;
01439 #endif
01440 {
01441 unsigned int objnr = (objp-slabp->s_mem)/cachep->objsize;
01442
01443 slab_bufctl(slabp)[objnr] = slabp->free;
01444 slabp->free = objnr;
01445 }
01446 STATS_DEC_ACTIVE(cachep);
01447
01448
01449 {
01450 int inuse = slabp->inuse;
01451 if (unlikely(!--slabp->inuse)) {
01452
01453 list_del(&slabp->list);
01454 list_add(&slabp->list, &cachep->slabs_free);
01455 } else if (unlikely(inuse == cachep->num)) {
01456
01457 list_del(&slabp->list);
01458 list_add(&slabp->list, &cachep->slabs_partial);
01459 }
01460 }
01461 }
01462
01463 #ifdef CONFIG_SMP
01464 static inline void __free_block (kmem_cache_t* cachep,
01465 void** objpp, int len)
01466 {
01467 for ( ; len > 0; len--, objpp++)
01468 kmem_cache_free_one(cachep, *objpp);
01469 }
01470
01471 static void free_block (kmem_cache_t* cachep, void** objpp, int len)
01472 {
01473 spin_lock(&cachep->spinlock);
01474 __free_block(cachep, objpp, len);
01475 spin_unlock(&cachep->spinlock);
01476 }
01477 #endif
01478
01479
01480
01481
01482
01483 static inline void __kmem_cache_free (kmem_cache_t *cachep, void* objp)
01484 {
01485 #ifdef CONFIG_SMP
01486 cpucache_t *cc = cc_data(cachep);
01487
01488 CHECK_PAGE(virt_to_page(objp));
01489 if (cc) {
01490 int batchcount;
01491 if (cc->avail < cc->limit) {
01492 STATS_INC_FREEHIT(cachep);
01493 cc_entry(cc)[cc->avail++] = objp;
01494 return;
01495 }
01496 STATS_INC_FREEMISS(cachep);
01497 batchcount = cachep->batchcount;
01498 cc->avail -= batchcount;
01499 free_block(cachep,
01500 &cc_entry(cc)[cc->avail],batchcount);
01501 cc_entry(cc)[cc->avail++] = objp;
01502 return;
01503 } else {
01504 free_block(cachep, &objp, 1);
01505 }
01506 #else
01507 kmem_cache_free_one(cachep, objp);
01508 #endif
01509 }
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519 void * kmem_cache_alloc (kmem_cache_t *cachep, int flags)
01520 {
01521 return __kmem_cache_alloc(cachep, flags);
01522 }
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545 void * kmalloc (size_t size, int flags)
01546 {
01547 cache_sizes_t *csizep = cache_sizes;
01548
01549 for (; csizep->cs_size; csizep++) {
01550 if (size > csizep->cs_size)
01551 continue;
01552 return __kmem_cache_alloc(flags & GFP_DMA ?
01553 csizep->cs_dmacachep : csizep->cs_cachep, flags);
01554 }
01555 return NULL;
01556 }
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566 void kmem_cache_free (kmem_cache_t *cachep, void *objp)
01567 {
01568 unsigned long flags;
01569 #if DEBUG
01570 CHECK_PAGE(virt_to_page(objp));
01571 if (cachep != GET_PAGE_CACHE(virt_to_page(objp)))
01572 BUG();
01573 #endif
01574
01575 local_irq_save(flags);
01576 __kmem_cache_free(cachep, objp);
01577 local_irq_restore(flags);
01578 }
01579
01580
01581
01582
01583
01584
01585
01586
01587 void kfree (const void *objp)
01588 {
01589 kmem_cache_t *c;
01590 unsigned long flags;
01591
01592 if (!objp)
01593 return;
01594 local_irq_save(flags);
01595 CHECK_PAGE(virt_to_page(objp));
01596 c = GET_PAGE_CACHE(virt_to_page(objp));
01597 __kmem_cache_free(c, (void*)objp);
01598 local_irq_restore(flags);
01599 }
01600
01601 kmem_cache_t * kmem_find_general_cachep (size_t size, int gfpflags)
01602 {
01603 cache_sizes_t *csizep = cache_sizes;
01604
01605
01606
01607
01608
01609 for ( ; csizep->cs_size; csizep++) {
01610 if (size > csizep->cs_size)
01611 continue;
01612 break;
01613 }
01614 return (gfpflags & GFP_DMA) ? csizep->cs_dmacachep : csizep->cs_cachep;
01615 }
01616
01617 #ifdef CONFIG_SMP
01618
01619
01620 static int kmem_tune_cpucache (kmem_cache_t* cachep, int limit, int batchcount)
01621 {
01622 ccupdate_struct_t new;
01623 int i;
01624
01625
01626
01627
01628 if (limit < 0)
01629 return -EINVAL;
01630 if (batchcount < 0)
01631 return -EINVAL;
01632 if (batchcount > limit)
01633 return -EINVAL;
01634 if (limit != 0 && !batchcount)
01635 return -EINVAL;
01636
01637 memset(&new.new,0,sizeof(new.new));
01638 if (limit) {
01639 for (i = 0; i< smp_num_cpus; i++) {
01640 cpucache_t* ccnew;
01641
01642 ccnew = kmalloc(sizeof(void*)*limit+
01643 sizeof(cpucache_t), GFP_KERNEL);
01644 if (!ccnew)
01645 goto oom;
01646 ccnew->limit = limit;
01647 ccnew->avail = 0;
01648 new.new[cpu_logical_map(i)] = ccnew;
01649 }
01650 }
01651 new.cachep = cachep;
01652 spin_lock_irq(&cachep->spinlock);
01653 cachep->batchcount = batchcount;
01654 spin_unlock_irq(&cachep->spinlock);
01655
01656 smp_call_function_all_cpus(do_ccupdate_local, (void *)&new);
01657
01658 for (i = 0; i < smp_num_cpus; i++) {
01659 cpucache_t* ccold = new.new[cpu_logical_map(i)];
01660 if (!ccold)
01661 continue;
01662 local_irq_disable();
01663 free_block(cachep, cc_entry(ccold), ccold->avail);
01664 local_irq_enable();
01665 kfree(ccold);
01666 }
01667 return 0;
01668 oom:
01669 for (i--; i >= 0; i--)
01670 kfree(new.new[cpu_logical_map(i)]);
01671 return -ENOMEM;
01672 }
01673
01674 static void enable_cpucache (kmem_cache_t *cachep)
01675 {
01676 int err;
01677 int limit;
01678
01679
01680 if (cachep->objsize > PAGE_SIZE)
01681 return;
01682 if (cachep->objsize > 1024)
01683 limit = 60;
01684 else if (cachep->objsize > 256)
01685 limit = 124;
01686 else
01687 limit = 252;
01688
01689 err = kmem_tune_cpucache(cachep, limit, limit/2);
01690 if (err)
01691 printk(KERN_ERR "enable_cpucache failed for %s, error %d.\n",
01692 cachep->name, -err);
01693 }
01694
01695 static void enable_all_cpucaches (void)
01696 {
01697 struct list_head* p;
01698
01699 down(&cache_chain_sem);
01700
01701 p = &cache_cache.next;
01702 do {
01703 kmem_cache_t* cachep = list_entry(p, kmem_cache_t, next);
01704
01705 enable_cpucache(cachep);
01706 p = cachep->next.next;
01707 } while (p != &cache_cache.next);
01708
01709 up(&cache_chain_sem);
01710 }
01711 #endif
01712
01713
01714
01715
01716
01717
01718
01719 int fastcall kmem_cache_reap (int gfp_mask)
01720 {
01721 slab_t *slabp;
01722 kmem_cache_t *searchp;
01723 kmem_cache_t *best_cachep;
01724 unsigned int best_pages;
01725 unsigned int best_len;
01726 unsigned int scan;
01727 int ret = 0;
01728
01729 if (gfp_mask & __GFP_WAIT)
01730 down(&cache_chain_sem);
01731 else
01732 if (down_trylock(&cache_chain_sem))
01733 return 0;
01734
01735 scan = REAP_SCANLEN;
01736 best_len = 0;
01737 best_pages = 0;
01738 best_cachep = NULL;
01739 searchp = clock_searchp;
01740 do {
01741 unsigned int pages;
01742 struct list_head* p;
01743 unsigned int full_free;
01744
01745
01746 if (searchp->flags & SLAB_NO_REAP)
01747 goto next;
01748 spin_lock_irq(&searchp->spinlock);
01749 if (searchp->growing)
01750 goto next_unlock;
01751 if (searchp->dflags & DFLGS_GROWN) {
01752 searchp->dflags &= ~DFLGS_GROWN;
01753 goto next_unlock;
01754 }
01755 #ifdef CONFIG_SMP
01756 {
01757 cpucache_t *cc = cc_data(searchp);
01758 if (cc && cc->avail) {
01759 __free_block(searchp, cc_entry(cc), cc->avail);
01760 cc->avail = 0;
01761 }
01762 }
01763 #endif
01764
01765 full_free = 0;
01766 p = searchp->slabs_free.next;
01767 while (p != &searchp->slabs_free) {
01768 slabp = list_entry(p, slab_t, list);
01769 #if DEBUG
01770 if (slabp->inuse)
01771 BUG();
01772 #endif
01773 full_free++;
01774 p = p->next;
01775 }
01776
01777
01778
01779
01780
01781
01782 pages = full_free * (1<<searchp->gfporder);
01783 if (searchp->ctor)
01784 pages = (pages*4+1)/5;
01785 if (searchp->gfporder)
01786 pages = (pages*4+1)/5;
01787 if (pages > best_pages) {
01788 best_cachep = searchp;
01789 best_len = full_free;
01790 best_pages = pages;
01791 if (pages >= REAP_PERFECT) {
01792 clock_searchp = list_entry(searchp->next.next,
01793 kmem_cache_t,next);
01794 goto perfect;
01795 }
01796 }
01797 next_unlock:
01798 spin_unlock_irq(&searchp->spinlock);
01799 next:
01800 searchp = list_entry(searchp->next.next,kmem_cache_t,next);
01801 } while (--scan && searchp != clock_searchp);
01802
01803 clock_searchp = searchp;
01804
01805 if (!best_cachep)
01806
01807 goto out;
01808
01809 spin_lock_irq(&best_cachep->spinlock);
01810 perfect:
01811
01812 best_len = (best_len + 1)/2;
01813 for (scan = 0; scan < best_len; scan++) {
01814 struct list_head *p;
01815
01816 if (best_cachep->growing)
01817 break;
01818 p = best_cachep->slabs_free.prev;
01819 if (p == &best_cachep->slabs_free)
01820 break;
01821 slabp = list_entry(p,slab_t,list);
01822 #if DEBUG
01823 if (slabp->inuse)
01824 BUG();
01825 #endif
01826 list_del(&slabp->list);
01827 STATS_INC_REAPED(best_cachep);
01828
01829
01830
01831
01832 spin_unlock_irq(&best_cachep->spinlock);
01833 kmem_slab_destroy(best_cachep, slabp);
01834 spin_lock_irq(&best_cachep->spinlock);
01835 }
01836 spin_unlock_irq(&best_cachep->spinlock);
01837 ret = scan * (1 << best_cachep->gfporder);
01838 out:
01839 up(&cache_chain_sem);
01840 return ret;
01841 }
01842
01843 #ifdef CONFIG_PROC_FS
01844
01845
01846
01847
01848
01849 #define FIXUP(t) \
01850 do { \
01851 if (len <= off) { \
01852 off -= len; \
01853 len = 0; \
01854 } else { \
01855 if (len-off > count) \
01856 goto t; \
01857 } \
01858 } while (0)
01859
01860 static int proc_getdata (char*page, char**start, off_t off, int count)
01861 {
01862 struct list_head *p;
01863 int len = 0;
01864
01865
01866
01867
01868 len += sprintf(page+len, "slabinfo - version: 1.1"
01869 #if STATS
01870 " (statistics)"
01871 #endif
01872 #ifdef CONFIG_SMP
01873 " (SMP)"
01874 #endif
01875 "\n");
01876 FIXUP(got_data);
01877
01878 down(&cache_chain_sem);
01879 p = &cache_cache.next;
01880 do {
01881 kmem_cache_t *cachep;
01882 struct list_head *q;
01883 slab_t *slabp;
01884 unsigned long active_objs;
01885 unsigned long num_objs;
01886 unsigned long active_slabs = 0;
01887 unsigned long num_slabs;
01888 cachep = list_entry(p, kmem_cache_t, next);
01889
01890 spin_lock_irq(&cachep->spinlock);
01891 active_objs = 0;
01892 num_slabs = 0;
01893 list_for_each(q,&cachep->slabs_full) {
01894 slabp = list_entry(q, slab_t, list);
01895 if (slabp->inuse != cachep->num)
01896 BUG();
01897 active_objs += cachep->num;
01898 active_slabs++;
01899 }
01900 list_for_each(q,&cachep->slabs_partial) {
01901 slabp = list_entry(q, slab_t, list);
01902 if (slabp->inuse == cachep->num || !slabp->inuse)
01903 BUG();
01904 active_objs += slabp->inuse;
01905 active_slabs++;
01906 }
01907 list_for_each(q,&cachep->slabs_free) {
01908 slabp = list_entry(q, slab_t, list);
01909 if (slabp->inuse)
01910 BUG();
01911 num_slabs++;
01912 }
01913 num_slabs+=active_slabs;
01914 num_objs = num_slabs*cachep->num;
01915
01916 len += sprintf(page+len, "%-17s %6lu %6lu %6u %4lu %4lu %4u",
01917 cachep->name, active_objs, num_objs, cachep->objsize,
01918 active_slabs, num_slabs, (1<<cachep->gfporder));
01919
01920 #if STATS
01921 {
01922 unsigned long errors = cachep->errors;
01923 unsigned long high = cachep->high_mark;
01924 unsigned long grown = cachep->grown;
01925 unsigned long reaped = cachep->reaped;
01926 unsigned long allocs = cachep->num_allocations;
01927
01928 len += sprintf(page+len, " : %6lu %7lu %5lu %4lu %4lu",
01929 high, allocs, grown, reaped, errors);
01930 }
01931 #endif
01932 #ifdef CONFIG_SMP
01933 {
01934 cpucache_t *cc = cc_data(cachep);
01935 unsigned int batchcount = cachep->batchcount;
01936 unsigned int limit;
01937
01938 if (cc)
01939 limit = cc->limit;
01940 else
01941 limit = 0;
01942 len += sprintf(page+len, " : %4u %4u",
01943 limit, batchcount);
01944 }
01945 #endif
01946 #if STATS && defined(CONFIG_SMP)
01947 {
01948 unsigned long allochit = atomic_read(&cachep->allochit);
01949 unsigned long allocmiss = atomic_read(&cachep->allocmiss);
01950 unsigned long freehit = atomic_read(&cachep->freehit);
01951 unsigned long freemiss = atomic_read(&cachep->freemiss);
01952 len += sprintf(page+len, " : %6lu %6lu %6lu %6lu",
01953 allochit, allocmiss, freehit, freemiss);
01954 }
01955 #endif
01956 len += sprintf(page+len,"\n");
01957 spin_unlock_irq(&cachep->spinlock);
01958 FIXUP(got_data_up);
01959 p = cachep->next.next;
01960 } while (p != &cache_cache.next);
01961 got_data_up:
01962 up(&cache_chain_sem);
01963
01964 got_data:
01965 *start = page+off;
01966 return len;
01967 }
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988 int slabinfo_read_proc (char *page, char **start, off_t off,
01989 int count, int *eof, void *data)
01990 {
01991 int len = proc_getdata(page, start, off, count);
01992 len -= (*start-page);
01993 if (len <= count)
01994 *eof = 1;
01995 if (len>count) len = count;
01996 if (len<0) len = 0;
01997 return len;
01998 }
01999
02000 #define MAX_SLABINFO_WRITE 128
02001
02002
02003
02004
02005
02006
02007
02008 int slabinfo_write_proc (struct file *file, const char *buffer,
02009 unsigned long count, void *data)
02010 {
02011 #ifdef CONFIG_SMP
02012 char kbuf[MAX_SLABINFO_WRITE+1], *tmp;
02013 int limit, batchcount, res;
02014 struct list_head *p;
02015
02016 if (count > MAX_SLABINFO_WRITE)
02017 return -EINVAL;
02018 if (copy_from_user(&kbuf, buffer, count))
02019 return -EFAULT;
02020 kbuf[MAX_SLABINFO_WRITE] = '\0';
02021
02022 tmp = strchr(kbuf, ' ');
02023 if (!tmp)
02024 return -EINVAL;
02025 *tmp = '\0';
02026 tmp++;
02027 limit = simple_strtol(tmp, &tmp, 10);
02028 while (*tmp == ' ')
02029 tmp++;
02030 batchcount = simple_strtol(tmp, &tmp, 10);
02031
02032
02033 down(&cache_chain_sem);
02034 res = -EINVAL;
02035 list_for_each(p,&cache_chain) {
02036 kmem_cache_t *cachep = list_entry(p, kmem_cache_t, next);
02037
02038 if (!strcmp(cachep->name, kbuf)) {
02039 res = kmem_tune_cpucache(cachep, limit, batchcount);
02040 break;
02041 }
02042 }
02043 up(&cache_chain_sem);
02044 if (res >= 0)
02045 res = count;
02046 return res;
02047 #else
02048 return -EINVAL;
02049 #endif
02050 }
02051 #endif
02052
02053 #if 0
02054 void * kmalloc (size_t size, int flags)
02055 {
02056 return (void *) __get_free_pages(0,size>>12);
02057
02058 }
02059
02060 void kmem_cache_free (kmem_cache_t *cachep, void *objp)
02061 {
02062 free_pages(objp,cachep->objsize>>12);
02063
02064 }
02065
02066
02067
02068
02069
02070
02071
02072
02073 void kfree (const void *objp)
02074 {
02075 free_pages(objp,0);
02076
02077 }
02078
02079 kmem_cache_t * kmem_find_general_cachep (size_t size, int gfpflags)
02080 {
02081 return 0;
02082 }
02083
02084 kmem_cache_t *
02085 kmem_cache_create (const char *name, size_t size, size_t offset,
02086 unsigned long flags, void (*ctor)(void*, kmem_cache_t *, unsigned long),
02087 void (*dtor)(void*, kmem_cache_t *, unsigned long))
02088 {
02089 return 0;
02090 }
02091
02092 void * __kmem_cache_alloc (kmem_cache_t *cachep, int flags)
02093 {
02094 return (void *) __get_free_pages(0,cachep->objsize>>12);
02095 }
02096
02097 void * kmem_cache_alloc (kmem_cache_t *cachep, int flags)
02098 {
02099 return __kmem_cache_alloc(cachep, flags);
02100 }
02101
02102 #endif
02103