Linux Headquarters
[ Register ]
[ About us ] [ Home Page ]

[ Kernel ] [ Documentation ] [ Links ] [ Books ]

Kernel v2.4.13-ac8 /mm/slab.c

Filename:/mm/slab.c
Lines Added:56
Lines Deleted:56
Also changed in: (Previous) 2.4.13-ac7  2.4.13-ac6  2.4.13-ac5  2.4.13-ac4  2.4.13-ac3  2.4.13-ac1 
(Following) 2.4.17-pre3  2.4.17-pre4  2.4.17-pre5  2.4.17-pre6  2.4.17-pre7  2.4.17-pre8 

Location
[  2.4.13-ac8
  [  mm
     o  slab.c

Patch

diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/mm/slab.c linux.ac/mm/slab.c
--- linux.vanilla/mm/slab.c   Tue Sep 18 22:16:26 2001
+++ linux.ac/mm/slab.c   Wed Oct 10 01:48:38 2001
@@ -72,7 +72,6 @@
 #include   <linux/slab.h>
 #include   <linux/interrupt.h>
 #include   <linux/init.h>
-#include   <linux/compiler.h>
 #include   <asm/uaccess.h>
 
 /*
@@ -109,9 +108,11 @@
 #if DEBUG
 # define CREATE_MASK   (SLAB_DEBUG_INITIAL | SLAB_RED_ZONE | \
           SLAB_POISON | SLAB_HWCACHE_ALIGN | \
-          SLAB_NO_REAP | SLAB_CACHE_DMA)
+          SLAB_NO_REAP | SLAB_CACHE_DMA | \
+          SLAB_MUST_HWCACHE_ALIGN)
 #else
-# define CREATE_MASK   (SLAB_HWCACHE_ALIGN | SLAB_NO_REAP | SLAB_CACHE_DMA)
+# define CREATE_MASK   (SLAB_HWCACHE_ALIGN | SLAB_NO_REAP | \
+          SLAB_CACHE_DMA | SLAB_MUST_HWCACHE_ALIGN)
 #endif
 
 /*
@@ -456,7 +457,7 @@
       /* Inc off-slab bufctl limit until the ceiling is hit. */
       if (!(OFF_SLAB(sizes->cs_cachep))) {
          offslab_limit = sizes->cs_size-sizeof(slab_t);
-         offslab_limit /= 2;
+         offslab_limit /= sizeof(kmem_bufctl_t);
       }
       sprintf(name, "size-%Zd(DMA)",sizes->cs_size);
       sizes->cs_dmacachep = kmem_cache_create(name, sizes->cs_size, 0,
@@ -649,7 +650,7 @@
       flags &= ~SLAB_POISON;
    }
 #if FORCED_DEBUG
-   if (size < (PAGE_SIZE>>3))
+   if ((size < (PAGE_SIZE>>3)) && !(flags & SLAB_MUST_HWCACHE_ALIGN))
       /*
        * do not red zone large object, causes severe
        * fragmentation.
@@ -927,10 +928,8 @@
          break;
 
       slabp = list_entry(cachep->slabs_free.prev, slab_t, list);
-#if DEBUG
       if (slabp->inuse)
          BUG();
-#endif
       list_del(&slabp->list);
 
       spin_unlock_irq(&cachep->spinlock);
@@ -1208,6 +1207,7 @@
 
 static inline void kmem_cache_alloc_head(kmem_cache_t *cachep, int flags)
 {
+#if DEBUG
    if (flags & SLAB_DMA) {
       if (!(cachep->gfpflags & GFP_DMA))
          BUG();
@@ -1215,10 +1215,11 @@
       if (cachep->gfpflags & GFP_DMA)
          BUG();
    }
+#endif
 }
 
 static inline void * kmem_cache_alloc_one_tail (kmem_cache_t *cachep,
-                  slab_t *slabp)
+                  slab_t *slabp, int partial)
 {
    void *objp;
 
@@ -1231,9 +1232,14 @@
    objp = slabp->s_mem + slabp->free*cachep->objsize;
    slabp->free=slab_bufctl(slabp)[slabp->free];
 
-   if (unlikely(slabp->free == BUFCTL_END)) {
+   if (slabp->free == BUFCTL_END) {
       list_del(&slabp->list);
       list_add(&slabp->list, &cachep->slabs_full);
+   } else {
+      if (!partial) {
+         list_del(&slabp->list);
+         list_add(&slabp->list, &cachep->slabs_partial);
+      }
    }
 #if DEBUG
    if (cachep->flags & SLAB_POISON)
@@ -1260,23 +1266,20 @@
  */
 #define kmem_cache_alloc_one(cachep)            \
 ({                        \
-   struct list_head * slabs_partial, * entry;      \
-   slab_t *slabp;                  \
+   slab_t   *slabp;                  \
+   struct list_head * slab_freelist;         \
+   int partial = 1;               \
                         \
-   slabs_partial = &(cachep)->slabs_partial;      \
-   entry = slabs_partial->next;            \
-   if (unlikely(entry == slabs_partial)) {         \
-      struct list_head * slabs_free;         \
-      slabs_free = &(cachep)->slabs_free;      \
-      entry = slabs_free->next;         \
-      if (unlikely(entry == slabs_free))      \
+   slab_freelist = &(cachep)->slabs_partial;      \
+   if (list_empty(slab_freelist)) {         \
+      partial = 0;               \
+      slab_freelist = &(cachep)->slabs_free;      \
+      if (list_empty(slab_freelist))         \
          goto alloc_new_slab;         \
-      list_del(entry);            \
-      list_add(entry, slabs_partial);         \
    }                     \
                         \
-   slabp = list_entry(entry, slab_t, list);      \
-   kmem_cache_alloc_one_tail(cachep, slabp);      \
+   slabp = list_entry(slab_freelist->next, slab_t, list);   \
+   kmem_cache_alloc_one_tail(cachep, slabp, partial);   \
 })
 
 #ifdef CONFIG_SMP
@@ -1284,27 +1287,25 @@
 {
    int batchcount = cachep->batchcount;
    cpucache_t* cc = cc_data(cachep);
+   struct list_head * slab_freelist;
+   int partial;
+   slab_t *slabp;
 
    spin_lock(&cachep->spinlock);
    while (batchcount--) {
-      struct list_head * slabs_partial, * entry;
-      slab_t *slabp;
       /* Get slab alloc is to come from. */
-      slabs_partial = &(cachep)->slabs_partial;
-      entry = slabs_partial->next;
-      if (unlikely(entry == slabs_partial)) {
-         struct list_head * slabs_free;
-         slabs_free = &(cachep)->slabs_free;
-         entry = slabs_free->next;
-         if (unlikely(entry == slabs_free))
+      slab_freelist = &(cachep)->slabs_partial;
+      partial = 1;
+      if (list_empty(slab_freelist)) {
+         partial = 0;
+         slab_freelist = &(cachep)->slabs_free;
+         if (list_empty(slab_freelist))
             break;
-         list_del(entry);
-         list_add(entry, slabs_partial);
       }
 
-      slabp = list_entry(entry, slab_t, list);
+      slabp = list_entry(slab_freelist->next, slab_t, list);
       cc_entry(cc)[cc->avail++] =
-            kmem_cache_alloc_one_tail(cachep, slabp);
+            kmem_cache_alloc_one_tail(cachep, slabp, partial);
    }
    spin_unlock(&cachep->spinlock);
 
@@ -1435,18 +1436,23 @@
    STATS_DEC_ACTIVE(cachep);
    
    /* fixup slab chains */
-   {
-      int inuse = slabp->inuse;
-      if (unlikely(!--slabp->inuse)) {
-         /* Was partial or full, now empty. */
-         list_del(&slabp->list);
-         list_add(&slabp->list, &cachep->slabs_free);
-      } else if (unlikely(inuse == cachep->num)) {
-         /* Was full. */
-         list_del(&slabp->list);
-         list_add(&slabp->list, &cachep->slabs_partial);
-      }
-   }
+   if (!--slabp->inuse)
+      goto moveslab_free;
+   if (slabp->inuse + 1 == cachep->num)
+      goto moveslab_partial;
+   return;
+
+moveslab_partial:
+       /* Was full. */
+   list_del(&slabp->list);
+   list_add(&slabp->list, &cachep->slabs_partial);
+   return;
+
+moveslab_free:
+   /* Was partial, now empty. */
+   list_del(&slabp->list);
+   list_add(&slabp->list, &cachep->slabs_free);
+   return;
 }
 
 #ifdef CONFIG_SMP
@@ -1705,7 +1711,7 @@
  *
  * Called from do_try_to_free_pages() and __alloc_pages()
  */
-int kmem_cache_reap (int gfp_mask)
+void kmem_cache_reap (int gfp_mask)
 {
    slab_t *slabp;
    kmem_cache_t *searchp;
@@ -1713,13 +1719,12 @@
    unsigned int best_pages;
    unsigned int best_len;
    unsigned int scan;
-   int ret = 0;
 
    if (gfp_mask & __GFP_WAIT)
       down(&cache_chain_sem);
    else
       if (down_trylock(&cache_chain_sem))
-         return 0;
+         return;
 
    scan = REAP_SCANLEN;
    best_len = 0;
@@ -1755,10 +1760,8 @@
       p = searchp->slabs_free.next;
       while (p != &searchp->slabs_free) {
          slabp = list_entry(p, slab_t, list);
-#if DEBUG
          if (slabp->inuse)
             BUG();
-#endif
          full_free++;
          p = p->next;
       }
@@ -1808,10 +1811,8 @@
       if (p == &best_cachep->slabs_free)
          break;
       slabp = list_entry(p,slab_t,list);
-#if DEBUG
       if (slabp->inuse)
          BUG();
-#endif
       list_del(&slabp->list);
       STATS_INC_REAPED(best_cachep);
 
@@ -1823,10 +1824,9 @@
       spin_lock_irq(&best_cachep->spinlock);
    }
    spin_unlock_irq(&best_cachep->spinlock);
-   ret = scan * (1 << best_cachep->gfporder);
 out:
    up(&cache_chain_sem);
-   return ret;
+   return;
 }
 
 #ifdef CONFIG_PROC_FS


Comments: webmaster (at) linuxhq.com.
Advertising: banners (at) linuxhq.com.
Compilation ©1998-2008 Linux Headquarters, Inc.