]> Git Repo - linux.git/commitdiff
Merge branch 'slub/hotplug' into slab/urgent
authorPekka Enberg <[email protected]>
Sat, 15 Jan 2011 11:28:17 +0000 (13:28 +0200)
committerPekka Enberg <[email protected]>
Sat, 15 Jan 2011 11:28:17 +0000 (13:28 +0200)
1  2 
include/linux/memory_hotplug.h
mm/memory_hotplug.c
mm/slub.c

index 24376fe7ee68b5cc71cca000cfdc260527de207b,12b9eb5a36c311474c9caf077d96e4f4d31c8163..8122018d300029167518eb4a9c93e395e3efd304
@@@ -13,16 -13,12 +13,16 @@@ struct mem_section
  #ifdef CONFIG_MEMORY_HOTPLUG
  
  /*
 - * Types for free bootmem.
 - * The normal smallest mapcount is -1. Here is smaller value than it.
 + * Types for free bootmem stored in page->lru.next. These have to be in
 + * some random range in unsigned long space for debugging purposes.
   */
 -#define SECTION_INFO          (-1 - 1)
 -#define MIX_SECTION_INFO      (-1 - 2)
 -#define NODE_INFO             (-1 - 3)
 +enum {
 +      MEMORY_HOTPLUG_MIN_BOOTMEM_TYPE = 12,
 +      SECTION_INFO = MEMORY_HOTPLUG_MIN_BOOTMEM_TYPE,
 +      MIX_SECTION_INFO,
 +      NODE_INFO,
 +      MEMORY_HOTPLUG_MAX_BOOTMEM_TYPE = NODE_INFO,
 +};
  
  /*
   * pgdat resizing functions
@@@ -165,6 -161,12 +165,12 @@@ extern void register_page_bootmem_info_
  extern void put_page_bootmem(struct page *page);
  #endif
  
+ /*
+  * Lock for memory hotplug guarantees 1) all callbacks for memory hotplug
+  * notifier will be called under this. 2) offline/online/add/remove memory
+  * will not run simultaneously.
+  */
  void lock_memory_hotplug(void);
  void unlock_memory_hotplug(void);
  
diff --combined mm/memory_hotplug.c
index e92f04749fcb23fa283642dbb2a00dcda1ccd38d,83163c096a7580645b6b281257fb3128cde93bc2..321fc7455df7328c08441b54300054ff963e487b
@@@ -82,10 -82,9 +82,10 @@@ static void release_memory_resource(str
  
  #ifdef CONFIG_MEMORY_HOTPLUG_SPARSE
  #ifndef CONFIG_SPARSEMEM_VMEMMAP
 -static void get_page_bootmem(unsigned long info,  struct page *page, int type)
 +static void get_page_bootmem(unsigned long info,  struct page *page,
 +                           unsigned long type)
  {
 -      atomic_set(&page->_mapcount, type);
 +      page->lru.next = (struct list_head *) type;
        SetPagePrivate(page);
        set_page_private(page, info);
        atomic_inc(&page->_count);
   * so use __ref to tell modpost not to generate a warning */
  void __ref put_page_bootmem(struct page *page)
  {
 -      int type;
 +      unsigned long type;
  
 -      type = atomic_read(&page->_mapcount);
 -      BUG_ON(type >= -1);
 +      type = (unsigned long) page->lru.next;
 +      BUG_ON(type < MEMORY_HOTPLUG_MIN_BOOTMEM_TYPE ||
 +             type > MEMORY_HOTPLUG_MAX_BOOTMEM_TYPE);
  
        if (atomic_dec_return(&page->_count) == 1) {
                ClearPagePrivate(page);
                set_page_private(page, 0);
 -              reset_page_mapcount(page);
 +              INIT_LIST_HEAD(&page->lru);
                __free_pages_bootmem(page, 0);
        }
  
@@@ -409,6 -407,7 +409,7 @@@ int online_pages(unsigned long pfn, uns
        int ret;
        struct memory_notify arg;
  
+       lock_memory_hotplug();
        arg.start_pfn = pfn;
        arg.nr_pages = nr_pages;
        arg.status_change_nid = -1;
        ret = notifier_to_errno(ret);
        if (ret) {
                memory_notify(MEM_CANCEL_ONLINE, &arg);
+               unlock_memory_hotplug();
                return ret;
        }
        /*
                printk(KERN_DEBUG "online_pages %lx at %lx failed\n",
                        nr_pages, pfn);
                memory_notify(MEM_CANCEL_ONLINE, &arg);
+               unlock_memory_hotplug();
                return ret;
        }
  
  
        if (onlined_pages)
                memory_notify(MEM_ONLINE, &arg);
+       unlock_memory_hotplug();
  
        return 0;
  }
@@@ -735,8 -737,7 +739,8 @@@ do_migrate_range(unsigned long start_pf
                        goto out;
                }
                /* this function returns # of failed pages */
 -              ret = migrate_pages(&source, hotremove_migrate_alloc, 0, 1);
 +              ret = migrate_pages(&source, hotremove_migrate_alloc, 0,
 +                                                              true, true);
                if (ret)
                        putback_lru_pages(&source);
        }
diff --combined mm/slub.c
index c7ef0070dd864efd8bd2261c428228cbffbabe44,96e690717822249ce7442a916f02b4aeeffee355..e15aa7f193c9734518f3c3508210c70f294e4ad3
+++ b/mm/slub.c
@@@ -28,8 -28,6 +28,8 @@@
  #include <linux/math64.h>
  #include <linux/fault-inject.h>
  
 +#include <trace/events/kmem.h>
 +
  /*
   * Lock order:
   *   1. slab_lock(page)
@@@ -1776,21 -1774,11 +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
@@@ -1806,17 -1794,13 +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
  
@@@ -1933,6 -1917,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
@@@ -2390,6 -2385,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
   */
@@@ -3636,7 -3660,7 +3636,7 @@@ static int list_locations(struct kmem_c
                len += sprintf(buf + len, "%7ld ", l->count);
  
                if (l->addr)
 -                      len += sprint_symbol(buf + len, (unsigned long)l->addr);
 +                      len += sprintf(buf + len, "%pS", (void *)l->addr);
                else
                        len += sprintf(buf + len, "<not-available>");
  
@@@ -3797,7 -3821,7 +3797,7 @@@ static ssize_t show_slab_objects(struc
                }
        }
  
-       down_read(&slub_lock);
+       lock_memory_hotplug();
  #ifdef CONFIG_SLUB_DEBUG
        if (flags & SO_ALL) {
                for_each_node_state(node, N_NORMAL_MEMORY) {
                        x += sprintf(buf + x, " N%d=%lu",
                                        node, nodes[node]);
  #endif
-       up_read(&slub_lock);
+       unlock_memory_hotplug();
        kfree(nodes);
        return x + sprintf(buf + x, "\n");
  }
@@@ -3946,9 -3970,12 +3946,9 @@@ SLAB_ATTR(min_partial)
  
  static ssize_t ctor_show(struct kmem_cache *s, char *buf)
  {
 -      if (s->ctor) {
 -              int n = sprint_symbol(buf, (unsigned long)s->ctor);
 -
 -              return n + sprintf(buf + n, "\n");
 -      }
 -      return 0;
 +      if (!s->ctor)
 +              return 0;
 +      return sprintf(buf, "%pS\n", s->ctor);
  }
  SLAB_ATTR_RO(ctor);
  
This page took 0.080666 seconds and 4 git commands to generate.