aboutsummaryrefslogtreecommitdiffstats
path: root/mm/slab.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/slab.c')
-rw-r--r--mm/slab.c30
1 files changed, 23 insertions, 7 deletions
diff --git a/mm/slab.c b/mm/slab.c
index f055c1420216..e6ef9bd52335 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -420,6 +420,7 @@ struct kmem_cache {
420 unsigned long max_freeable; 420 unsigned long max_freeable;
421 unsigned long node_allocs; 421 unsigned long node_allocs;
422 unsigned long node_frees; 422 unsigned long node_frees;
423 unsigned long node_overflow;
423 atomic_t allochit; 424 atomic_t allochit;
424 atomic_t allocmiss; 425 atomic_t allocmiss;
425 atomic_t freehit; 426 atomic_t freehit;
@@ -465,6 +466,7 @@ struct kmem_cache {
465#define STATS_INC_ERR(x) ((x)->errors++) 466#define STATS_INC_ERR(x) ((x)->errors++)
466#define STATS_INC_NODEALLOCS(x) ((x)->node_allocs++) 467#define STATS_INC_NODEALLOCS(x) ((x)->node_allocs++)
467#define STATS_INC_NODEFREES(x) ((x)->node_frees++) 468#define STATS_INC_NODEFREES(x) ((x)->node_frees++)
469#define STATS_INC_ACOVERFLOW(x) ((x)->node_overflow++)
468#define STATS_SET_FREEABLE(x, i) \ 470#define STATS_SET_FREEABLE(x, i) \
469 do { \ 471 do { \
470 if ((x)->max_freeable < i) \ 472 if ((x)->max_freeable < i) \
@@ -484,6 +486,7 @@ struct kmem_cache {
484#define STATS_INC_ERR(x) do { } while (0) 486#define STATS_INC_ERR(x) do { } while (0)
485#define STATS_INC_NODEALLOCS(x) do { } while (0) 487#define STATS_INC_NODEALLOCS(x) do { } while (0)
486#define STATS_INC_NODEFREES(x) do { } while (0) 488#define STATS_INC_NODEFREES(x) do { } while (0)
489#define STATS_INC_ACOVERFLOW(x) do { } while (0)
487#define STATS_SET_FREEABLE(x, i) do { } while (0) 490#define STATS_SET_FREEABLE(x, i) do { } while (0)
488#define STATS_INC_ALLOCHIT(x) do { } while (0) 491#define STATS_INC_ALLOCHIT(x) do { } while (0)
489#define STATS_INC_ALLOCMISS(x) do { } while (0) 492#define STATS_INC_ALLOCMISS(x) do { } while (0)
@@ -1453,7 +1456,14 @@ static void *kmem_getpages(struct kmem_cache *cachep, gfp_t flags, int nodeid)
1453 int i; 1456 int i;
1454 1457
1455 flags |= cachep->gfpflags; 1458 flags |= cachep->gfpflags;
1459#ifndef CONFIG_MMU
1460 /* nommu uses slab's for process anonymous memory allocations, so
1461 * requires __GFP_COMP to properly refcount higher order allocations"
1462 */
1463 page = alloc_pages_node(nodeid, (flags | __GFP_COMP), cachep->gfporder);
1464#else
1456 page = alloc_pages_node(nodeid, flags, cachep->gfporder); 1465 page = alloc_pages_node(nodeid, flags, cachep->gfporder);
1466#endif
1457 if (!page) 1467 if (!page)
1458 return NULL; 1468 return NULL;
1459 addr = page_address(page); 1469 addr = page_address(page);
@@ -2318,13 +2328,15 @@ EXPORT_SYMBOL(kmem_cache_destroy);
2318 2328
2319/* Get the memory for a slab management obj. */ 2329/* Get the memory for a slab management obj. */
2320static struct slab *alloc_slabmgmt(struct kmem_cache *cachep, void *objp, 2330static struct slab *alloc_slabmgmt(struct kmem_cache *cachep, void *objp,
2321 int colour_off, gfp_t local_flags) 2331 int colour_off, gfp_t local_flags,
2332 int nodeid)
2322{ 2333{
2323 struct slab *slabp; 2334 struct slab *slabp;
2324 2335
2325 if (OFF_SLAB(cachep)) { 2336 if (OFF_SLAB(cachep)) {
2326 /* Slab management obj is off-slab. */ 2337 /* Slab management obj is off-slab. */
2327 slabp = kmem_cache_alloc(cachep->slabp_cache, local_flags); 2338 slabp = kmem_cache_alloc_node(cachep->slabp_cache,
2339 local_flags, nodeid);
2328 if (!slabp) 2340 if (!slabp)
2329 return NULL; 2341 return NULL;
2330 } else { 2342 } else {
@@ -2334,6 +2346,7 @@ static struct slab *alloc_slabmgmt(struct kmem_cache *cachep, void *objp,
2334 slabp->inuse = 0; 2346 slabp->inuse = 0;
2335 slabp->colouroff = colour_off; 2347 slabp->colouroff = colour_off;
2336 slabp->s_mem = objp + colour_off; 2348 slabp->s_mem = objp + colour_off;
2349 slabp->nodeid = nodeid;
2337 return slabp; 2350 return slabp;
2338} 2351}
2339 2352
@@ -2519,7 +2532,7 @@ static int cache_grow(struct kmem_cache *cachep, gfp_t flags, int nodeid)
2519 goto failed; 2532 goto failed;
2520 2533
2521 /* Get slab management. */ 2534 /* Get slab management. */
2522 slabp = alloc_slabmgmt(cachep, objp, offset, local_flags); 2535 slabp = alloc_slabmgmt(cachep, objp, offset, local_flags, nodeid);
2523 if (!slabp) 2536 if (!slabp)
2524 goto opps1; 2537 goto opps1;
2525 2538
@@ -3080,9 +3093,11 @@ static inline void __cache_free(struct kmem_cache *cachep, void *objp)
3080 if (l3->alien && l3->alien[nodeid]) { 3093 if (l3->alien && l3->alien[nodeid]) {
3081 alien = l3->alien[nodeid]; 3094 alien = l3->alien[nodeid];
3082 spin_lock(&alien->lock); 3095 spin_lock(&alien->lock);
3083 if (unlikely(alien->avail == alien->limit)) 3096 if (unlikely(alien->avail == alien->limit)) {
3097 STATS_INC_ACOVERFLOW(cachep);
3084 __drain_alien_cache(cachep, 3098 __drain_alien_cache(cachep,
3085 alien, nodeid); 3099 alien, nodeid);
3100 }
3086 alien->entry[alien->avail++] = objp; 3101 alien->entry[alien->avail++] = objp;
3087 spin_unlock(&alien->lock); 3102 spin_unlock(&alien->lock);
3088 } else { 3103 } else {
@@ -3760,7 +3775,7 @@ static void print_slabinfo_header(struct seq_file *m)
3760 seq_puts(m, " : slabdata <active_slabs> <num_slabs> <sharedavail>"); 3775 seq_puts(m, " : slabdata <active_slabs> <num_slabs> <sharedavail>");
3761#if STATS 3776#if STATS
3762 seq_puts(m, " : globalstat <listallocs> <maxobjs> <grown> <reaped> " 3777 seq_puts(m, " : globalstat <listallocs> <maxobjs> <grown> <reaped> "
3763 "<error> <maxfreeable> <nodeallocs> <remotefrees>"); 3778 "<error> <maxfreeable> <nodeallocs> <remotefrees> <alienoverflow>");
3764 seq_puts(m, " : cpustat <allochit> <allocmiss> <freehit> <freemiss>"); 3779 seq_puts(m, " : cpustat <allochit> <allocmiss> <freehit> <freemiss>");
3765#endif 3780#endif
3766 seq_putc(m, '\n'); 3781 seq_putc(m, '\n');
@@ -3874,11 +3889,12 @@ static int s_show(struct seq_file *m, void *p)
3874 unsigned long max_freeable = cachep->max_freeable; 3889 unsigned long max_freeable = cachep->max_freeable;
3875 unsigned long node_allocs = cachep->node_allocs; 3890 unsigned long node_allocs = cachep->node_allocs;
3876 unsigned long node_frees = cachep->node_frees; 3891 unsigned long node_frees = cachep->node_frees;
3892 unsigned long overflows = cachep->node_overflow;
3877 3893
3878 seq_printf(m, " : globalstat %7lu %6lu %5lu %4lu \ 3894 seq_printf(m, " : globalstat %7lu %6lu %5lu %4lu \
3879 %4lu %4lu %4lu %4lu", allocs, high, grown, 3895 %4lu %4lu %4lu %4lu %4lu", allocs, high, grown,
3880 reaped, errors, max_freeable, node_allocs, 3896 reaped, errors, max_freeable, node_allocs,
3881 node_frees); 3897 node_frees, overflows);
3882 } 3898 }
3883 /* cpu stats */ 3899 /* cpu stats */
3884 { 3900 {