--- mm/slub.c | 47 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 7 deletions(-) Index: linux-2.6/mm/slub.c =================================================================== --- linux-2.6.orig/mm/slub.c 2007-10-18 12:27:02.000000000 -0700 +++ linux-2.6/mm/slub.c 2007-10-18 12:28:07.000000000 -0700 @@ -101,6 +101,7 @@ #define FROZEN (1 << PG_active) #define SLABPARTIAL (1 << PG_writeback) +#define SLABFULL (1 << PG_dirty) #ifdef CONFIG_SLUB_DEBUG #define SLABDEBUG (1 << PG_error) @@ -149,6 +150,24 @@ static inline void ClearSlabPartial(stru } /* + * The partialbit is updated under list_lock + */ +static inline int SlabFull(struct page *page) +{ + return page->flags & SLABFULL; +} + +static inline void SetSlabFull(struct page *page) +{ + page->flags |= SLABFULL; +} + +static inline void ClearSlabFull(struct page *page) +{ + page->flags &= ~SLABFULL; +} + +/* * Slabdebug is only set on slab creation and destruction */ static inline int SlabDebug(struct page *page) @@ -862,9 +881,17 @@ static void add_full(struct kmem_cache * struct kmem_cache_node *n = get_node(s, page_to_nid(page)); unsigned long flags; + if (!SlabDebug(page)) + return; + + if (!(s->flags & SLAB_STORE_USER)) + return; + spin_lock_irqsave(&n->list_lock, flags); - if (!SlabPartial(page)) + if (!SlabPartial(page) && !SlabFull(page)) { + SetSlabFull(page); list_add(&page->lru, &n->full); + } spin_unlock_irqrestore(&n->list_lock, flags); } @@ -880,6 +907,7 @@ static void remove_full(struct kmem_cach spin_lock_irqsave(&n->list_lock, flags); list_del(&page->lru); + ClearSlabFull(page); spin_unlock_irqrestore(&n->list_lock, flags); } @@ -1264,6 +1292,10 @@ static void add_partial(struct kmem_cach unsigned long flags; spin_lock_irqsave(&n->list_lock, flags); + if (SlabFull(page)) { + list_del(&page->lru); + ClearSlabFull(page); + } if (!SlabPartial(page)) { SetSlabPartial(page); n->nr_partial++; @@ -1401,7 +1433,7 @@ static void unfreeze_slab(struct kmem_ca */ if (page->freelist) add_partial(s, page, tail); - else if (SlabDebug(page) && (s->flags & SLAB_STORE_USER)) + else add_full(s, page); slab_unlock(page); }