aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-28 18:04:26 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-28 18:04:26 -0400
commit0c9aac08261512d70d7d4817bd222abca8b6bdd6 (patch)
tree41bbfed632bfc6233eac3e936cfdce75c5bd3a8f /mm
parented0bb8ea059764c3fc882fb135473afd347335e9 (diff)
parent8bdec192b40cf7f7eec170b317c76089eb5eeddb (diff)
Merge branch 'slab/for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/penberg/linux
Pull SLAB changes from Pekka Enberg: "There's the new kmalloc_array() API, minor fixes and performance improvements, but quite honestly, nothing terribly exciting." * 'slab/for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/penberg/linux: mm: SLAB Out-of-memory diagnostics slab: introduce kmalloc_array() slub: per cpu partial statistics change slub: include include for prefetch slub: Do not hold slub_lock when calling sysfs_slab_add() slub: prefetch next freelist pointer in slab_alloc() slab, cleanup: remove unneeded return
Diffstat (limited to 'mm')
-rw-r--r--mm/slab.c56
-rw-r--r--mm/slub.c26
2 files changed, 73 insertions, 9 deletions
diff --git a/mm/slab.c b/mm/slab.c
index 29c8716eb7a9..e901a36e2520 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -1731,6 +1731,52 @@ static int __init cpucache_init(void)
1731} 1731}
1732__initcall(cpucache_init); 1732__initcall(cpucache_init);
1733 1733
1734static noinline void
1735slab_out_of_memory(struct kmem_cache *cachep, gfp_t gfpflags, int nodeid)
1736{
1737 struct kmem_list3 *l3;
1738 struct slab *slabp;
1739 unsigned long flags;
1740 int node;
1741
1742 printk(KERN_WARNING
1743 "SLAB: Unable to allocate memory on node %d (gfp=0x%x)\n",
1744 nodeid, gfpflags);
1745 printk(KERN_WARNING " cache: %s, object size: %d, order: %d\n",
1746 cachep->name, cachep->buffer_size, cachep->gfporder);
1747
1748 for_each_online_node(node) {
1749 unsigned long active_objs = 0, num_objs = 0, free_objects = 0;
1750 unsigned long active_slabs = 0, num_slabs = 0;
1751
1752 l3 = cachep->nodelists[node];
1753 if (!l3)
1754 continue;
1755
1756 spin_lock_irqsave(&l3->list_lock, flags);
1757 list_for_each_entry(slabp, &l3->slabs_full, list) {
1758 active_objs += cachep->num;
1759 active_slabs++;
1760 }
1761 list_for_each_entry(slabp, &l3->slabs_partial, list) {
1762 active_objs += slabp->inuse;
1763 active_slabs++;
1764 }
1765 list_for_each_entry(slabp, &l3->slabs_free, list)
1766 num_slabs++;
1767
1768 free_objects += l3->free_objects;
1769 spin_unlock_irqrestore(&l3->list_lock, flags);
1770
1771 num_slabs += active_slabs;
1772 num_objs = num_slabs * cachep->num;
1773 printk(KERN_WARNING
1774 " node %d: slabs: %ld/%ld, objs: %ld/%ld, free: %ld\n",
1775 node, active_slabs, num_slabs, active_objs, num_objs,
1776 free_objects);
1777 }
1778}
1779
1734/* 1780/*
1735 * Interface to system's page allocator. No need to hold the cache-lock. 1781 * Interface to system's page allocator. No need to hold the cache-lock.
1736 * 1782 *
@@ -1757,8 +1803,11 @@ static void *kmem_getpages(struct kmem_cache *cachep, gfp_t flags, int nodeid)
1757 flags |= __GFP_RECLAIMABLE; 1803 flags |= __GFP_RECLAIMABLE;
1758 1804
1759 page = alloc_pages_exact_node(nodeid, flags | __GFP_NOTRACK, cachep->gfporder); 1805 page = alloc_pages_exact_node(nodeid, flags | __GFP_NOTRACK, cachep->gfporder);
1760 if (!page) 1806 if (!page) {
1807 if (!(flags & __GFP_NOWARN) && printk_ratelimit())
1808 slab_out_of_memory(cachep, flags, nodeid);
1761 return NULL; 1809 return NULL;
1810 }
1762 1811
1763 nr_pages = (1 << cachep->gfporder); 1812 nr_pages = (1 << cachep->gfporder);
1764 if (cachep->flags & SLAB_RECLAIM_ACCOUNT) 1813 if (cachep->flags & SLAB_RECLAIM_ACCOUNT)
@@ -3696,13 +3745,12 @@ static inline void __cache_free(struct kmem_cache *cachep, void *objp,
3696 3745
3697 if (likely(ac->avail < ac->limit)) { 3746 if (likely(ac->avail < ac->limit)) {
3698 STATS_INC_FREEHIT(cachep); 3747 STATS_INC_FREEHIT(cachep);
3699 ac->entry[ac->avail++] = objp;
3700 return;
3701 } else { 3748 } else {
3702 STATS_INC_FREEMISS(cachep); 3749 STATS_INC_FREEMISS(cachep);
3703 cache_flusharray(cachep, ac); 3750 cache_flusharray(cachep, ac);
3704 ac->entry[ac->avail++] = objp;
3705 } 3751 }
3752
3753 ac->entry[ac->avail++] = objp;
3706} 3754}
3707 3755
3708/** 3756/**
diff --git a/mm/slub.c b/mm/slub.c
index f4a6229848fd..64d9966d16bc 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -29,6 +29,7 @@
29#include <linux/math64.h> 29#include <linux/math64.h>
30#include <linux/fault-inject.h> 30#include <linux/fault-inject.h>
31#include <linux/stacktrace.h> 31#include <linux/stacktrace.h>
32#include <linux/prefetch.h>
32 33
33#include <trace/events/kmem.h> 34#include <trace/events/kmem.h>
34 35
@@ -269,6 +270,11 @@ static inline void *get_freepointer(struct kmem_cache *s, void *object)
269 return *(void **)(object + s->offset); 270 return *(void **)(object + s->offset);
270} 271}
271 272
273static void prefetch_freepointer(const struct kmem_cache *s, void *object)
274{
275 prefetch(object + s->offset);
276}
277
272static inline void *get_freepointer_safe(struct kmem_cache *s, void *object) 278static inline void *get_freepointer_safe(struct kmem_cache *s, void *object)
273{ 279{
274 void *p; 280 void *p;
@@ -1560,6 +1566,7 @@ static void *get_partial_node(struct kmem_cache *s,
1560 } else { 1566 } else {
1561 page->freelist = t; 1567 page->freelist = t;
1562 available = put_cpu_partial(s, page, 0); 1568 available = put_cpu_partial(s, page, 0);
1569 stat(s, CPU_PARTIAL_NODE);
1563 } 1570 }
1564 if (kmem_cache_debug(s) || available > s->cpu_partial / 2) 1571 if (kmem_cache_debug(s) || available > s->cpu_partial / 2)
1565 break; 1572 break;
@@ -1983,6 +1990,7 @@ int put_cpu_partial(struct kmem_cache *s, struct page *page, int drain)
1983 local_irq_restore(flags); 1990 local_irq_restore(flags);
1984 pobjects = 0; 1991 pobjects = 0;
1985 pages = 0; 1992 pages = 0;
1993 stat(s, CPU_PARTIAL_DRAIN);
1986 } 1994 }
1987 } 1995 }
1988 1996
@@ -1994,7 +2002,6 @@ int put_cpu_partial(struct kmem_cache *s, struct page *page, int drain)
1994 page->next = oldpage; 2002 page->next = oldpage;
1995 2003
1996 } while (this_cpu_cmpxchg(s->cpu_slab->partial, oldpage, page) != oldpage); 2004 } while (this_cpu_cmpxchg(s->cpu_slab->partial, oldpage, page) != oldpage);
1997 stat(s, CPU_PARTIAL_FREE);
1998 return pobjects; 2005 return pobjects;
1999} 2006}
2000 2007
@@ -2319,6 +2326,8 @@ redo:
2319 object = __slab_alloc(s, gfpflags, node, addr, c); 2326 object = __slab_alloc(s, gfpflags, node, addr, c);
2320 2327
2321 else { 2328 else {
2329 void *next_object = get_freepointer_safe(s, object);
2330
2322 /* 2331 /*
2323 * The cmpxchg will only match if there was no additional 2332 * The cmpxchg will only match if there was no additional
2324 * operation and if we are on the right processor. 2333 * operation and if we are on the right processor.
@@ -2334,11 +2343,12 @@ redo:
2334 if (unlikely(!this_cpu_cmpxchg_double( 2343 if (unlikely(!this_cpu_cmpxchg_double(
2335 s->cpu_slab->freelist, s->cpu_slab->tid, 2344 s->cpu_slab->freelist, s->cpu_slab->tid,
2336 object, tid, 2345 object, tid,
2337 get_freepointer_safe(s, object), next_tid(tid)))) { 2346 next_object, next_tid(tid)))) {
2338 2347
2339 note_cmpxchg_failure("slab_alloc", s, tid); 2348 note_cmpxchg_failure("slab_alloc", s, tid);
2340 goto redo; 2349 goto redo;
2341 } 2350 }
2351 prefetch_freepointer(s, next_object);
2342 stat(s, ALLOC_FASTPATH); 2352 stat(s, ALLOC_FASTPATH);
2343 } 2353 }
2344 2354
@@ -2475,9 +2485,10 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
2475 * If we just froze the page then put it onto the 2485 * If we just froze the page then put it onto the
2476 * per cpu partial list. 2486 * per cpu partial list.
2477 */ 2487 */
2478 if (new.frozen && !was_frozen) 2488 if (new.frozen && !was_frozen) {
2479 put_cpu_partial(s, page, 1); 2489 put_cpu_partial(s, page, 1);
2480 2490 stat(s, CPU_PARTIAL_FREE);
2491 }
2481 /* 2492 /*
2482 * The list lock was not taken therefore no list 2493 * The list lock was not taken therefore no list
2483 * activity can be necessary. 2494 * activity can be necessary.
@@ -3939,13 +3950,14 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size,
3939 if (kmem_cache_open(s, n, 3950 if (kmem_cache_open(s, n,
3940 size, align, flags, ctor)) { 3951 size, align, flags, ctor)) {
3941 list_add(&s->list, &slab_caches); 3952 list_add(&s->list, &slab_caches);
3953 up_write(&slub_lock);
3942 if (sysfs_slab_add(s)) { 3954 if (sysfs_slab_add(s)) {
3955 down_write(&slub_lock);
3943 list_del(&s->list); 3956 list_del(&s->list);
3944 kfree(n); 3957 kfree(n);
3945 kfree(s); 3958 kfree(s);
3946 goto err; 3959 goto err;
3947 } 3960 }
3948 up_write(&slub_lock);
3949 return s; 3961 return s;
3950 } 3962 }
3951 kfree(n); 3963 kfree(n);
@@ -5069,6 +5081,8 @@ STAT_ATTR(CMPXCHG_DOUBLE_CPU_FAIL, cmpxchg_double_cpu_fail);
5069STAT_ATTR(CMPXCHG_DOUBLE_FAIL, cmpxchg_double_fail); 5081STAT_ATTR(CMPXCHG_DOUBLE_FAIL, cmpxchg_double_fail);
5070STAT_ATTR(CPU_PARTIAL_ALLOC, cpu_partial_alloc); 5082STAT_ATTR(CPU_PARTIAL_ALLOC, cpu_partial_alloc);
5071STAT_ATTR(CPU_PARTIAL_FREE, cpu_partial_free); 5083STAT_ATTR(CPU_PARTIAL_FREE, cpu_partial_free);
5084STAT_ATTR(CPU_PARTIAL_NODE, cpu_partial_node);
5085STAT_ATTR(CPU_PARTIAL_DRAIN, cpu_partial_drain);
5072#endif 5086#endif
5073 5087
5074static struct attribute *slab_attrs[] = { 5088static struct attribute *slab_attrs[] = {
@@ -5134,6 +5148,8 @@ static struct attribute *slab_attrs[] = {
5134 &cmpxchg_double_cpu_fail_attr.attr, 5148 &cmpxchg_double_cpu_fail_attr.attr,
5135 &cpu_partial_alloc_attr.attr, 5149 &cpu_partial_alloc_attr.attr,
5136 &cpu_partial_free_attr.attr, 5150 &cpu_partial_free_attr.attr,
5151 &cpu_partial_node_attr.attr,
5152 &cpu_partial_drain_attr.attr,
5137#endif 5153#endif
5138#ifdef CONFIG_FAILSLAB 5154#ifdef CONFIG_FAILSLAB
5139 &failslab_attr.attr, 5155 &failslab_attr.attr,