]> Pileus Git - ~andy/linux/commitdiff
Merge branch 'slab/next' of git://git.kernel.org/pub/scm/linux/kernel/git/penberg...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 22 Nov 2013 16:10:34 +0000 (08:10 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 22 Nov 2013 16:10:34 +0000 (08:10 -0800)
Pull SLAB changes from Pekka Enberg:
 "The patches from Joonsoo Kim switch mm/slab.c to use 'struct page' for
  slab internals similar to mm/slub.c.  This reduces memory usage and
  improves performance:

    https://lkml.org/lkml/2013/10/16/155

  Rest of the changes are bug fixes from various people"

* 'slab/next' of git://git.kernel.org/pub/scm/linux/kernel/git/penberg/linux: (21 commits)
  mm, slub: fix the typo in mm/slub.c
  mm, slub: fix the typo in include/linux/slub_def.h
  slub: Handle NULL parameter in kmem_cache_flags
  slab: replace non-existing 'struct freelist *' with 'void *'
  slab: fix to calm down kmemleak warning
  slub: proper kmemleak tracking if CONFIG_SLUB_DEBUG disabled
  slab: rename slab_bufctl to slab_freelist
  slab: remove useless statement for checking pfmemalloc
  slab: use struct page for slab management
  slab: replace free and inuse in struct slab with newly introduced active
  slab: remove SLAB_LIMIT
  slab: remove kmem_bufctl_t
  slab: change the management method of free objects of the slab
  slab: use __GFP_COMP flag for allocating slab pages
  slab: use well-defined macro, virt_to_slab()
  slab: overloading the RCU head over the LRU for RCU free
  slab: remove cachep in struct slab_rcu
  slab: remove nodeid in struct slab
  slab: remove colouroff in struct slab
  slab: change return type of kmem_getpages() to struct page
  ...

1  2 
include/linux/mm_types.h
include/linux/slab.h
include/linux/slab_def.h
include/linux/slub_def.h
mm/slab.c
mm/slub.c

diff --combined include/linux/mm_types.h
index 011eb85d7b0f75709471990e261396922c156477,95bf0c5a7eb9584cd668b9fb60268543dcf91dbb..bd299418a934e21b99c303af82a7c2f427bbf915
@@@ -23,9 -23,7 +23,9 @@@
  
  struct address_space;
  
 -#define USE_SPLIT_PTLOCKS     (NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS)
 +#define USE_SPLIT_PTE_PTLOCKS (NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS)
 +#define USE_SPLIT_PMD_PTLOCKS (USE_SPLIT_PTE_PTLOCKS && \
 +              IS_ENABLED(CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK))
  
  /*
   * Each physical page in the system has a struct page associated with
@@@ -44,18 -42,22 +44,22 @@@ struct page 
        /* First double word block */
        unsigned long flags;            /* Atomic flags, some possibly
                                         * updated asynchronously */
-       struct address_space *mapping;  /* If low bit clear, points to
-                                        * inode address_space, or NULL.
-                                        * If page mapped as anonymous
-                                        * memory, low bit is set, and
-                                        * it points to anon_vma object:
-                                        * see PAGE_MAPPING_ANON below.
-                                        */
+       union {
+               struct address_space *mapping;  /* If low bit clear, points to
+                                                * inode address_space, or NULL.
+                                                * If page mapped as anonymous
+                                                * memory, low bit is set, and
+                                                * it points to anon_vma object:
+                                                * see PAGE_MAPPING_ANON below.
+                                                */
+               void *s_mem;                    /* slab first object */
+       };
        /* Second double word */
        struct {
                union {
                        pgoff_t index;          /* Our offset within mapping. */
-                       void *freelist;         /* slub/slob first free object */
+                       void *freelist;         /* sl[aou]b first free object */
                        bool pfmemalloc;        /* If set by the page allocator,
                                                 * ALLOC_NO_WATERMARKS was set
                                                 * and the low watermark was not
                                };
                                atomic_t _count;                /* Usage count, see below. */
                        };
+                       unsigned int active;    /* SLAB */
                };
        };
  
  
                struct list_head list;  /* slobs list of pages */
                struct slab *slab_page; /* slab fields */
+               struct rcu_head rcu_head;       /* Used by SLAB
+                                                * when destroying via RCU
+                                                */
 +#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && USE_SPLIT_PMD_PTLOCKS
 +              pgtable_t pmd_huge_pte; /* protected by page->ptl */
 +#endif
        };
  
        /* Remainder is not double word aligned */
                                                 * indicates order in the buddy
                                                 * system if PG_buddy is set.
                                                 */
 -#if USE_SPLIT_PTLOCKS
 +#if USE_SPLIT_PTE_PTLOCKS
 +#if BLOATED_SPINLOCKS
 +              spinlock_t *ptl;
 +#else
                spinlock_t ptl;
 +#endif
  #endif
                struct kmem_cache *slab_cache;  /* SL[AU]B: Pointer to slab */
                struct page *first_page;        /* Compound tail pages */
        void *shadow;
  #endif
  
 -#ifdef LAST_NID_NOT_IN_PAGE_FLAGS
 -      int _last_nid;
 +#ifdef LAST_CPUPID_NOT_IN_PAGE_FLAGS
 +      int _last_cpupid;
  #endif
  }
  /*
@@@ -318,20 -317,19 +326,20 @@@ enum 
        NR_MM_COUNTERS
  };
  
 -#if USE_SPLIT_PTLOCKS && defined(CONFIG_MMU)
 +#if USE_SPLIT_PTE_PTLOCKS && defined(CONFIG_MMU)
  #define SPLIT_RSS_COUNTING
  /* per-thread cached information, */
  struct task_rss_stat {
        int events;     /* for synchronization threshold */
        int count[NR_MM_COUNTERS];
  };
 -#endif /* USE_SPLIT_PTLOCKS */
 +#endif /* USE_SPLIT_PTE_PTLOCKS */
  
  struct mm_rss_stat {
        atomic_long_t count[NR_MM_COUNTERS];
  };
  
 +struct kioctx_table;
  struct mm_struct {
        struct vm_area_struct * mmap;           /* list of VMAs */
        struct rb_root mm_rb;
        pgd_t * pgd;
        atomic_t mm_users;                      /* How many users with user space? */
        atomic_t mm_count;                      /* How many references to "struct mm_struct" (users count as 1) */
 +      atomic_long_t nr_ptes;                  /* Page table pages */
        int map_count;                          /* number of VMAs */
  
        spinlock_t page_table_lock;             /* Protects page tables and some counters */
        unsigned long exec_vm;          /* VM_EXEC & ~VM_WRITE */
        unsigned long stack_vm;         /* VM_GROWSUP/DOWN */
        unsigned long def_flags;
 -      unsigned long nr_ptes;          /* Page table pages */
        unsigned long start_code, end_code, start_data, end_data;
        unsigned long start_brk, brk, start_stack;
        unsigned long arg_start, arg_end, env_start, env_end;
  
        struct core_state *core_state; /* coredumping support */
  #ifdef CONFIG_AIO
 -      spinlock_t              ioctx_lock;
 -      struct hlist_head       ioctx_list;
 +      spinlock_t                      ioctx_lock;
 +      struct kioctx_table __rcu       *ioctx_table;
  #endif
  #ifdef CONFIG_MM_OWNER
        /*
  #ifdef CONFIG_MMU_NOTIFIER
        struct mmu_notifier_mm *mmu_notifier_mm;
  #endif
 -#ifdef CONFIG_TRANSPARENT_HUGEPAGE
 +#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && !USE_SPLIT_PMD_PTLOCKS
        pgtable_t pmd_huge_pte; /* protected by page_table_lock */
  #endif
  #ifdef CONFIG_CPUMASK_OFFSTACK
         */
        unsigned long numa_next_scan;
  
 -      /* numa_next_reset is when the PTE scanner period will be reset */
 -      unsigned long numa_next_reset;
 -
        /* Restart point for scanning and setting pte_numa */
        unsigned long numa_scan_offset;
  
        /* numa_scan_seq prevents two threads setting pte_numa */
        int numa_scan_seq;
 -
 -      /*
 -       * The first node a task was scheduled on. If a task runs on
 -       * a different node than Make PTE Scan Go Now.
 -       */
 -      int first_nid;
  #endif
        struct uprobes_state uprobes_state;
  };
  
 -/* first nid will either be a valid NID or one of these values */
 -#define NUMA_PTE_SCAN_INIT    -1
 -#define NUMA_PTE_SCAN_ACTIVE  -2
 -
  static inline void mm_init_cpumask(struct mm_struct *mm)
  {
  #ifdef CONFIG_CPUMASK_OFFSTACK
diff --combined include/linux/slab.h
index 74f105847d13ceae757c8aa6b83bdf8412816696,caaad51fee1f708e6ced5de4e5a4b8c86abb6006..c2bba248fa63d46024930f5b4d6c47b652a51dc6
@@@ -4,8 -4,6 +4,8 @@@
   * (C) SGI 2006, Christoph Lameter
   *    Cleaned up and restructured to ease the addition of alternative
   *    implementations of SLAB allocators.
 + * (C) Linux Foundation 2008-2013
 + *      Unified interface for all slab allocators
   */
  
  #ifndef _LINUX_SLAB_H
   *  }
   *  rcu_read_unlock();
   *
