[PATCH] fix kernel-doc warnings in 2.6.20-rc1
[sfrench/cifs-2.6.git] / mm / slab.c
index 1f374c1df018fc402fbedcdc9c3843afbf7f7285..0d4e57431de41c8d7fccfe9307bfb504087e5c03 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
 #include       <linux/module.h>
 #include       <linux/rcupdate.h>
 #include       <linux/string.h>
+#include       <linux/uaccess.h>
 #include       <linux/nodemask.h>
 #include       <linux/mempolicy.h>
 #include       <linux/mutex.h>
+#include       <linux/fault-inject.h>
 #include       <linux/rtmutex.h>
+#include       <linux/reciprocal_div.h>
 
-#include       <asm/uaccess.h>
 #include       <asm/cacheflush.h>
 #include       <asm/tlbflush.h>
 #include       <asm/page.h>
@@ -385,6 +387,7 @@ struct kmem_cache {
        unsigned int shared;
 
        unsigned int buffer_size;
+       u32 reciprocal_buffer_size;
 /* 3) touched by every alloc & free from the backend */
        struct kmem_list3 *nodelists[MAX_NUMNODES];
 
@@ -626,10 +629,17 @@ static inline void *index_to_obj(struct kmem_cache *cache, struct slab *slab,
        return slab->s_mem + cache->buffer_size * idx;
 }
 
-static inline unsigned int obj_to_index(struct kmem_cache *cache,
-                                       struct slab *slab, void *obj)
+/*
+ * We want to avoid an expensive divide : (offset / cache->buffer_size)
+ *   Using the fact that buffer_size is a constant for a particular cache,
+ *   we can replace (offset / cache->buffer_size) by
+ *   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)
 {
-       return (unsigned)(obj - slab->s_mem) / cache->buffer_size;
+       u32 offset = (obj - slab->s_mem);
+       return reciprocal_divide(offset, cache->reciprocal_buffer_size);
 }
 
 /*
@@ -945,7 +955,8 @@ static void __devinit start_cpu_timer(int cpu)
        if (keventd_up() && reap_work->work.func == NULL) {
                init_reap_node(cpu);
                INIT_DELAYED_WORK(reap_work, cache_reap);
-               schedule_delayed_work_on(cpu, reap_work, HZ + 3 * cpu);
+               schedule_delayed_work_on(cpu, reap_work,
+                                       __round_jiffies_relative(HZ, cpu));
        }
 }
 
@@ -1425,6 +1436,8 @@ void __init kmem_cache_init(void)
 
        cache_cache.buffer_size = ALIGN(cache_cache.buffer_size,
                                        cache_line_size());
+       cache_cache.reciprocal_buffer_size =
+               reciprocal_value(cache_cache.buffer_size);
 
        for (order = 0; order < MAX_ORDER; order++) {
                cache_estimate(order, cache_cache.buffer_size,
@@ -1605,12 +1618,7 @@ static void *kmem_getpages(struct kmem_cache *cachep, gfp_t flags, int nodeid)
        flags |= __GFP_COMP;
 #endif
 
-       /*
-        * Under NUMA we want memory on the indicated node. We will handle
-        * the needed fallback ourselves since we want to serve from our
-        * per node object lists first for other nodes.
-        */
-       flags |= cachep->gfpflags | GFP_THISNODE;
+       flags |= cachep->gfpflags;
 
        page = alloc_pages_node(nodeid, flags, cachep->gfporder);
        if (!page)
@@ -2129,7 +2137,6 @@ kmem_cache_create (const char *name, size_t size, size_t align,
        mutex_lock(&cache_chain_mutex);
 
        list_for_each_entry(pc, &cache_chain, next) {
-               mm_segment_t old_fs = get_fs();
                char tmp;
                int res;
 
@@ -2138,9 +2145,7 @@ kmem_cache_create (const char *name, size_t size, size_t align,
                 * destroy its slab cache and no-one else reuses the vmalloc
                 * area of the module.  Print a warning.
                 */
-               set_fs(KERNEL_DS);
-               res = __get_user(tmp, pc->name);
-               set_fs(old_fs);
+               res = probe_kernel_address(pc->name, tmp);
                if (res) {
                        printk("SLAB: cache with size %d has lost its name\n",
                               pc->buffer_size);
@@ -2319,6 +2324,7 @@ kmem_cache_create (const char *name, size_t size, size_t align,
        if (flags & SLAB_CACHE_DMA)
                cachep->gfpflags |= GFP_DMA;
        cachep->buffer_size = size;
+       cachep->reciprocal_buffer_size = reciprocal_value(size);
 
        if (flags & CFLGS_OFF_SLAB) {
                cachep->slabp_cache = kmem_find_general_cachep(slab_size, 0u);
@@ -2567,7 +2573,7 @@ static struct slab *alloc_slabmgmt(struct kmem_cache *cachep, void *objp,
        if (OFF_SLAB(cachep)) {
                /* Slab management obj is off-slab. */
                slabp = kmem_cache_alloc_node(cachep->slabp_cache,
-                                             local_flags, nodeid);
+                                             local_flags & ~GFP_THISNODE, nodeid);
                if (!slabp)
                        return NULL;
        } else {
@@ -2637,7 +2643,7 @@ static void cache_init_objs(struct kmem_cache *cachep,
 
 static void kmem_flagcheck(struct kmem_cache *cachep, gfp_t flags)
 {
-       if (flags & SLAB_DMA)
+       if (flags & GFP_DMA)
                BUG_ON(!(cachep->gfpflags & GFP_DMA));
        else
                BUG_ON(cachep->gfpflags & GFP_DMA);
@@ -2708,10 +2714,10 @@ static void slab_map_pages(struct kmem_cache *cache, struct slab *slab,
  * Grow (by 1) the number of slabs within a cache.  This is called by
  * 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)
+static int cache_grow(struct kmem_cache *cachep,
+               gfp_t flags, int nodeid, void *objp)
 {
        struct slab *slabp;
-       void *objp;
        size_t offset;
        gfp_t local_flags;
        unsigned long ctor_flags;
@@ -2721,7 +2727,7 @@ static int cache_grow(struct kmem_cache *cachep, gfp_t flags, int nodeid)
         * Be lazy and only check for valid flags here,  keeping it out of the
         * critical path in kmem_cache_alloc().
         */
-       BUG_ON(flags & ~(SLAB_DMA | GFP_LEVEL_MASK | __GFP_NO_GROW));
+       BUG_ON(flags & ~(GFP_DMA | GFP_LEVEL_MASK | __GFP_NO_GROW));
        if (flags & __GFP_NO_GROW)
                return 0;
 
@@ -2763,12 +2769,14 @@ static int cache_grow(struct kmem_cache *cachep, gfp_t flags, int nodeid)
         * Get mem for the objs.  Attempt to allocate a physical page from
         * 'nodeid'.
         */
-       objp = kmem_getpages(cachep, flags, nodeid);
+       if (!objp)
+               objp = kmem_getpages(cachep, flags, nodeid);
        if (!objp)
                goto failed;
 
        /* Get slab management. */
-       slabp = alloc_slabmgmt(cachep, objp, offset, local_flags, nodeid);
+       slabp = alloc_slabmgmt(cachep, objp, offset,
+                       local_flags & ~GFP_THISNODE, nodeid);
        if (!slabp)
                goto opps1;
 
@@ -3006,7 +3014,7 @@ alloc_done:
 
        if (unlikely(!ac->avail)) {
                int x;
-               x = cache_grow(cachep, flags, node);
+               x = cache_grow(cachep, flags | GFP_THISNODE, node, NULL);
 
                /* cache_grow can reenable interrupts, then ac could change. */
                ac = cpu_cache_get(cachep);
@@ -3094,12 +3102,89 @@ static void *cache_alloc_debugcheck_after(struct kmem_cache *cachep,
 #define cache_alloc_debugcheck_after(a,b,objp,d) (objp)
 #endif
 
+#ifdef CONFIG_FAILSLAB
+
+static struct failslab_attr {
+
+       struct fault_attr attr;
+
+       u32 ignore_gfp_wait;
+#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
+       struct dentry *ignore_gfp_wait_file;
+#endif
+
+} failslab = {
+       .attr = FAULT_ATTR_INITIALIZER,
+       .ignore_gfp_wait = 1,
+};
+
+static int __init setup_failslab(char *str)
+{
+       return setup_fault_attr(&failslab.attr, str);
+}
+__setup("failslab=", setup_failslab);
+
+static int should_failslab(struct kmem_cache *cachep, gfp_t flags)
+{
+       if (cachep == &cache_cache)
+               return 0;
+       if (flags & __GFP_NOFAIL)
+               return 0;
+       if (failslab.ignore_gfp_wait && (flags & __GFP_WAIT))
+               return 0;
+
+       return should_fail(&failslab.attr, obj_size(cachep));
+}
+
+#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS
+
+static int __init failslab_debugfs(void)
+{
+       mode_t mode = S_IFREG | S_IRUSR | S_IWUSR;
+       struct dentry *dir;
+       int err;
+
+               err = init_fault_attr_dentries(&failslab.attr, "failslab");
+       if (err)
+               return err;
+       dir = failslab.attr.dentries.dir;
+
+       failslab.ignore_gfp_wait_file =
+               debugfs_create_bool("ignore-gfp-wait", mode, dir,
+                                     &failslab.ignore_gfp_wait);
+
+       if (!failslab.ignore_gfp_wait_file) {
+               err = -ENOMEM;
+               debugfs_remove(failslab.ignore_gfp_wait_file);
+               cleanup_fault_attr_dentries(&failslab.attr);
+       }
+
+       return err;
+}
+
+late_initcall(failslab_debugfs);
+
+#endif /* CONFIG_FAULT_INJECTION_DEBUG_FS */
+
+#else /* CONFIG_FAILSLAB */
+
+static inline int should_failslab(struct kmem_cache *cachep, gfp_t flags)
+{
+       return 0;
+}
+
+#endif /* CONFIG_FAILSLAB */
+
 static inline void *____cache_alloc(struct kmem_cache *cachep, gfp_t flags)
 {
        void *objp;
        struct array_cache *ac;
 
        check_irq_off();
+
+       if (should_failslab(cachep, flags))
+               return NULL;
+
        ac = cpu_cache_get(cachep);
        if (likely(ac->avail)) {
                STATS_INC_ALLOCHIT(cachep);
@@ -3166,9 +3251,11 @@ static void *alternate_node_alloc(struct kmem_cache *cachep, gfp_t flags)
 
 /*
  * Fallback function if there was no memory available and no objects on a
- * certain node and we are allowed to fall back. We mimick the behavior of
- * the page allocator. We fall back according to a zonelist determined by
- * the policy layer while obeying cpuset constraints.
+ * certain node and fall back is permitted. First we scan all the
+ * available nodelists for available objects. If that fails then we
+ * perform an allocation without specifying a node. This allows the page
+ * allocator to do its reclaim / fallback magic. We then insert the
+ * slab into the proper nodelist and then allocate from it.
  */
 void *fallback_alloc(struct kmem_cache *cache, gfp_t flags)
 {
@@ -3176,15 +3263,57 @@ void *fallback_alloc(struct kmem_cache *cache, gfp_t flags)
                                        ->node_zonelists[gfp_zone(flags)];
        struct zone **z;
        void *obj = NULL;
+       int nid;
+       gfp_t local_flags = (flags & GFP_LEVEL_MASK);
 
+retry:
+       /*
+        * Look through allowed nodes for objects available
+        * from existing per node queues.
+        */
        for (z = zonelist->zones; *z && !obj; z++) {
-               int nid = zone_to_nid(*z);
+               nid = zone_to_nid(*z);
+
+               if (cpuset_zone_allowed_hardwall(*z, flags) &&
+                       cache->nodelists[nid] &&
+                       cache->nodelists[nid]->free_objects)
+                               obj = ____cache_alloc_node(cache,
+                                       flags | GFP_THISNODE, nid);
+       }
 
-               if (zone_idx(*z) <= ZONE_NORMAL &&
-                               cpuset_zone_allowed(*z, flags) &&
-                               cache->nodelists[nid])
-                       obj = ____cache_alloc_node(cache,
-                                       flags | __GFP_THISNODE, nid);
+       if (!obj) {
+               /*
+                * This allocation will be performed within the constraints
+                * of the current cpuset / memory policy requirements.
+                * We may trigger various forms of reclaim on the allowed
+                * set and go into memory reserves if necessary.
+                */
+               if (local_flags & __GFP_WAIT)
+                       local_irq_enable();
+               kmem_flagcheck(cache, flags);
+               obj = kmem_getpages(cache, flags, -1);
+               if (local_flags & __GFP_WAIT)
+                       local_irq_disable();
+               if (obj) {
+                       /*
+                        * Insert into the appropriate per node queues
+                        */
+                       nid = page_to_nid(virt_to_page(obj));
+                       if (cache_grow(cache, flags, nid, obj)) {
+                               obj = ____cache_alloc_node(cache,
+                                       flags | GFP_THISNODE, nid);
+                               if (!obj)
+                                       /*
+                                        * Another processor may allocate the
+                                        * objects in the slab since we are
+                                        * not holding any locks.
+                                        */
+                                       goto retry;
+                       } else {
+                               kmem_freepages(cache, obj);
+                               obj = NULL;
+                       }
+               }
        }
        return obj;
 }
@@ -3241,7 +3370,7 @@ retry:
 
 must_grow:
        spin_unlock(&l3->list_lock);
-       x = cache_grow(cachep, flags, nodeid);
+       x = cache_grow(cachep, flags | GFP_THISNODE, nodeid, NULL);
        if (x)
                goto retry;
 
@@ -3424,7 +3553,7 @@ EXPORT_SYMBOL(kmem_cache_zalloc);
  *
  * Currently only used for dentry validation.
  */
-int fastcall kmem_ptr_validate(struct kmem_cache *cachep, void *ptr)
+int kmem_ptr_validate(struct kmem_cache *cachep, const void *ptr)
 {
        unsigned long addr = (unsigned long)ptr;
        unsigned long min_addr = PAGE_OFFSET;
@@ -3458,30 +3587,47 @@ out:
  * @cachep: The cache to allocate from.
  * @flags: See kmalloc().
  * @nodeid: node number of the target node.
+ * @caller: return address of caller, used for debug information
+ *
+ * Identical to kmem_cache_alloc but it will allocate memory on the given
+ * node, which can improve the performance for cpu bound structures.
  *
- * Identical to kmem_cache_alloc, except that this function is slow
- * and can sleep. And it will allocate memory on the given node, which
- * can improve the performance for cpu bound structures.
- * New and improved: it will now make sure that the object gets
- * put on the correct node list so that there is no false sharing.
+ * Fallback to other node is possible if __GFP_THISNODE is not set.
  */
 static __always_inline void *
 __cache_alloc_node(struct kmem_cache *cachep, gfp_t flags,
                int nodeid, void *caller)
 {
        unsigned long save_flags;
-       void *ptr;
+       void *ptr = NULL;
 
        cache_alloc_debugcheck_before(cachep, flags);
        local_irq_save(save_flags);
 
-       if (nodeid == -1 || nodeid == numa_node_id() ||
-                       !cachep->nodelists[nodeid])
-               ptr = ____cache_alloc(cachep, flags);
-       else
-               ptr = ____cache_alloc_node(cachep, flags, nodeid);
-       local_irq_restore(save_flags);
+       if (unlikely(nodeid == -1))
+               nodeid = numa_node_id();
 
+       if (likely(cachep->nodelists[nodeid])) {
+               if (nodeid == numa_node_id()) {
+                       /*
+                        * Use the locally cached objects if possible.
+                        * However ____cache_alloc does not allow fallback
+                        * to other nodes. It may fail while we still have
+                        * objects on other nodes available.
+                        */
+                       ptr = ____cache_alloc(cachep, flags);
+               }
+               if (!ptr) {
+                       /* ___cache_alloc_node can fall back to other nodes */
+                       ptr = ____cache_alloc_node(cachep, flags, nodeid);
+               }
+       } else {
+               /* Node not bootstrapped yet */
+               if (!(flags & __GFP_THISNODE))
+                       ptr = fallback_alloc(cachep, flags);
+       }
+
+       local_irq_restore(save_flags);
        ptr = cache_alloc_debugcheck_after(cachep, flags, ptr, caller);
 
        return ptr;
@@ -3880,7 +4026,7 @@ static void cache_reap(struct work_struct *unused)
        if (!mutex_trylock(&cache_chain_mutex)) {
                /* Give up. Setup the next iteration. */
                schedule_delayed_work(&__get_cpu_var(reap_work),
-                                     REAPTIMEOUT_CPUC);
+                                     round_jiffies_relative(REAPTIMEOUT_CPUC));
                return;
        }
 
@@ -3926,7 +4072,8 @@ next:
        next_reap_node();
        refresh_cpu_vm_stats(smp_processor_id());
        /* Set up the next iteration */
-       schedule_delayed_work(&__get_cpu_var(reap_work), REAPTIMEOUT_CPUC);
+       schedule_delayed_work(&__get_cpu_var(reap_work),
+               round_jiffies_relative(REAPTIMEOUT_CPUC));
 }
 
 #ifdef CONFIG_PROC_FS
@@ -4094,7 +4241,7 @@ static int s_show(struct seq_file *m, void *p)
  * + further values on SMP and with statistics enabled
  */
 
-struct seq_operations slabinfo_op = {
+const struct seq_operations slabinfo_op = {
        .start = s_start,
        .next = s_next,
        .stop = s_stop,
@@ -4292,7 +4439,7 @@ static int leaks_show(struct seq_file *m, void *p)
        return 0;
 }
 
-struct seq_operations slabstats_op = {
+const struct seq_operations slabstats_op = {
        .start = leaks_start,
        .next = s_next,
        .stop = s_stop,