Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/penberg...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 10 Jan 2011 16:38:01 +0000 (08:38 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 10 Jan 2011 16:38:01 +0000 (08:38 -0800)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/penberg/slab-2.6:
  slub: Fix a crash during slabinfo -v
  tracing/slab: Move kmalloc tracepoint out of inline code
  slub: Fix slub_lock down/up imbalance
  slub: Fix build breakage in Documentation/vm
  slub tracing: move trace calls out of always inlined functions to reduce kernel code size
  slub: move slabinfo.c to tools/slub/slabinfo.c

1  2 
mm/slab.c
mm/slub.c

diff --combined mm/slab.c
+++ b/mm/slab.c
@@@ -829,12 -829,12 +829,12 @@@ static void init_reap_node(int cpu
  
  static void next_reap_node(void)
  {
 -      int node = __get_cpu_var(slab_reap_node);
 +      int node = __this_cpu_read(slab_reap_node);
  
        node = next_node(node, node_online_map);
        if (unlikely(node >= MAX_NUMNODES))
                node = first_node(node_online_map);
 -      __get_cpu_var(slab_reap_node) = node;
 +      __this_cpu_write(slab_reap_node, node);
  }
  
  #else
@@@ -1012,7 -1012,7 +1012,7 @@@ static void __drain_alien_cache(struct 
   */
  static void reap_alien(struct kmem_cache *cachep, struct kmem_list3 *l3)
  {
 -      int node = __get_cpu_var(slab_reap_node);
 +      int node = __this_cpu_read(slab_reap_node);
  
        if (l3->alien) {
                struct array_cache *ac = l3->alien[node];
@@@ -1293,7 -1293,7 +1293,7 @@@ static int __cpuinit cpuup_callback(str
                 * anything expensive but will only modify reap_work
                 * and reschedule the timer.
                */
 -              cancel_rearming_delayed_work(&per_cpu(slab_reap_work, cpu));
 +              cancel_delayed_work_sync(&per_cpu(slab_reap_work, cpu));
                /* Now the cache_reaper is guaranteed to be not running. */
                per_cpu(slab_reap_work, cpu).work.func = NULL;
                break;
@@@ -2781,7 -2781,7 +2781,7 @@@ static void slab_put_obj(struct kmem_ca
  /*
   * Map pages beginning at addr to the given cache and slab. This is required
   * for the slab allocator to be able to lookup the cache and slab of a
 - * virtual address for kfree, ksize, kmem_ptr_validate, and slab debugging.
 + * virtual address for kfree, ksize, and slab debugging.
   */
  static void slab_map_pages(struct kmem_cache *cache, struct slab *slab,
                           void *addr)
@@@ -3653,13 -3653,50 +3653,20 @@@ void *kmem_cache_alloc(struct kmem_cach
  EXPORT_SYMBOL(kmem_cache_alloc);
  
  #ifdef CONFIG_TRACING
- void *kmem_cache_alloc_notrace(struct kmem_cache *cachep, gfp_t flags)
+ void *
+ kmem_cache_alloc_trace(size_t size, struct kmem_cache *cachep, gfp_t flags)
  {
-       return __cache_alloc(cachep, flags, __builtin_return_address(0));
+       void *ret;
+       ret = __cache_alloc(cachep, flags, __builtin_return_address(0));
+       trace_kmalloc(_RET_IP_, ret,
+                     size, slab_buffer_size(cachep), flags);
+       return ret;
  }
- EXPORT_SYMBOL(kmem_cache_alloc_notrace);
+ EXPORT_SYMBOL(kmem_cache_alloc_trace);
  #endif
  
 -/**
 - * kmem_ptr_validate - check if an untrusted pointer might be a slab entry.
 - * @cachep: the cache we're checking against
 - * @ptr: pointer to validate
 - *
 - * This verifies that the untrusted pointer looks sane;
 - * it is _not_ a guarantee that the pointer is actually
 - * part of the slab cache in question, but it at least
 - * validates that the pointer can be dereferenced and
 - * looks half-way sane.
 - *
 - * Currently only used for dentry validation.
 - */
 -int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr)
 -{
 -      unsigned long size = cachep->buffer_size;
 -      struct page *page;
 -
 -      if (unlikely(!kern_ptr_validate(ptr, size)))
 -              goto out;
 -      page = virt_to_page(ptr);
 -      if (unlikely(!PageSlab(page)))
 -              goto out;
 -      if (unlikely(page_get_cache(page) != cachep))
 -              goto out;
 -      return 1;
 -out:
 -      return 0;
 -}
 -
  #ifdef CONFIG_NUMA
  void *kmem_cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid)
  {
  EXPORT_SYMBOL(kmem_cache_alloc_node);
  
  #ifdef CONFIG_TRACING
- void *kmem_cache_alloc_node_notrace(struct kmem_cache *cachep,
-                                   gfp_t flags,
-                                   int nodeid)
+ void *kmem_cache_alloc_node_trace(size_t size,
+                                 struct kmem_cache *cachep,
+                                 gfp_t flags,
+                                 int nodeid)
  {
-       return __cache_alloc_node(cachep, flags, nodeid,
+       void *ret;
+       ret = __cache_alloc_node(cachep, flags, nodeid,
                                  __builtin_return_address(0));
+       trace_kmalloc_node(_RET_IP_, ret,
+                          size, slab_buffer_size(cachep),
+                          flags, nodeid);
+       return ret;
  }
- EXPORT_SYMBOL(kmem_cache_alloc_node_notrace);
+ EXPORT_SYMBOL(kmem_cache_alloc_node_trace);
  #endif
  
  static __always_inline void *
  __do_kmalloc_node(size_t size, gfp_t flags, int node, void *caller)
  {
        struct kmem_cache *cachep;
-       void *ret;
  
        cachep = kmem_find_general_cachep(size, flags);
        if (unlikely(ZERO_OR_NULL_PTR(cachep)))
                return cachep;
-       ret = kmem_cache_alloc_node_notrace(cachep, flags, node);
-       trace_kmalloc_node((unsigned long) caller, ret,
-                          size, cachep->buffer_size, flags, node);
-       return ret;
+       return kmem_cache_alloc_node_trace(size, cachep, flags, node);
  }
  
  #if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_TRACING)
diff --combined mm/slub.c
+++ b/mm/slub.c
@@@ -28,6 -28,8 +28,8 @@@
  #include <linux/math64.h>
  #include <linux/fault-inject.h>
  
+ #include <trace/events/kmem.h>
  /*
   * Lock order:
   *   1. slab_lock(page)
@@@ -1774,11 -1776,21 +1776,21 @@@ void *kmem_cache_alloc(struct kmem_cach
  EXPORT_SYMBOL(kmem_cache_alloc);
  
  #ifdef CONFIG_TRACING
- void *kmem_cache_alloc_notrace(struct kmem_cache *s, gfp_t gfpflags)
+ void *kmem_cache_alloc_trace(struct kmem_cache *s, gfp_t gfpflags, size_t size)
+ {
+       void *ret = slab_alloc(s, gfpflags, NUMA_NO_NODE, _RET_IP_);
+       trace_kmalloc(_RET_IP_, ret, size, s->size, gfpflags);
+       return ret;
+ }
+ EXPORT_SYMBOL(kmem_cache_alloc_trace);
+ void *kmalloc_order_trace(size_t size, gfp_t flags, unsigned int order)
  {
-       return slab_alloc(s, gfpflags, NUMA_NO_NODE, _RET_IP_);
+       void *ret = kmalloc_order(size, flags, order);
+       trace_kmalloc(_RET_IP_, ret, size, PAGE_SIZE << order, flags);
+       return ret;
  }
- EXPORT_SYMBOL(kmem_cache_alloc_notrace);
+ EXPORT_SYMBOL(kmalloc_order_trace);
  #endif
  
  #ifdef CONFIG_NUMA
@@@ -1794,13 -1806,17 +1806,17 @@@ void *kmem_cache_alloc_node(struct kmem
  EXPORT_SYMBOL(kmem_cache_alloc_node);
  
  #ifdef CONFIG_TRACING
- void *kmem_cache_alloc_node_notrace(struct kmem_cache *s,
+ void *kmem_cache_alloc_node_trace(struct kmem_cache *s,
                                    gfp_t gfpflags,
-                                   int node)
+                                   int node, size_t size)
  {
-       return slab_alloc(s, gfpflags, node, _RET_IP_);
+       void *ret = slab_alloc(s, gfpflags, node, _RET_IP_);
+       trace_kmalloc_node(_RET_IP_, ret,
+                          size, s->size, gfpflags, node);
+       return ret;
  }
- EXPORT_SYMBOL(kmem_cache_alloc_node_notrace);
+ EXPORT_SYMBOL(kmem_cache_alloc_node_trace);
  #endif
  #endif
  
@@@ -1917,6 -1933,17 +1933,6 @@@ void kmem_cache_free(struct kmem_cache 
  }
  EXPORT_SYMBOL(kmem_cache_free);
  
 -/* Figure out on which slab page the object resides */
 -static struct page *get_object_page(const void *x)
 -{
 -      struct page *page = virt_to_head_page(x);
 -
 -      if (!PageSlab(page))
 -              return NULL;
 -
 -      return page;
 -}
 -
  /*
   * Object placement in a slab is made very easy because we always start at
   * offset 0. If we tune the size of the object to the alignment then we can
@@@ -2374,6 -2401,35 +2390,6 @@@ error
        return 0;
  }
  
 -/*
 - * Check if a given pointer is valid
 - */
 -int kmem_ptr_validate(struct kmem_cache *s, const void *object)
 -{
 -      struct page *page;
 -
 -      if (!kern_ptr_validate(object, s->size))
 -              return 0;
 -
 -      page = get_object_page(object);
 -
 -      if (!page || s != page->slab)
 -              /* No slab or wrong slab */
 -              return 0;
 -
 -      if (!check_valid_pointer(s, page, object))
 -              return 0;
 -
 -      /*
 -       * We could also check if the object is on the slabs freelist.
 -       * But this would be too expensive and it seems that the main
 -       * purpose of kmem_ptr_valid() is to check if the object belongs
 -       * to a certain slab.
 -       */
 -      return 1;
 -}
 -EXPORT_SYMBOL(kmem_ptr_validate);
 -
  /*
   * Determine the size of a slab object
   */