-  * See also the comment on struct slab_rcu in mm/slab.c.
+  * This is useful if we need to approach a kernel structure obliquely,
+  * from its address obtained without the usual locking. We can lock
+  * the structure to stabilize it and check it's still at the given address,
+  * only if we can be sure that the memory has not been meanwhile reused
+  * for some other kind of object (which our subsystem's lock might corrupt).
+  *
+  * rcu_read_lock before reading the address, then rcu_read_unlock after
+  * taking the spinlock within the structure expected at that address.
   */
  #define SLAB_DESTROY_BY_RCU   0x00080000UL    /* Defer freeing slabs to RCU */
  #define SLAB_MEM_SPREAD               0x00100000UL    /* Spread some memory over cpuset */
  #define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= \
                                (unsigned long)ZERO_SIZE_PTR)
  
 +#include <linux/kmemleak.h>
  
  struct mem_cgroup;
  /*
@@@ -292,57 -296,6 +299,57 @@@ static __always_inline int kmalloc_inde
  }
  #endif /* !CONFIG_SLOB */
  
 +void *__kmalloc(size_t size, gfp_t flags);
 +void *kmem_cache_alloc(struct kmem_cache *, gfp_t flags);
 +
 +#ifdef CONFIG_NUMA
 +void *__kmalloc_node(size_t size, gfp_t flags, int node);
 +void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
 +#else
 +static __always_inline void *__kmalloc_node(size_t size, gfp_t flags, int node)
 +{
 +      return __kmalloc(size, flags);
 +}
 +
 +static __always_inline void *kmem_cache_alloc_node(struct kmem_cache *s, gfp_t flags, int node)
 +{
 +      return kmem_cache_alloc(s, flags);
 +}
 +#endif
 +
 +#ifdef CONFIG_TRACING
 +extern void *kmem_cache_alloc_trace(struct kmem_cache *, gfp_t, size_t);
 +
 +#ifdef CONFIG_NUMA
 +extern void *kmem_cache_alloc_node_trace(struct kmem_cache *s,
 +                                         gfp_t gfpflags,
 +                                         int node, size_t size);
 +#else
 +static __always_inline void *
 +kmem_cache_alloc_node_trace(struct kmem_cache *s,
 +                            gfp_t gfpflags,
 +                            int node, size_t size)
 +{
 +      return kmem_cache_alloc_trace(s, gfpflags, size);
 +}
 +#endif /* CONFIG_NUMA */
 +
 +#else /* CONFIG_TRACING */
 +static __always_inline void *kmem_cache_alloc_trace(struct kmem_cache *s,
 +              gfp_t flags, size_t size)
 +{
 +      return kmem_cache_alloc(s, flags);
 +}
 +
 +static __always_inline void *
 +kmem_cache_alloc_node_trace(struct kmem_cache *s,
 +                            gfp_t gfpflags,
 +                            int node, size_t size)
 +{
 +      return kmem_cache_alloc_node(s, gfpflags, node);
 +}
 +#endif /* CONFIG_TRACING */
 +
  #ifdef CONFIG_SLAB
  #include <linux/slab_def.h>
  #endif
  #include <linux/slub_def.h>
  #endif
  
 -#ifdef CONFIG_SLOB
 -#include <linux/slob_def.h>
 +static __always_inline void *
 +kmalloc_order(size_t size, gfp_t flags, unsigned int order)
 +{
 +      void *ret;
 +
 +      flags |= (__GFP_COMP | __GFP_KMEMCG);
 +      ret = (void *) __get_free_pages(flags, order);
 +      kmemleak_alloc(ret, size, 1, flags);
 +      return ret;
 +}
 +
 +#ifdef CONFIG_TRACING
 +extern void *kmalloc_order_trace(size_t size, gfp_t flags, unsigned int order);
 +#else
 +static __always_inline void *
 +kmalloc_order_trace(size_t size, gfp_t flags, unsigned int order)
 +{
 +      return kmalloc_order(size, flags, order);
 +}
  #endif
  
 +static __always_inline void *kmalloc_large(size_t size, gfp_t flags)
 +{
 +      unsigned int order = get_order(size);
 +      return kmalloc_order_trace(size, flags, order);
 +}
 +
 +/**
 + * kmalloc - allocate memory
 + * @size: how many bytes of memory are required.
 + * @flags: the type of memory to allocate (see kcalloc).
 + *
 + * kmalloc is the normal method of allocating memory
 + * for objects smaller than page size in the kernel.
 + */
 +static __always_inline void *kmalloc(size_t size, gfp_t flags)
 +{
 +      if (__builtin_constant_p(size)) {
 +              if (size > KMALLOC_MAX_CACHE_SIZE)
 +                      return kmalloc_large(size, flags);
 +#ifndef CONFIG_SLOB
 +              if (!(flags & GFP_DMA)) {
 +                      int index = kmalloc_index(size);
 +
 +                      if (!index)
 +                              return ZERO_SIZE_PTR;
 +
 +                      return kmem_cache_alloc_trace(kmalloc_caches[index],
 +                                      flags, size);
 +              }
 +#endif
 +      }
 +      return __kmalloc(size, flags);
 +}
 +
  /*
   * Determine size used for the nth kmalloc cache.
   * return size or 0 if a kmalloc cache for that
@@@ -426,23 -328,6 +433,23 @@@ static __always_inline int kmalloc_size
        return 0;
  }
  
 +static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node)
 +{
 +#ifndef CONFIG_SLOB
 +      if (__builtin_constant_p(size) &&
 +              size <= KMALLOC_MAX_CACHE_SIZE && !(flags & GFP_DMA)) {
 +              int i = kmalloc_index(size);
 +
 +              if (!i)
 +                      return ZERO_SIZE_PTR;
 +
 +              return kmem_cache_alloc_node_trace(kmalloc_caches[i],
 +                                              flags, node, size);
 +      }
 +#endif
 +      return __kmalloc_node(size, flags, node);
 +}
 +
  /*
   * Setting ARCH_SLAB_MINALIGN in arch headers allows a different alignment.
   * Intended for arches that get misalignment faults even for 64 bit integer
@@@ -573,6 -458,36 +580,6 @@@ static inline void *kcalloc(size_t n, s
        return kmalloc_array(n, size, flags | __GFP_ZERO);
  }
  
 -#if !defined(CONFIG_NUMA) && !defined(CONFIG_SLOB)
 -/**
 - * kmalloc_node - allocate memory from a specific node
 - * @size: how many bytes of memory are required.
 - * @flags: the type of memory to allocate (see kmalloc).
 - * @node: node to allocate from.
 - *
 - * kmalloc() for non-local nodes, used to allocate from a specific node
 - * if available. Equivalent to kmalloc() in the non-NUMA single-node
 - * case.
 - */
 -static inline void *kmalloc_node(size_t size, gfp_t flags, int node)
 -{
 -      return kmalloc(size, flags);
 -}
 -
 -static inline void *__kmalloc_node(size_t size, gfp_t flags, int node)
 -{
 -      return __kmalloc(size, flags);
 -}
 -
 -void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
 -
 -static inline void *kmem_cache_alloc_node(struct kmem_cache *cachep,
 -                                      gfp_t flags, int node)
 -{
 -      return kmem_cache_alloc(cachep, flags);
 -}
 -#endif /* !CONFIG_NUMA && !CONFIG_SLOB */
 -
  /*
   * kmalloc_track_caller is a special version of kmalloc that records the
   * calling function of the routine calling it for slab leak tracking instead
diff --combined include/linux/slab_def.h
index e9346b4f1ef4b2ef6d302a5799e30e631fa10ce2,ca82e8ff89fa29375e5055f312f85bb7812c0d8b..09bfffb08a56db285caa27146202f04e2188b480
@@@ -3,6 -3,20 +3,6 @@@
  
  /*
   * Definitions unique to the original Linux SLAB allocator.
 - *
 - * What we provide here is a way to optimize the frequent kmalloc
 - * calls in the kernel by selecting the appropriate general cache
 - * if kmalloc was called with a size that can be established at
 - * compile time.
 - */
 -
 -#include <linux/init.h>
 -#include <linux/compiler.h>
 -
 -/*
 - * struct kmem_cache
 - *
 - * manages a cache.
   */
  
  struct kmem_cache {
@@@ -27,8 -41,8 +27,8 @@@
  
        size_t colour;                  /* cache colouring range */
        unsigned int colour_off;        /* colour offset */
-       struct kmem_cache *slabp_cache;
-       unsigned int slab_size;
+       struct kmem_cache *freelist_cache;
+       unsigned int freelist_size;
  
        /* constructor func */
        void (*ctor)(void *obj);
         */
  };
  
 -void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
 -void *__kmalloc(size_t size, gfp_t flags);
 -
 -#ifdef CONFIG_TRACING
 -extern void *kmem_cache_alloc_trace(struct kmem_cache *, gfp_t, size_t);
 -#else
 -static __always_inline void *
 -kmem_cache_alloc_trace(struct kmem_cache *cachep, gfp_t flags, size_t size)
 -{
 -      return kmem_cache_alloc(cachep, flags);
 -}
 -#endif
 -
 -static __always_inline void *kmalloc(size_t size, gfp_t flags)
 -{
 -      struct kmem_cache *cachep;
 -      void *ret;
 -
 -      if (__builtin_constant_p(size)) {
 -              int i;
 -
 -              if (!size)
 -                      return ZERO_SIZE_PTR;
 -
 -              if (WARN_ON_ONCE(size > KMALLOC_MAX_SIZE))
 -                      return NULL;
 -
 -              i = kmalloc_index(size);
 -
 -#ifdef CONFIG_ZONE_DMA
 -              if (flags & GFP_DMA)
 -                      cachep = kmalloc_dma_caches[i];
 -              else
 -#endif
 -                      cachep = kmalloc_caches[i];
 -
 -              ret = kmem_cache_alloc_trace(cachep, flags, size);
 -
 -              return ret;
 -      }
 -      return __kmalloc(size, flags);
 -}
 -
 -#ifdef CONFIG_NUMA
 -extern void *__kmalloc_node(size_t size, gfp_t flags, int node);
 -extern void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
 -
 -#ifdef CONFIG_TRACING
 -extern void *kmem_cache_alloc_node_trace(struct kmem_cache *cachep,
 -                                       gfp_t flags,
 -                                       int nodeid,
 -                                       size_t size);
 -#else
 -static __always_inline void *
 -kmem_cache_alloc_node_trace(struct kmem_cache *cachep,
 -                          gfp_t flags,
 -                          int nodeid,
 -                          size_t size)
 -{
 -      return kmem_cache_alloc_node(cachep, flags, nodeid);
 -}
 -#endif
 -
 -static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node)
 -{
 -      struct kmem_cache *cachep;
 -
 -      if (__builtin_constant_p(size)) {
 -              int i;
 -
 -              if (!size)
 -                      return ZERO_SIZE_PTR;
 -
 -              if (WARN_ON_ONCE(size > KMALLOC_MAX_SIZE))
 -                      return NULL;
 -
 -              i = kmalloc_index(size);
 -
 -#ifdef CONFIG_ZONE_DMA
 -              if (flags & GFP_DMA)
 -                      cachep = kmalloc_dma_caches[i];
 -              else
 -#endif
 -                      cachep = kmalloc_caches[i];
 -
 -              return kmem_cache_alloc_node_trace(cachep, flags, node, size);
 -      }
 -      return __kmalloc_node(size, flags, node);
 -}
 -
 -#endif        /* CONFIG_NUMA */
 -
  #endif        /* _LINUX_SLAB_DEF_H */
diff --combined include/linux/slub_def.h
index cc0b67eada4260331276e9ae145fa593c14ecee8,2dc4e78fc234e3b14ac89078fa3cfa60dbfc0e07..f56bfa9e4526f6382467fe2647c19bdbca185346
@@@ -6,12 -6,18 +6,12 @@@
   *
   * (C) 2007 SGI, Christoph Lameter
   */
 -#include <linux/types.h>
 -#include <linux/gfp.h>
 -#include <linux/bug.h>
 -#include <linux/workqueue.h>
  #include <linux/kobject.h>
  
 -#include <linux/kmemleak.h>
 -
  enum stat_item {
        ALLOC_FASTPATH,         /* Allocation from cpu slab */
        ALLOC_SLOWPATH,         /* Allocation by getting a new cpu slab */
-       FREE_FASTPATH,          /* Free to cpu slub */
+       FREE_FASTPATH,          /* Free to cpu slab */
        FREE_SLOWPATH,          /* Freeing not to cpu slab */
        FREE_FROZEN,            /* Freeing to frozen slab */
        FREE_ADD_PARTIAL,       /* Freeing moves slab to partial list */
@@@ -98,4 -104,108 +98,4 @@@ struct kmem_cache 
        struct kmem_cache_node *node[MAX_NUMNODES];
  };
  
 -void *kmem_cache_alloc(struct kmem_cache *, gfp_t);
 -void *__kmalloc(size_t size, gfp_t flags);
 -
 -static __always_inline void *
 -kmalloc_order(size_t size, gfp_t flags, unsigned int order)
 -{
 -      void *ret;
 -
 -      flags |= (__GFP_COMP | __GFP_KMEMCG);
 -      ret = (void *) __get_free_pages(flags, order);
 -      kmemleak_alloc(ret, size, 1, flags);
 -      return ret;
 -}
 -
 -/**
 - * Calling this on allocated memory will check that the memory
 - * is expected to be in use, and print warnings if not.
 - */
 -#ifdef CONFIG_SLUB_DEBUG
 -extern bool verify_mem_not_deleted(const void *x);
 -#else
 -static inline bool verify_mem_not_deleted(const void *x)
 -{
 -      return true;
 -}
 -#endif
 -
 -#ifdef CONFIG_TRACING
 -extern void *
 -kmem_cache_alloc_trace(struct kmem_cache *s, gfp_t gfpflags, size_t size);
 -extern void *kmalloc_order_trace(size_t size, gfp_t flags, unsigned int order);
 -#else
 -static __always_inline void *
 -kmem_cache_alloc_trace(struct kmem_cache *s, gfp_t gfpflags, size_t size)
 -{
 -      return kmem_cache_alloc(s, gfpflags);
 -}
 -
 -static __always_inline void *
 -kmalloc_order_trace(size_t size, gfp_t flags, unsigned int order)
 -{
 -      return kmalloc_order(size, flags, order);
 -}
 -#endif
 -
 -static __always_inline void *kmalloc_large(size_t size, gfp_t flags)
 -{
 -      unsigned int order = get_order(size);
 -      return kmalloc_order_trace(size, flags, order);
 -}
 -
 -static __always_inline void *kmalloc(size_t size, gfp_t flags)
 -{
 -      if (__builtin_constant_p(size)) {
 -              if (size > KMALLOC_MAX_CACHE_SIZE)
 -                      return kmalloc_large(size, flags);
 -
 -              if (!(flags & GFP_DMA)) {
 -                      int index = kmalloc_index(size);
 -
 -                      if (!index)
 -                              return ZERO_SIZE_PTR;
 -
 -                      return kmem_cache_alloc_trace(kmalloc_caches[index],
 -                                      flags, size);
 -              }
 -      }
 -      return __kmalloc(size, flags);
 -}
 -
 -#ifdef CONFIG_NUMA
 -void *__kmalloc_node(size_t size, gfp_t flags, int node);
 -void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
 -
 -#ifdef CONFIG_TRACING
 -extern void *kmem_cache_alloc_node_trace(struct kmem_cache *s,
 -                                         gfp_t gfpflags,
 -                                         int node, size_t size);
 -#else
 -static __always_inline void *
 -kmem_cache_alloc_node_trace(struct kmem_cache *s,
 -                            gfp_t gfpflags,
 -                            int node, size_t size)
 -{
 -      return kmem_cache_alloc_node(s, gfpflags, node);
 -}
 -#endif
 -
 -static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node)
 -{
 -      if (__builtin_constant_p(size) &&
 -              size <= KMALLOC_MAX_CACHE_SIZE && !(flags & GFP_DMA)) {
 -              int index = kmalloc_index(size);
 -
 -              if (!index)
 -                      return ZERO_SIZE_PTR;
 -
 -              return kmem_cache_alloc_node_trace(kmalloc_caches[index],
 -                             flags, node, size);
 -      }
 -      return __kmalloc_node(size, flags, node);
 -}
 -#endif
 -
  #endif /* _LINUX_SLUB_DEF_H */
diff --combined mm/slab.c
index 0c8967bb201878e567c4d949ae1d9ee57cf04d0b,a983e30843322c37a3ba7983d16a79bd98e9a7ff..eb043bf05f4c57687c0644f11c12bd6b3a654795
+++ b/mm/slab.c
   */
  static bool pfmemalloc_active __read_mostly;
  
- /*
-  * kmem_bufctl_t:
-  *
-  * Bufctl's are used for linking objs within a slab
-  * linked offsets.
-  *
-  * This implementation relies on "struct page" for locating the cache &
-  * slab an object belongs to.
-  * This allows the bufctl structure to be small (one int), but limits
-  * the number of objects a slab (not a cache) can contain when off-slab
-  * bufctls are used. The limit is the size of the largest general cache
-  * that does not use off-slab slabs.
-  * For 32bit archs with 4 kB pages, is this 56.
-  * This is not serious, as it is only for large objects, when it is unwise
-  * to have too many per slab.
-  * Note: This limit can be raised by introducing a general cache whose size
-  * is less than 512 (PAGE_SIZE<<3), but greater than 256.
-  */
- typedef unsigned int kmem_bufctl_t;
- #define BUFCTL_END    (((kmem_bufctl_t)(~0U))-0)
- #define BUFCTL_FREE   (((kmem_bufctl_t)(~0U))-1)
- #define       BUFCTL_ACTIVE   (((kmem_bufctl_t)(~0U))-2)
- #define       SLAB_LIMIT      (((kmem_bufctl_t)(~0U))-3)
- /*
-  * struct slab_rcu
-  *
-  * slab_destroy on a SLAB_DESTROY_BY_RCU cache uses this structure to
-  * arrange for kmem_freepages to be called via RCU.  This is useful if
-  * we need to approach a kernel structure obliquely, from its address
-  * obtained without the usual locking.  We can lock the structure to
-  * stabilize it and check it's still at the given address, only if we
-  * can be sure that the memory has not been meanwhile reused for some
-  * other kind of object (which our subsystem's lock might corrupt).
-  *
-  * rcu_read_lock before reading the address, then rcu_read_unlock after
-  * taking the spinlock within the structure expected at that address.
-  */
- struct slab_rcu {
-       struct rcu_head head;
-       struct kmem_cache *cachep;
-       void *addr;
- };
- /*
-  * struct slab
-  *
-  * Manages the objs in a slab. Placed either at the beginning of mem allocated
-  * for a slab, or allocated from an general cache.
-  * Slabs are chained into three list: fully used, partial, fully free slabs.
-  */
- struct slab {
-       union {
-               struct {
-                       struct list_head list;
-                       unsigned long colouroff;
-                       void *s_mem;            /* including colour offset */
-                       unsigned int inuse;     /* num of objs active in slab */
-                       kmem_bufctl_t free;
-                       unsigned short nodeid;
-               };
-               struct slab_rcu __slab_cover_slab_rcu;
-       };
- };
  /*
   * struct array_cache
   *
@@@ -456,18 -390,10 +390,10 @@@ static inline struct kmem_cache *virt_t
        return page->slab_cache;
  }
  
- static inline struct slab *virt_to_slab(const void *obj)
- {
-       struct page *page = virt_to_head_page(obj);
-       VM_BUG_ON(!PageSlab(page));
-       return page->slab_page;
- }
- static inline void *index_to_obj(struct kmem_cache *cache, struct slab *slab,
+ static inline void *index_to_obj(struct kmem_cache *cache, struct page *page,
                                 unsigned int idx)
  {
-       return slab->s_mem + cache->size * idx;
+       return page->s_mem + cache->size * idx;
  }
  
  /*
   *   reciprocal_divide(offset, cache->reciprocal_buffer_size)
   */
  static inline unsigned int obj_to_index(const struct kmem_cache *cache,
-                                       const struct slab *slab, void *obj)
+                                       const struct page *page, void *obj)
  {
-       u32 offset = (obj - slab->s_mem);
+       u32 offset = (obj - page->s_mem);
        return reciprocal_divide(offset, cache->reciprocal_buffer_size);
  }
  
@@@ -641,7 -567,7 +567,7 @@@ static inline struct array_cache *cpu_c
  
  static size_t slab_mgmt_size(size_t nr_objs, size_t align)
  {
-       return ALIGN(sizeof(struct slab)+nr_objs*sizeof(kmem_bufctl_t), align);
+       return ALIGN(nr_objs * sizeof(unsigned int), align);
  }
  
  /*
@@@ -660,8 -586,7 +586,7 @@@ static void cache_estimate(unsigned lon
         * on it. For the latter case, the memory allocated for a
         * slab is used for:
         *
-        * - The struct slab
-        * - One kmem_bufctl_t for each object
+        * - One unsigned int for each object
         * - Padding to respect alignment of @align
         * - @buffer_size bytes for each object
         *
                mgmt_size = 0;
                nr_objs = slab_size / buffer_size;
  
-               if (nr_objs > SLAB_LIMIT)
-                       nr_objs = SLAB_LIMIT;
        } else {
                /*
                 * Ignore padding for the initial guess. The padding
                 * into the memory allocation when taking the padding
                 * into account.
                 */
-               nr_objs = (slab_size - sizeof(struct slab)) /
-                         (buffer_size + sizeof(kmem_bufctl_t));
+               nr_objs = (slab_size) / (buffer_size + sizeof(unsigned int));
  
                /*
                 * This calculated number will be either the right
                       > slab_size)
                        nr_objs--;
  
-               if (nr_objs > SLAB_LIMIT)
-                       nr_objs = SLAB_LIMIT;
                mgmt_size = slab_mgmt_size(nr_objs, align);
        }
        *num = nr_objs;
@@@ -829,10 -748,8 +748,8 @@@ static struct array_cache *alloc_arrayc
        return nc;
  }
  
- static inline bool is_slab_pfmemalloc(struct slab *slabp)
+ static inline bool is_slab_pfmemalloc(struct page *page)
  {
-       struct page *page = virt_to_page(slabp->s_mem);
        return PageSlabPfmemalloc(page);
  }
  
@@@ -841,23 -758,23 +758,23 @@@ static void recheck_pfmemalloc_active(s
                                                struct array_cache *ac)
  {
        struct kmem_cache_node *n = cachep->node[numa_mem_id()];
-       struct slab *slabp;
+       struct page *page;
        unsigned long flags;
  
        if (!pfmemalloc_active)
                return;
  
        spin_lock_irqsave(&n->list_lock, flags);
-       list_for_each_entry(slabp, &n->slabs_full, list)
-               if (is_slab_pfmemalloc(slabp))
+       list_for_each_entry(page, &n->slabs_full, lru)
+               if (is_slab_pfmemalloc(page))
                        goto out;
  
-       list_for_each_entry(slabp, &n->slabs_partial, list)
-               if (is_slab_pfmemalloc(slabp))
+       list_for_each_entry(page, &n->slabs_partial, lru)
+               if (is_slab_pfmemalloc(page))
                        goto out;
  
-       list_for_each_entry(slabp, &n->slabs_free, list)
-               if (is_slab_pfmemalloc(slabp))
+       list_for_each_entry(page, &n->slabs_free, lru)
+               if (is_slab_pfmemalloc(page))
                        goto out;
  
        pfmemalloc_active = false;
@@@ -897,8 -814,8 +814,8 @@@ static void *__ac_get_obj(struct kmem_c
                 */
                n = cachep->node[numa_mem_id()];
                if (!list_empty(&n->slabs_free) && force_refill) {
-                       struct slab *slabp = virt_to_slab(objp);
-                       ClearPageSlabPfmemalloc(virt_to_head_page(slabp->s_mem));
+                       struct page *page = virt_to_head_page(objp);
+                       ClearPageSlabPfmemalloc(page);
                        clear_obj_pfmemalloc(&objp);
                        recheck_pfmemalloc_active(cachep, ac);
                        return objp;
@@@ -1099,8 -1016,7 +1016,7 @@@ static void drain_alien_cache(struct km
  
  static inline int cache_free_alien(struct kmem_cache *cachep, void *objp)
  {
-       struct slab *slabp = virt_to_slab(objp);
-       int nodeid = slabp->nodeid;
+       int nodeid = page_to_nid(virt_to_page(objp));
        struct kmem_cache_node *n;
        struct array_cache *alien = NULL;
        int node;
         * Make sure we are not freeing a object from another node to the array
         * cache on this cpu.
         */
-       if (likely(slabp->nodeid == node))
+       if (likely(nodeid == node))
                return 0;
  
        n = cachep->node[node];
@@@ -1512,6 -1428,8 +1428,8 @@@ void __init kmem_cache_init(void
  {
        int i;
  
+       BUILD_BUG_ON(sizeof(((struct page *)NULL)->lru) <
+                                       sizeof(struct rcu_head));
        kmem_cache = &kmem_cache_boot;
        setup_node_pointer(kmem_cache);
  
@@@ -1687,7 -1605,7 +1605,7 @@@ static noinline voi
  slab_out_of_memory(struct kmem_cache *cachep, gfp_t gfpflags, int nodeid)
  {
        struct kmem_cache_node *n;
-       struct slab *slabp;
+       struct page *page;
        unsigned long flags;
        int node;
  
                        continue;
  
                spin_lock_irqsave(&n->list_lock, flags);
-               list_for_each_entry(slabp, &n->slabs_full, list) {
+               list_for_each_entry(page, &n->slabs_full, lru) {
                        active_objs += cachep->num;
                        active_slabs++;
                }
-               list_for_each_entry(slabp, &n->slabs_partial, list) {
-                       active_objs += slabp->inuse;
+               list_for_each_entry(page, &n->slabs_partial, lru) {
+                       active_objs += page->active;
                        active_slabs++;
                }
-               list_for_each_entry(slabp, &n->slabs_free, list)
+               list_for_each_entry(page, &n->slabs_free, lru)
                        num_slabs++;
  
                free_objects += n->free_objects;
   * did not request dmaable memory, we might get it, but that
   * would be relatively rare and ignorable.
   */
- static void *kmem_getpages(struct kmem_cache *cachep, gfp_t flags, int nodeid)
+ static struct page *kmem_getpages(struct kmem_cache *cachep, gfp_t flags,
+                                                               int nodeid)
  {
        struct page *page;
        int nr_pages;
-       int i;
- #ifndef CONFIG_MMU
-       /*
-        * Nommu uses slab's for process anonymous memory allocations, and thus
-        * requires __GFP_COMP to properly refcount higher order allocations
-        */
-       flags |= __GFP_COMP;
- #endif
  
        flags |= cachep->allocflags;
        if (cachep->flags & SLAB_RECLAIM_ACCOUNT)
        else
                add_zone_page_state(page_zone(page),
                        NR_SLAB_UNRECLAIMABLE, nr_pages);
-       for (i = 0; i < nr_pages; i++) {
-               __SetPageSlab(page + i);
-               if (page->pfmemalloc)
-                       SetPageSlabPfmemalloc(page + i);
-       }
+       __SetPageSlab(page);
+       if (page->pfmemalloc)
+               SetPageSlabPfmemalloc(page);
        memcg_bind_pages(cachep, cachep->gfporder);
  
        if (kmemcheck_enabled && !(cachep->flags & SLAB_NOTRACK)) {
                        kmemcheck_mark_unallocated_pages(page, nr_pages);
        }
  
-       return page_address(page);
+       return page;
  }
  
  /*
   * Interface to system's page release.
   */
- static void kmem_freepages(struct kmem_cache *cachep, void *addr)
+ static void kmem_freepages(struct kmem_cache *cachep, struct page *page)
  {
-       unsigned long i = (1 << cachep->gfporder);
-       struct page *page = virt_to_page(addr);
-       const unsigned long nr_freed = i;
+       const unsigned long nr_freed = (1 << cachep->gfporder);
  
        kmemcheck_free_shadow(page, cachep->gfporder);
  
        else
                sub_zone_page_state(page_zone(page),
                                NR_SLAB_UNRECLAIMABLE, nr_freed);
-       while (i--) {
-               BUG_ON(!PageSlab(page));
-               __ClearPageSlabPfmemalloc(page);
-               __ClearPageSlab(page);
-               page++;
-       }
+       BUG_ON(!PageSlab(page));
+       __ClearPageSlabPfmemalloc(page);
+       __ClearPageSlab(page);
+       page_mapcount_reset(page);
+       page->mapping = NULL;
  
        memcg_release_pages(cachep, cachep->gfporder);
        if (current->reclaim_state)
                current->reclaim_state->reclaimed_slab += nr_freed;
-       free_memcg_kmem_pages((unsigned long)addr, cachep->gfporder);
+       __free_memcg_kmem_pages(page, cachep->gfporder);
  }
  
  static void kmem_rcu_free(struct rcu_head *head)
  {
-       struct slab_rcu *slab_rcu = (struct slab_rcu *)head;
-       struct kmem_cache *cachep = slab_rcu->cachep;
+       struct kmem_cache *cachep;
+       struct page *page;
  
-       kmem_freepages(cachep, slab_rcu->addr);
-       if (OFF_SLAB(cachep))
-               kmem_cache_free(cachep->slabp_cache, slab_rcu);
+       page = container_of(head, struct page, rcu_head);
+       cachep = page->slab_cache;
+       kmem_freepages(cachep, page);
  }
  
  #if DEBUG
@@@ -1978,19 -1884,19 +1884,19 @@@ static void check_poison_obj(struct kme
                /* Print some data about the neighboring objects, if they
                 * exist:
                 */
-               struct slab *slabp = virt_to_slab(objp);
+               struct page *page = virt_to_head_page(objp);
                unsigned int objnr;
  
-               objnr = obj_to_index(cachep, slabp, objp);
+               objnr = obj_to_index(cachep, page, objp);
                if (objnr) {
-                       objp = index_to_obj(cachep, slabp, objnr - 1);
+                       objp = index_to_obj(cachep, page, objnr - 1);
                        realobj = (char *)objp + obj_offset(cachep);
                        printk(KERN_ERR "Prev obj: start=%p, len=%d\n",
                               realobj, size);
                        print_objinfo(cachep, objp, 2);
                }
                if (objnr + 1 < cachep->num) {
-                       objp = index_to_obj(cachep, slabp, objnr + 1);
+                       objp = index_to_obj(cachep, page, objnr + 1);
                        realobj = (char *)objp + obj_offset(cachep);
                        printk(KERN_ERR "Next obj: start=%p, len=%d\n",
                               realobj, size);
  #endif
  
  #if DEBUG
- static void slab_destroy_debugcheck(struct kmem_cache *cachep, struct slab *slabp)
+ static void slab_destroy_debugcheck(struct kmem_cache *cachep,
+                                               struct page *page)
  {
        int i;
        for (i = 0; i < cachep->num; i++) {
-               void *objp = index_to_obj(cachep, slabp, i);
+               void *objp = index_to_obj(cachep, page, i);
  
                if (cachep->flags & SLAB_POISON) {
  #ifdef CONFIG_DEBUG_PAGEALLOC
        }
  }
  #else
- static void slab_destroy_debugcheck(struct kmem_cache *cachep, struct slab *slabp)
+ static void slab_destroy_debugcheck(struct kmem_cache *cachep,
+                                               struct page *page)
  {
  }
  #endif
   * Before calling the slab must have been unlinked from the cache.  The
   * cache-lock is not held/needed.
   */
- static void slab_destroy(struct kmem_cache *cachep, struct slab *slabp)
+ static void slab_destroy(struct kmem_cache *cachep, struct page *page)
  {
-       void *addr = slabp->s_mem - slabp->colouroff;
+       void *freelist;
  
-       slab_destroy_debugcheck(cachep, slabp);
+       freelist = page->freelist;
+       slab_destroy_debugcheck(cachep, page);
        if (unlikely(cachep->flags & SLAB_DESTROY_BY_RCU)) {
-               struct slab_rcu *slab_rcu;
+               struct rcu_head *head;
+               /*
+                * RCU free overloads the RCU head over the LRU.
+                * slab_page has been overloeaded over the LRU,
+                * however it is not used from now on so that
+                * we can use it safely.
+                */
+               head = (void *)&page->rcu_head;
+               call_rcu(head, kmem_rcu_free);
  
-               slab_rcu = (struct slab_rcu *)slabp;
-               slab_rcu->cachep = cachep;
-               slab_rcu->addr = addr;
-               call_rcu(&slab_rcu->head, kmem_rcu_free);
        } else {
-               kmem_freepages(cachep, addr);
-               if (OFF_SLAB(cachep))
-                       kmem_cache_free(cachep->slabp_cache, slabp);
+               kmem_freepages(cachep, page);
        }
+       /*
+        * From now on, we don't use freelist
+        * although actual page can be freed in rcu context
+        */
+       if (OFF_SLAB(cachep))
+               kmem_cache_free(cachep->freelist_cache, freelist);
  }
  
  /**
@@@ -2097,8 -2016,8 +2016,8 @@@ static size_t calculate_slab_order(stru
                         * use off-slab slabs. Needed to avoid a possible
                         * looping condition in cache_grow().
                         */
-                       offslab_limit = size - sizeof(struct slab);
-                       offslab_limit /= sizeof(kmem_bufctl_t);
+                       offslab_limit = size;
+                       offslab_limit /= sizeof(unsigned int);
  
                        if (num > offslab_limit)
                                break;
@@@ -2220,7 -2139,7 +2139,7 @@@ static int __init_refok setup_cpu_cache
  int
  __kmem_cache_create (struct kmem_cache *cachep, unsigned long flags)
  {
-       size_t left_over, slab_size, ralign;
+       size_t left_over, freelist_size, ralign;
        gfp_t gfp;
        int err;
        size_t size = cachep->size;
        if (!cachep->num)
                return -E2BIG;
  
-       slab_size = ALIGN(cachep->num * sizeof(kmem_bufctl_t)
-                         + sizeof(struct slab), cachep->align);
+       freelist_size =
+               ALIGN(cachep->num * sizeof(unsigned int), cachep->align);
  
        /*
         * If the slab has been placed off-slab, and we have enough space then
         * move it on-slab. This is at the expense of any extra colouring.
         */
-       if (flags & CFLGS_OFF_SLAB && left_over >= slab_size) {
+       if (flags & CFLGS_OFF_SLAB && left_over >= freelist_size) {
                flags &= ~CFLGS_OFF_SLAB;
-               left_over -= slab_size;
+               left_over -= freelist_size;
        }
  
        if (flags & CFLGS_OFF_SLAB) {
                /* really off slab. No need for manual alignment */
-               slab_size =
-                   cachep->num * sizeof(kmem_bufctl_t) + sizeof(struct slab);
+               freelist_size = cachep->num * sizeof(unsigned int);
  
  #ifdef CONFIG_PAGE_POISONING
                /* If we're going to use the generic kernel_map_pages()
        if (cachep->colour_off < cachep->align)
                cachep->colour_off = cachep->align;
        cachep->colour = left_over / cachep->colour_off;
-       cachep->slab_size = slab_size;
+       cachep->freelist_size = freelist_size;
        cachep->flags = flags;
-       cachep->allocflags = 0;
+       cachep->allocflags = __GFP_COMP;
        if (CONFIG_ZONE_DMA_FLAG && (flags & SLAB_CACHE_DMA))
                cachep->allocflags |= GFP_DMA;
        cachep->size = size;
        cachep->reciprocal_buffer_size = reciprocal_value(size);
  
        if (flags & CFLGS_OFF_SLAB) {
-               cachep->slabp_cache = kmalloc_slab(slab_size, 0u);
+               cachep->freelist_cache = kmalloc_slab(freelist_size, 0u);
                /*
                 * This is a possibility for one of the malloc_sizes caches.
                 * But since we go off slab only for object size greater than
                 * this should not happen at all.
                 * But leave a BUG_ON for some lucky dude.
                 */
-               BUG_ON(ZERO_OR_NULL_PTR(cachep->slabp_cache));
+               BUG_ON(ZERO_OR_NULL_PTR(cachep->freelist_cache));
        }
  
        err = setup_cpu_cache(cachep, gfp);
@@@ -2494,7 -2412,7 +2412,7 @@@ static int drain_freelist(struct kmem_c
  {
        struct list_head *p;
        int nr_freed;
-       struct slab *slabp;
+       struct page *page;
  
        nr_freed = 0;
        while (nr_freed < tofree && !list_empty(&n->slabs_free)) {
                        goto out;
                }
  
-               slabp = list_entry(p, struct slab, list);
+               page = list_entry(p, struct page, lru);
  #if DEBUG
-               BUG_ON(slabp->inuse);
+               BUG_ON(page->active);
  #endif
-               list_del(&slabp->list);
+               list_del(&page->lru);
                /*
                 * Safe to drop the lock. The slab is no longer linked
                 * to the cache.
                 */
                n->free_objects -= cache->num;
                spin_unlock_irq(&n->list_lock);
-               slab_destroy(cache, slabp);
+               slab_destroy(cache, page);
                nr_freed++;
        }
  out:
@@@ -2600,52 -2518,42 +2518,42 @@@ int __kmem_cache_shutdown(struct kmem_c
   * descriptors in kmem_cache_create, we search through the malloc_sizes array.
   * If we are creating a malloc_sizes cache here it would not be visible to
   * kmem_find_general_cachep till the initialization is complete.
-  * Hence we cannot have slabp_cache same as the original cache.
+  * Hence we cannot have freelist_cache same as the original cache.
   */
- static struct slab *alloc_slabmgmt(struct kmem_cache *cachep, void *objp,
-                                  int colour_off, gfp_t local_flags,
-                                  int nodeid)
+ static void *alloc_slabmgmt(struct kmem_cache *cachep,
+                                  struct page *page, int colour_off,
+                                  gfp_t local_flags, int nodeid)
  {
-       struct slab *slabp;
+       void *freelist;
+       void *addr = page_address(page);
  
        if (OFF_SLAB(cachep)) {
                /* Slab management obj is off-slab. */
-               slabp = kmem_cache_alloc_node(cachep->slabp_cache,
+               freelist = kmem_cache_alloc_node(cachep->freelist_cache,
                                              local_flags, nodeid);
-               /*
-                * If the first object in the slab is leaked (it's allocated
-                * but no one has a reference to it), we want to make sure
-                * kmemleak does not treat the ->s_mem pointer as a reference
-                * to the object. Otherwise we will not report the leak.
-                */
-               kmemleak_scan_area(&slabp->list, sizeof(struct list_head),
-                                  local_flags);
-               if (!slabp)
+               if (!freelist)
                        return NULL;
        } else {
-               slabp = objp + colour_off;
-               colour_off += cachep->slab_size;
+               freelist = addr + colour_off;
+               colour_off += cachep->freelist_size;
        }
-       slabp->inuse = 0;
-       slabp->colouroff = colour_off;
-       slabp->s_mem = objp + colour_off;
-       slabp->nodeid = nodeid;
-       slabp->free = 0;
-       return slabp;
+       page->active = 0;
+       page->s_mem = addr + colour_off;
+       return freelist;
  }
  
- static inline kmem_bufctl_t *slab_bufctl(struct slab *slabp)
+ static inline unsigned int *slab_freelist(struct page *page)
  {
-       return (kmem_bufctl_t *) (slabp + 1);
+       return (unsigned int *)(page->freelist);
  }
  
  static void cache_init_objs(struct kmem_cache *cachep,
-                           struct slab *slabp)
+                           struct page *page)
  {
        int i;
  
        for (i = 0; i < cachep->num; i++) {
-               void *objp = index_to_obj(cachep, slabp, i);
+               void *objp = index_to_obj(cachep, page, i);
  #if DEBUG
                /* need to poison the objs? */
                if (cachep->flags & SLAB_POISON)
                if (cachep->ctor)
                        cachep->ctor(objp);
  #endif
-               slab_bufctl(slabp)[i] = i + 1;
+               slab_freelist(page)[i] = i;
        }
-       slab_bufctl(slabp)[i - 1] = BUFCTL_END;
  }
  
  static void kmem_flagcheck(struct kmem_cache *cachep, gfp_t flags)
        }
  }
  
- static void *slab_get_obj(struct kmem_cache *cachep, struct slab *slabp,
+ static void *slab_get_obj(struct kmem_cache *cachep, struct page *page,
                                int nodeid)
  {
-       void *objp = index_to_obj(cachep, slabp, slabp->free);
-       kmem_bufctl_t next;
+       void *objp;
  
-       slabp->inuse++;
-       next = slab_bufctl(slabp)[slabp->free];
+       objp = index_to_obj(cachep, page, slab_freelist(page)[page->active]);
+       page->active++;
  #if DEBUG
-       slab_bufctl(slabp)[slabp->free] = BUFCTL_FREE;
-       WARN_ON(slabp->nodeid != nodeid);
+       WARN_ON(page_to_nid(virt_to_page(objp)) != nodeid);
  #endif
-       slabp->free = next;
  
        return objp;
  }
  
- static void slab_put_obj(struct kmem_cache *cachep, struct slab *slabp,
+ static void slab_put_obj(struct kmem_cache *cachep, struct page *page,
                                void *objp, int nodeid)
  {
-       unsigned int objnr = obj_to_index(cachep, slabp, objp);
+       unsigned int objnr = obj_to_index(cachep, page, objp);
  #if DEBUG
+       unsigned int i;
        /* Verify that the slab belongs to the intended node */
-       WARN_ON(slabp->nodeid != nodeid);
+       WARN_ON(page_to_nid(virt_to_page(objp)) != nodeid);
  
-       if (slab_bufctl(slabp)[objnr] + 1 <= SLAB_LIMIT + 1) {
-               printk(KERN_ERR "slab: double free detected in cache "
-                               "'%s', objp %p\n", cachep->name, objp);
-               BUG();
+       /* Verify double free bug */
+       for (i = page->active; i < cachep->num; i++) {
+               if (slab_freelist(page)[i] == objnr) {
+                       printk(KERN_ERR "slab: double free detected in cache "
+                                       "'%s', objp %p\n", cachep->name, objp);
+                       BUG();
+               }
        }
  #endif
-       slab_bufctl(slabp)[objnr] = slabp->free;
-       slabp->free = objnr;
-       slabp->inuse--;
+       page->active--;
+       slab_freelist(page)[page->active] = objnr;
  }
  
  /*
   * for the slab allocator to be able to lookup the cache and slab of a
   * virtual address for kfree, ksize, and slab debugging.
   */
- static void slab_map_pages(struct kmem_cache *cache, struct slab *slab,
-                          void *addr)
+ static void slab_map_pages(struct kmem_cache *cache, struct page *page,
+                          void *freelist)
  {
-       int nr_pages;
-       struct page *page;
-       page = virt_to_page(addr);
-       nr_pages = 1;
-       if (likely(!PageCompound(page)))
-               nr_pages <<= cache->gfporder;
-       do {
-               page->slab_cache = cache;
-               page->slab_page = slab;
-               page++;
-       } while (--nr_pages);
+       page->slab_cache = cache;
+       page->freelist = freelist;
  }
  
  /*
   * kmem_cache_alloc() when there are no active objs left in a cache.
   */
  static int cache_grow(struct kmem_cache *cachep,
-               gfp_t flags, int nodeid, void *objp)
+               gfp_t flags, int nodeid, struct page *page)
  {
-       struct slab *slabp;
+       void *freelist;
        size_t offset;
        gfp_t local_flags;
        struct kmem_cache_node *n;
         * Get mem for the objs.  Attempt to allocate a physical page from
         * 'nodeid'.
         */
-       if (!objp)
-               objp = kmem_getpages(cachep, local_flags, nodeid);
-       if (!objp)
+       if (!page)
+               page = kmem_getpages(cachep, local_flags, nodeid);
+       if (!page)
                goto failed;
  
        /* Get slab management. */
-       slabp = alloc_slabmgmt(cachep, objp, offset,
+       freelist = alloc_slabmgmt(cachep, page, offset,
                        local_flags & ~GFP_CONSTRAINT_MASK, nodeid);
-       if (!slabp)
+       if (!freelist)
                goto opps1;
  
-       slab_map_pages(cachep, slabp, objp);
+       slab_map_pages(cachep, page, freelist);
  
-       cache_init_objs(cachep, slabp);
+       cache_init_objs(cachep, page);
  
        if (local_flags & __GFP_WAIT)
                local_irq_disable();
        spin_lock(&n->list_lock);
  
        /* Make slab active. */
-       list_add_tail(&slabp->list, &(n->slabs_free));
+       list_add_tail(&page->lru, &(n->slabs_free));
        STATS_INC_GROWN(cachep);
        n->free_objects += cachep->num;
        spin_unlock(&n->list_lock);
        return 1;
  opps1:
-       kmem_freepages(cachep, objp);
+       kmem_freepages(cachep, page);
  failed:
        if (local_flags & __GFP_WAIT)
                local_irq_disable();
@@@ -2880,9 -2775,8 +2775,8 @@@ static inline void verify_redzone_free(
  static void *cache_free_debugcheck(struct kmem_cache *cachep, void *objp,
                                   unsigned long caller)
  {
-       struct page *page;
        unsigned int objnr;
-       struct slab *slabp;
+       struct page *page;
  
        BUG_ON(virt_to_cache(objp) != cachep);
  
        kfree_debugcheck(objp);
        page = virt_to_head_page(objp);
  
-       slabp = page->slab_page;
        if (cachep->flags & SLAB_RED_ZONE) {
                verify_redzone_free(cachep, objp);
                *dbg_redzone1(cachep, objp) = RED_INACTIVE;
        if (cachep->flags & SLAB_STORE_USER)
                *dbg_userword(cachep, objp) = (void *)caller;
  
-       objnr = obj_to_index(cachep, slabp, objp);
+       objnr = obj_to_index(cachep, page, objp);
  
        BUG_ON(objnr >= cachep->num);
-       BUG_ON(objp != index_to_obj(cachep, slabp, objnr));
+       BUG_ON(objp != index_to_obj(cachep, page, objnr));
  
- #ifdef CONFIG_DEBUG_SLAB_LEAK
-       slab_bufctl(slabp)[objnr] = BUFCTL_FREE;
- #endif
        if (cachep->flags & SLAB_POISON) {
  #ifdef CONFIG_DEBUG_PAGEALLOC
                if ((cachep->size % PAGE_SIZE)==0 && OFF_SLAB(cachep)) {
        return objp;
  }
  
- static void check_slabp(struct kmem_cache *cachep, struct slab *slabp)
- {
-       kmem_bufctl_t i;
-       int entries = 0;
-       /* Check slab's freelist to see if this obj is there. */
-       for (i = slabp->free; i != BUFCTL_END; i = slab_bufctl(slabp)[i]) {
-               entries++;
-               if (entries > cachep->num || i >= cachep->num)
-                       goto bad;
-       }
-       if (entries != cachep->num - slabp->inuse) {
- bad:
-               printk(KERN_ERR "slab: Internal list corruption detected in "
-                       "cache '%s'(%d), slabp %p(%d). Tainted(%s). Hexdump:\n",
-                       cachep->name, cachep->num, slabp, slabp->inuse,
-                       print_tainted());
-               print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 16, 1, slabp,
-                       sizeof(*slabp) + cachep->num * sizeof(kmem_bufctl_t),
-                       1);
-               BUG();
-       }
- }
  #else
  #define kfree_debugcheck(x) do { } while(0)
  #define cache_free_debugcheck(x,objp,z) (objp)
- #define check_slabp(x,y) do { } while(0)
  #endif
  
  static void *cache_alloc_refill(struct kmem_cache *cachep, gfp_t flags,
@@@ -2989,7 -2854,7 +2854,7 @@@ retry
  
        while (batchcount > 0) {
                struct list_head *entry;
-               struct slab *slabp;
+               struct page *page;
                /* Get slab alloc is to come from. */
                entry = n->slabs_partial.next;
                if (entry == &n->slabs_partial) {
                                goto must_grow;
                }
  
-               slabp = list_entry(entry, struct slab, list);
-               check_slabp(cachep, slabp);
+               page = list_entry(entry, struct page, lru);
                check_spinlock_acquired(cachep);
  
                /*
                 * there must be at least one object available for
                 * allocation.
                 */
-               BUG_ON(slabp->inuse >= cachep->num);
+               BUG_ON(page->active >= cachep->num);
  
-               while (slabp->inuse < cachep->num && batchcount--) {
+               while (page->active < cachep->num && batchcount--) {
                        STATS_INC_ALLOCED(cachep);
                        STATS_INC_ACTIVE(cachep);
                        STATS_SET_HIGH(cachep);
  
-                       ac_put_obj(cachep, ac, slab_get_obj(cachep, slabp,
+                       ac_put_obj(cachep, ac, slab_get_obj(cachep, page,
                                                                        node));
                }
-               check_slabp(cachep, slabp);
  
                /* move slabp to correct slabp list: */
-               list_del(&slabp->list);
-               if (slabp->free == BUFCTL_END)
-                       list_add(&slabp->list, &n->slabs_full);
+               list_del(&page->lru);
+               if (page->active == cachep->num)
+                       list_add(&page->list, &n->slabs_full);
                else
-                       list_add(&slabp->list, &n->slabs_partial);
+                       list_add(&page->list, &n->slabs_partial);
        }
  
  must_grow:
@@@ -3097,16 -2960,6 +2960,6 @@@ static void *cache_alloc_debugcheck_aft
                *dbg_redzone1(cachep, objp) = RED_ACTIVE;
                *dbg_redzone2(cachep, objp) = RED_ACTIVE;
        }
- #ifdef CONFIG_DEBUG_SLAB_LEAK
-       {
-               struct slab *slabp;
-               unsigned objnr;
-               slabp = virt_to_head_page(objp)->slab_page;
-               objnr = (unsigned)(objp - slabp->s_mem) / cachep->size;
-               slab_bufctl(slabp)[objnr] = BUFCTL_ACTIVE;
-       }
- #endif
        objp += obj_offset(cachep);
        if (cachep->ctor && cachep->flags & SLAB_POISON)
                cachep->ctor(objp);
@@@ -3248,18 -3101,20 +3101,20 @@@ retry
                 * We may trigger various forms of reclaim on the allowed
                 * set and go into memory reserves if necessary.
                 */
+               struct page *page;
                if (local_flags & __GFP_WAIT)
                        local_irq_enable();
                kmem_flagcheck(cache, flags);
-               obj = kmem_getpages(cache, local_flags, numa_mem_id());
+               page = kmem_getpages(cache, local_flags, numa_mem_id());
                if (local_flags & __GFP_WAIT)
                        local_irq_disable();
-               if (obj) {
+               if (page) {
                        /*
                         * Insert into the appropriate per node queues
                         */
-                       nid = page_to_nid(virt_to_page(obj));
-                       if (cache_grow(cache, flags, nid, obj)) {
+                       nid = page_to_nid(page);
+                       if (cache_grow(cache, flags, nid, page)) {
                                obj = ____cache_alloc_node(cache,
                                        flags | GFP_THISNODE, nid);
                                if (!obj)
@@@ -3288,7 -3143,7 +3143,7 @@@ static void *____cache_alloc_node(struc
                                int nodeid)
  {
        struct list_head *entry;
-       struct slab *slabp;
+       struct page *page;
        struct kmem_cache_node *n;
        void *obj;
        int x;
@@@ -3308,26 -3163,24 +3163,24 @@@ retry
                        goto must_grow;
        }
  
-       slabp = list_entry(entry, struct slab, list);
+       page = list_entry(entry, struct page, lru);
        check_spinlock_acquired_node(cachep, nodeid);
-       check_slabp(cachep, slabp);
  
        STATS_INC_NODEALLOCS(cachep);
        STATS_INC_ACTIVE(cachep);
        STATS_SET_HIGH(cachep);
  
-       BUG_ON(slabp->inuse == cachep->num);
+       BUG_ON(page->active == cachep->num);
  
-       obj = slab_get_obj(cachep, slabp, nodeid);
-       check_slabp(cachep, slabp);
+       obj = slab_get_obj(cachep, page, nodeid);
        n->free_objects--;
        /* move slabp to correct slabp list: */
-       list_del(&slabp->list);
+       list_del(&page->lru);
  
-       if (slabp->free == BUFCTL_END)
-               list_add(&slabp->list, &n->slabs_full);
+       if (page->active == cachep->num)
+               list_add(&page->lru, &n->slabs_full);
        else
-               list_add(&slabp->list, &n->slabs_partial);
+               list_add(&page->lru, &n->slabs_partial);
  
        spin_unlock(&n->list_lock);
        goto done;
@@@ -3477,23 -3330,21 +3330,21 @@@ static void free_block(struct kmem_cach
  
        for (i = 0; i < nr_objects; i++) {
                void *objp;
-               struct slab *slabp;
+               struct page *page;
  
                clear_obj_pfmemalloc(&objpp[i]);
                objp = objpp[i];
  
-               slabp = virt_to_slab(objp);
+               page = virt_to_head_page(objp);
                n = cachep->node[node];
-               list_del(&slabp->list);
+               list_del(&page->lru);
                check_spinlock_acquired_node(cachep, node);
-               check_slabp(cachep, slabp);
-               slab_put_obj(cachep, slabp, objp, node);
+               slab_put_obj(cachep, page, objp, node);
                STATS_DEC_ACTIVE(cachep);
                n->free_objects++;
-               check_slabp(cachep, slabp);
  
                /* fixup slab chains */
-               if (slabp->inuse == 0) {
+               if (page->active == 0) {
                        if (n->free_objects > n->free_limit) {
                                n->free_objects -= cachep->num;
                                /* No need to drop any previously held
                                 * a different cache, refer to comments before
                                 * alloc_slabmgmt.
                                 */
-                               slab_destroy(cachep, slabp);
+                               slab_destroy(cachep, page);
                        } else {
-                               list_add(&slabp->list, &n->slabs_free);
+                               list_add(&page->lru, &n->slabs_free);
                        }
                } else {
                        /* Unconditionally move a slab to the end of the
                         * partial list on free - maximum time for the
                         * other objects to be freed, too.
                         */
-                       list_add_tail(&slabp->list, &n->slabs_partial);
+                       list_add_tail(&page->lru, &n->slabs_partial);
                }
        }
  }
@@@ -3551,10 -3402,10 +3402,10 @@@ free_done
  
                p = n->slabs_free.next;
                while (p != &(n->slabs_free)) {
-                       struct slab *slabp;
+                       struct page *page;
  
-                       slabp = list_entry(p, struct slab, list);
-                       BUG_ON(slabp->inuse);
+                       page = list_entry(p, struct page, lru);
+                       BUG_ON(page->active);
  
                        i++;
                        p = p->next;
@@@ -3982,7 -3833,7 +3833,7 @@@ static int do_tune_cpucache(struct kmem
  
        VM_BUG_ON(!mutex_is_locked(&slab_mutex));
        for_each_memcg_cache_index(i) {
 -              c = cache_from_memcg(cachep, i);
 +              c = cache_from_memcg_idx(cachep, i);
                if (c)
                        /* return value determined by the parent cache only */
                        __do_tune_cpucache(c, limit, batchcount, shared, gfp);
@@@ -4158,7 -4009,7 +4009,7 @@@ out
  #ifdef CONFIG_SLABINFO
  void get_slabinfo(struct kmem_cache *cachep, struct slabinfo *sinfo)
  {
-       struct slab *slabp;
+       struct page *page;
        unsigned long active_objs;
        unsigned long num_objs;
        unsigned long active_slabs = 0;
                check_irq_on();
                spin_lock_irq(&n->list_lock);
  
-               list_for_each_entry(slabp, &n->slabs_full, list) {
-                       if (slabp->inuse != cachep->num && !error)
+               list_for_each_entry(page, &n->slabs_full, lru) {
+                       if (page->active != cachep->num && !error)
                                error = "slabs_full accounting error";
                        active_objs += cachep->num;
                        active_slabs++;
                }
-               list_for_each_entry(slabp, &n->slabs_partial, list) {
-                       if (slabp->inuse == cachep->num && !error)
-                               error = "slabs_partial inuse accounting error";
-                       if (!slabp->inuse && !error)
-                               error = "slabs_partial/inuse accounting error";
-                       active_objs += slabp->inuse;
+               list_for_each_entry(page, &n->slabs_partial, lru) {
+                       if (page->active == cachep->num && !error)
+                               error = "slabs_partial accounting error";
+                       if (!page->active && !error)
+                               error = "slabs_partial accounting error";
+                       active_objs += page->active;
                        active_slabs++;
                }
-               list_for_each_entry(slabp, &n->slabs_free, list) {
-                       if (slabp->inuse && !error)
-                               error = "slabs_free/inuse accounting error";
+               list_for_each_entry(page, &n->slabs_free, lru) {
+                       if (page->active && !error)
+                               error = "slabs_free accounting error";
                        num_slabs++;
                }
                free_objects += n->free_objects;
@@@ -4346,15 -4197,27 +4197,27 @@@ static inline int add_caller(unsigned l
        return 1;
  }
  
- static void handle_slab(unsigned long *n, struct kmem_cache *c, struct slab *s)
+ static void handle_slab(unsigned long *n, struct kmem_cache *c,
+                                               struct page *page)
  {
        void *p;
-       int i;
+       int i, j;
        if (n[0] == n[1])
                return;
-       for (i = 0, p = s->s_mem; i < c->num; i++, p += c->size) {
-               if (slab_bufctl(s)[i] != BUFCTL_ACTIVE)
+       for (i = 0, p = page->s_mem; i < c->num; i++, p += c->size) {
+               bool active = true;
+               for (j = page->active; j < c->num; j++) {
+                       /* Skip freed item */
+                       if (slab_freelist(page)[j] == i) {
+                               active = false;
+                               break;
+                       }
+               }
+               if (!active)
                        continue;
                if (!add_caller(n, (unsigned long)*dbg_userword(c, p)))
                        return;
        }
@@@ -4379,7 -4242,7 +4242,7 @@@ static void show_symbol(struct seq_fil
  static int leaks_show(struct seq_file *m, void *p)
  {
        struct kmem_cache *cachep = list_entry(p, struct kmem_cache, list);
-       struct slab *slabp;
+       struct page *page;
        struct kmem_cache_node *n;
        const char *name;
        unsigned long *x = m->private;
                check_irq_on();
                spin_lock_irq(&n->list_lock);
  
-               list_for_each_entry(slabp, &n->slabs_full, list)
-                       handle_slab(x, cachep, slabp);
-               list_for_each_entry(slabp, &n->slabs_partial, list)
-                       handle_slab(x, cachep, slabp);
+               list_for_each_entry(page, &n->slabs_full, lru)
+                       handle_slab(x, cachep, page);
+               list_for_each_entry(page, &n->slabs_partial, lru)
+                       handle_slab(x, cachep, page);
                spin_unlock_irq(&n->list_lock);
        }
        name = cachep->name;
diff --combined mm/slub.c
index 7e8bd8d828bc0e5c7e96919c6e24186d8d5382df,1ee14acb3bdacb71adc0c6a4ff26a1a13eec1a94..545a170ebf9f66cf0e3716c9cd6f4cb7eef0eda6
+++ b/mm/slub.c
@@@ -155,7 -155,7 +155,7 @@@ static inline bool kmem_cache_has_cpu_p
  /*
   * Maximum number of desirable partial slabs.
   * The existence of more partial slabs makes kmem_cache_shrink
-  * sort the partial list by the number of objects in the.
+  * sort the partial list by the number of objects in use.
   */
  #define MAX_PARTIAL 10
  
@@@ -373,8 -373,7 +373,8 @@@ static inline bool __cmpxchg_double_sla
  #endif
        {
                slab_lock(page);
 -              if (page->freelist == freelist_old && page->counters == counters_old) {
 +              if (page->freelist == freelist_old &&
 +                                      page->counters == counters_old) {
                        page->freelist = freelist_new;
                        page->counters = counters_new;
                        slab_unlock(page);
@@@ -412,8 -411,7 +412,8 @@@ static inline bool cmpxchg_double_slab(
  
                local_irq_save(flags);
                slab_lock(page);
 -              if (page->freelist == freelist_old && page->counters == counters_old) {
 +              if (page->freelist == freelist_old &&
 +                                      page->counters == counters_old) {
                        page->freelist = freelist_new;
                        page->counters = counters_new;
                        slab_unlock(page);
@@@ -555,9 -553,8 +555,9 @@@ static void print_tracking(struct kmem_
  
  static void print_page_info(struct page *page)
  {
 -      printk(KERN_ERR "INFO: Slab 0x%p objects=%u used=%u fp=0x%p flags=0x%04lx\n",
 -              page, page->objects, page->inuse, page->freelist, page->flags);
 +      printk(KERN_ERR
 +             "INFO: Slab 0x%p objects=%u used=%u fp=0x%p flags=0x%04lx\n",
 +             page, page->objects, page->inuse, page->freelist, page->flags);
  
  }
  
@@@ -632,8 -629,7 +632,8 @@@ static void object_err(struct kmem_cach
        print_trailer(s, page, object);
  }
  
 -static void slab_err(struct kmem_cache *s, struct page *page, const char *fmt, ...)
 +static void slab_err(struct kmem_cache *s, struct page *page,
 +                      const char *fmt, ...)
  {
        va_list args;
        char buf[100];
@@@ -792,8 -788,7 +792,8 @@@ static int check_object(struct kmem_cac
        } else {
                if ((s->flags & SLAB_POISON) && s->object_size < s->inuse) {
                        check_bytes_and_report(s, page, p, "Alignment padding",
 -                              endobject, POISON_INUSE, s->inuse - s->object_size);
 +                              endobject, POISON_INUSE,
 +                              s->inuse - s->object_size);
                }
        }
  
@@@ -878,6 -873,7 +878,6 @@@ static int on_freelist(struct kmem_cach
                                object_err(s, page, object,
                                        "Freechain corrupt");
                                set_freepointer(s, object, NULL);
 -                              break;
                        } else {
                                slab_err(s, page, "Freepointer corrupt");
                                page->freelist = NULL;
@@@ -922,8 -918,7 +922,8 @@@ static void trace(struct kmem_cache *s
                        page->freelist);
  
                if (!alloc)
 -                      print_section("Object ", (void *)object, s->object_size);
 +                      print_section("Object ", (void *)object,
 +                                      s->object_size);
  
                dump_stack();
        }
   * Hooks for other subsystems that check memory allocations. In a typical
   * production configuration these hooks all should produce no code at all.
   */
+ static inline void kmalloc_large_node_hook(void *ptr, size_t size, gfp_t flags)
+ {
+       kmemleak_alloc(ptr, size, 1, flags);
+ }
+ static inline void kfree_hook(const void *x)
+ {
+       kmemleak_free(x);
+ }
  static inline int slab_pre_alloc_hook(struct kmem_cache *s, gfp_t flags)
  {
        flags &= gfp_allowed_mask;
        return should_failslab(s->object_size, flags, s->flags);
  }
  
 -static inline void slab_post_alloc_hook(struct kmem_cache *s, gfp_t flags, void *object)
 +static inline void slab_post_alloc_hook(struct kmem_cache *s,
 +                                      gfp_t flags, void *object)
  {
        flags &= gfp_allowed_mask;
        kmemcheck_slab_alloc(s, flags, object, slab_ksize(s));
@@@ -955,7 -959,7 +965,7 @@@ static inline void slab_free_hook(struc
        kmemleak_free_recursive(x, s->flags);
  
        /*
 -       * Trouble is that we may no longer disable interupts in the fast path
 +       * Trouble is that we may no longer disable interrupts in the fast path
         * So in order to make the debug calls that expect irqs to be
         * disabled we need to disable interrupts temporarily.
         */
@@@ -1045,8 -1049,7 +1055,8 @@@ static void setup_object_debug(struct k
        init_tracking(s, object);
  }
  
 -static noinline int alloc_debug_processing(struct kmem_cache *s, struct page *page,
 +static noinline int alloc_debug_processing(struct kmem_cache *s,
 +                                      struct page *page,
                                        void *object, unsigned long addr)
  {
        if (!check_slab(s, page))
@@@ -1217,8 -1220,8 +1227,8 @@@ static unsigned long kmem_cache_flags(u
        /*
         * Enable debugging if selected on the kernel commandline.
         */
-       if (slub_debug && (!slub_debug_slabs ||
-               !strncmp(slub_debug_slabs, name, strlen(slub_debug_slabs))))
+       if (slub_debug && (!slub_debug_slabs || (name &&
+               !strncmp(slub_debug_slabs, name, strlen(slub_debug_slabs)))))
                flags |= slub_debug;
  
        return flags;
@@@ -1260,13 -1263,30 +1270,30 @@@ static inline void inc_slabs_node(struc
  static inline void dec_slabs_node(struct kmem_cache *s, int node,
                                                        int objects) {}
  
+ static inline void kmalloc_large_node_hook(void *ptr, size_t size, gfp_t flags)
+ {
+       kmemleak_alloc(ptr, size, 1, flags);
+ }
+ static inline void kfree_hook(const void *x)
+ {
+       kmemleak_free(x);
+ }
  static inline int slab_pre_alloc_hook(struct kmem_cache *s, gfp_t flags)
                                                        { return 0; }
  
  static inline void slab_post_alloc_hook(struct kmem_cache *s, gfp_t flags,
-               void *object) {}
+               void *object)
+ {
+       kmemleak_alloc_recursive(object, s->object_size, 1, s->flags,
+               flags & gfp_allowed_mask);
+ }
  
- static inline void slab_free_hook(struct kmem_cache *s, void *x) {}
+ static inline void slab_free_hook(struct kmem_cache *s, void *x)
+ {
+       kmemleak_free_recursive(x, s->flags);
+ }
  
  #endif /* CONFIG_SLUB_DEBUG */
  
@@@ -1750,8 -1770,7 +1777,8 @@@ static void init_kmem_cache_cpus(struc
  /*
   * Remove the cpu slab
   */
 -static void deactivate_slab(struct kmem_cache *s, struct page *page, void *freelist)
 +static void deactivate_slab(struct kmem_cache *s, struct page *page,
 +                              void *freelist)
  {
        enum slab_modes { M_NONE, M_PARTIAL, M_FULL, M_FREE };
        struct kmem_cache_node *n = get_node(s, page_to_nid(page));
@@@ -2007,8 -2026,7 +2034,8 @@@ static void put_cpu_partial(struct kmem
                page->pobjects = pobjects;
                page->next = oldpage;
  
 -      } while (this_cpu_cmpxchg(s->cpu_slab->partial, oldpage, page) != oldpage);
 +      } while (this_cpu_cmpxchg(s->cpu_slab->partial, oldpage, page)
 +                                                              != oldpage);
  #endif
  }
  
@@@ -2178,8 -2196,8 +2205,8 @@@ static inline bool pfmemalloc_match(str
  }
  
  /*
 - * Check the page->freelist of a page and either transfer the freelist to the per cpu freelist
 - * or deactivate the page.
 + * Check the page->freelist of a page and either transfer the freelist to the
 + * per cpu freelist or deactivate the page.
   *
   * The page is still frozen if the return value is not NULL.
   *
@@@ -2323,8 -2341,7 +2350,8 @@@ new_slab
                goto load_freelist;
  
        /* Only entered in the debug case */
 -      if (kmem_cache_debug(s) && !alloc_debug_processing(s, page, freelist, addr))
 +      if (kmem_cache_debug(s) &&
 +                      !alloc_debug_processing(s, page, freelist, addr))
                goto new_slab;  /* Slab failed checks. Next slab needed */
  
        deactivate_slab(s, page, get_freepointer(s, freelist));
@@@ -2382,7 -2399,7 +2409,7 @@@ redo
  
        object = c->freelist;
        page = c->page;
 -      if (unlikely(!object || !page || !node_match(page, node)))
 +      if (unlikely(!object || !node_match(page, node)))
                object = __slab_alloc(s, gfpflags, node, addr, c);
  
        else {
                 * The cmpxchg will only match if there was no additional
                 * operation and if we are on the right processor.
                 *
 -               * The cmpxchg does the following atomically (without lock semantics!)
 +               * The cmpxchg does the following atomically (without lock
 +               * semantics!)
                 * 1. Relocate first pointer to the current per cpu area.
                 * 2. Verify that tid and freelist have not been changed
                 * 3. If they were not changed replace tid and freelist
                 *
 -               * Since this is without lock semantics the protection is only against
 -               * code executing on this cpu *not* from access by other cpus.
 +               * Since this is without lock semantics the protection is only
 +               * against code executing on this cpu *not* from access by
 +               * other cpus.
                 */
                if (unlikely(!this_cpu_cmpxchg_double(
                                s->cpu_slab->freelist, s->cpu_slab->tid,
@@@ -2432,8 -2447,7 +2459,8 @@@ void *kmem_cache_alloc(struct kmem_cach
  {
        void *ret = slab_alloc(s, gfpflags, _RET_IP_);
  
 -      trace_kmem_cache_alloc(_RET_IP_, ret, s->object_size, s->size, gfpflags);
 +      trace_kmem_cache_alloc(_RET_IP_, ret, s->object_size,
 +                              s->size, gfpflags);
  
        return ret;
  }
@@@ -2447,6 -2461,14 +2474,6 @@@ void *kmem_cache_alloc_trace(struct kme
        return ret;
  }
  EXPORT_SYMBOL(kmem_cache_alloc_trace);
 -
 -void *kmalloc_order_trace(size_t size, gfp_t flags, unsigned int order)
 -{
 -      void *ret = kmalloc_order(size, flags, order);
 -      trace_kmalloc(_RET_IP_, ret, size, PAGE_SIZE << order, flags);
 -      return ret;
 -}
 -EXPORT_SYMBOL(kmalloc_order_trace);
  #endif
  
  #ifdef CONFIG_NUMA
@@@ -2517,10 -2539,8 +2544,10 @@@ static void __slab_free(struct kmem_cac
                        if (kmem_cache_has_cpu_partial(s) && !prior)
  
                                /*
 -                               * Slab was on no list before and will be partially empty
 -                               * We can defer the list move and instead freeze it.
 +                               * Slab was on no list before and will be
 +                               * partially empty
 +                               * We can defer the list move and instead
 +                               * freeze it.
                                 */
                                new.frozen = 1;
  
@@@ -2829,8 -2849,8 +2856,8 @@@ static struct kmem_cache *kmem_cache_no
   * slab on the node for this slabcache. There are no concurrent accesses
   * possible.
   *
-  * Note that this function only works on the kmalloc_node_cache
-  * when allocating for the kmalloc_node_cache. This is used for bootstrapping
+  * Note that this function only works on the kmem_cache_node
+  * when allocating for the kmem_cache_node. This is used for bootstrapping
   * memory on a fresh node that has no slab structures yet.
   */
  static void early_kmem_cache_node_alloc(int node)
@@@ -3078,8 -3098,8 +3105,8 @@@ static int kmem_cache_open(struct kmem_
         * A) The number of objects from per cpu partial slabs dumped to the
         *    per node list when we reach the limit.
         * B) The number of objects in cpu partial slabs to extract from the
 -       *    per node list when we run out of per cpu objects. We only fetch 50%
 -       *    to keep some capacity around for frees.
 +       *    per node list when we run out of per cpu objects. We only fetch
 +       *    50% to keep some capacity around for frees.
         */
        if (!kmem_cache_has_cpu_partial(s))
                s->cpu_partial = 0;
@@@ -3106,8 -3126,8 +3133,8 @@@ error
        if (flags & SLAB_PANIC)
                panic("Cannot create slab %s size=%lu realsize=%u "
                        "order=%u offset=%u flags=%lx\n",
 -                      s->name, (unsigned long)s->size, s->size, oo_order(s->oo),
 -                      s->offset, flags);
 +                      s->name, (unsigned long)s->size, s->size,
 +                      oo_order(s->oo), s->offset, flags);
        return -EINVAL;
  }
  
@@@ -3272,7 -3292,7 +3299,7 @@@ static void *kmalloc_large_node(size_t 
        if (page)
                ptr = page_address(page);
  
-       kmemleak_alloc(ptr, size, 1, flags);
+       kmalloc_large_node_hook(ptr, size, flags);
        return ptr;
  }
  
@@@ -3323,6 -3343,42 +3350,6 @@@ size_t ksize(const void *object
  }
  EXPORT_SYMBOL(ksize);
  
 -#ifdef CONFIG_SLUB_DEBUG
 -bool verify_mem_not_deleted(const void *x)
 -{
 -      struct page *page;
 -      void *object = (void *)x;
 -      unsigned long flags;
 -      bool rv;
 -
 -      if (unlikely(ZERO_OR_NULL_PTR(x)))
 -              return false;
 -
 -      local_irq_save(flags);
 -
 -      page = virt_to_head_page(x);
 -      if (unlikely(!PageSlab(page))) {
 -              /* maybe it was from stack? */
 -              rv = true;
 -              goto out_unlock;
 -      }
 -
 -      slab_lock(page);
 -      if (on_freelist(page->slab_cache, page, object)) {
 -              object_err(page->slab_cache, page, object, "Object is on free-list");
 -              rv = false;
 -      } else {
 -              rv = true;
 -      }
 -      slab_unlock(page);
 -
 -out_unlock:
 -      local_irq_restore(flags);
 -      return rv;
 -}
 -EXPORT_SYMBOL(verify_mem_not_deleted);
 -#endif
 -
  void kfree(const void *x)
  {
        struct page *page;
        page = virt_to_head_page(x);
        if (unlikely(!PageSlab(page))) {
                BUG_ON(!PageCompound(page));
-               kmemleak_free(x);
+               kfree_hook(x);
                __free_memcg_kmem_pages(page, compound_order(page));
                return;
        }
@@@ -4133,17 -4189,15 +4160,17 @@@ static int list_locations(struct kmem_c
                                !cpumask_empty(to_cpumask(l->cpus)) &&
                                len < PAGE_SIZE - 60) {
                        len += sprintf(buf + len, " cpus=");
 -                      len += cpulist_scnprintf(buf + len, PAGE_SIZE - len - 50,
 +                      len += cpulist_scnprintf(buf + len,
 +                                               PAGE_SIZE - len - 50,
                                                 to_cpumask(l->cpus));
                }
  
                if (nr_online_nodes > 1 && !nodes_empty(l->nodes) &&
                                len < PAGE_SIZE - 60) {
                        len += sprintf(buf + len, " nodes=");
 -                      len += nodelist_scnprintf(buf + len, PAGE_SIZE - len - 50,
 -                                      l->nodes);
 +                      len += nodelist_scnprintf(buf + len,
 +                                                PAGE_SIZE - len - 50,
 +                                                l->nodes);
                }
  
                len += sprintf(buf + len, "\n");
@@@ -4241,17 -4295,18 +4268,17 @@@ static ssize_t show_slab_objects(struc
        int node;
        int x;
        unsigned long *nodes;
 -      unsigned long *per_cpu;
  
 -      nodes = kzalloc(2 * sizeof(unsigned long) * nr_node_ids, GFP_KERNEL);
 +      nodes = kzalloc(sizeof(unsigned long) * nr_node_ids, GFP_KERNEL);
        if (!nodes)
                return -ENOMEM;
 -      per_cpu = nodes + nr_node_ids;
  
        if (flags & SO_CPU) {
                int cpu;
  
                for_each_possible_cpu(cpu) {
 -                      struct kmem_cache_cpu *c = per_cpu_ptr(s->cpu_slab, cpu);
 +                      struct kmem_cache_cpu *c = per_cpu_ptr(s->cpu_slab,
 +                                                             cpu);
                        int node;
                        struct page *page;
  
                                total += x;
                                nodes[node] += x;
                        }
 -
 -                      per_cpu[node]++;
                }
        }
  
                for_each_node_state(node, N_NORMAL_MEMORY) {
                        struct kmem_cache_node *n = get_node(s, node);
  
 -              if (flags & SO_TOTAL)
 -                      x = atomic_long_read(&n->total_objects);
 -              else if (flags & SO_OBJECTS)
 -                      x = atomic_long_read(&n->total_objects) -
 -                              count_partial(n, count_free);
 -
 +                      if (flags & SO_TOTAL)
 +                              x = atomic_long_read(&n->total_objects);
 +                      else if (flags & SO_OBJECTS)
 +                              x = atomic_long_read(&n->total_objects) -
 +                                      count_partial(n, count_free);
                        else
                                x = atomic_long_read(&n->nr_slabs);
                        total += x;
@@@ -4389,7 -4447,7 +4416,7 @@@ static ssize_t order_store(struct kmem_
        unsigned long order;
        int err;
  
 -      err = strict_strtoul(buf, 10, &order);
 +      err = kstrtoul(buf, 10, &order);
        if (err)
                return err;
  
@@@ -4417,7 -4475,7 +4444,7 @@@ static ssize_t min_partial_store(struc
        unsigned long min;
        int err;
  
 -      err = strict_strtoul(buf, 10, &min);
 +      err = kstrtoul(buf, 10, &min);
        if (err)
                return err;
  
@@@ -4437,7 -4495,7 +4464,7 @@@ static ssize_t cpu_partial_store(struc
        unsigned long objects;
        int err;
  
 -      err = strict_strtoul(buf, 10, &objects);
 +      err = kstrtoul(buf, 10, &objects);
        if (err)
                return err;
        if (objects && !kmem_cache_has_cpu_partial(s))
@@@ -4753,7 -4811,7 +4780,7 @@@ static ssize_t remote_node_defrag_ratio
        unsigned long ratio;
        int err;
  
 -      err = strict_strtoul(buf, 10, &ratio);
 +      err = kstrtoul(buf, 10, &ratio);
        if (err)
                return err;
  
@@@ -4983,7 -5041,7 +5010,7 @@@ static ssize_t slab_attr_store(struct k
                 * through the descendants with best-effort propagation.
                 */
                for_each_memcg_cache_index(i) {
 -                      struct kmem_cache *c = cache_from_memcg(s, i);
 +                      struct kmem_cache *c = cache_from_memcg_idx(s, i);
                        if (c)
                                attribute->store(c, buf, len);
                }
@@@ -5105,8 -5163,7 +5132,8 @@@ static char *create_unique_id(struct km
  
  #ifdef CONFIG_MEMCG_KMEM
        if (!is_root_cache(s))
 -              p += sprintf(p, "-%08d", memcg_cache_id(s->memcg_params->memcg));
 +              p += sprintf(p, "-%08d",
 +                              memcg_cache_id(s->memcg_params->memcg));
  #endif
  
        BUG_ON(p > name + ID_STR_LENGTH - 1);