aboutsummaryrefslogtreecommitdiffstats
path: root/mm/slab.c
diff options
context:
space:
mode:
authorJoonsoo Kim <iamjoonsoo.kim@lge.com>2014-08-06 19:04:25 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-06 21:01:14 -0400
commit97654dfa20caa5e6c1b0a4af715aabaf5d070d69 (patch)
tree0b4b16ba910572e9068905cf12d587d888cc5ecb /mm/slab.c
parent25c063fbd5512eb7190bf5af88351109aededb3f (diff)
slab: defer slab_destroy in free_block()
In free_block(), if freeing object makes new free slab and number of free_objects exceeds free_limit, we start to destroy this new free slab with holding the kmem_cache node lock. Holding the lock is useless and, generally, holding a lock as least as possible is good thing. I never measure performance effect of this, but we'd be better not to hold the lock as much as possible. Commented by Christoph: This is also good because kmem_cache_free is no longer called while holding the node lock. So we avoid one case of recursion. Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com> Acked-by: Christoph Lameter <cl@linux.com> Cc: Pekka Enberg <penberg@kernel.org> Acked-by: David Rientjes <rientjes@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/slab.c')
-rw-r--r--mm/slab.c60
1 files changed, 41 insertions, 19 deletions
diff --git a/mm/slab.c b/mm/slab.c
index 205632c94a6a..f6ad8d335be7 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -242,7 +242,8 @@ static struct kmem_cache_node __initdata init_kmem_cache_node[NUM_INIT_LISTS];
242static int drain_freelist(struct kmem_cache *cache, 242static int drain_freelist(struct kmem_cache *cache,
243 struct kmem_cache_node *n, int tofree); 243 struct kmem_cache_node *n, int tofree);
244static void free_block(struct kmem_cache *cachep, void **objpp, int len, 244static void free_block(struct kmem_cache *cachep, void **objpp, int len,
245 int node); 245 int node, struct list_head *list);
246static void slabs_destroy(struct kmem_cache *cachep, struct list_head *list);
246static int enable_cpucache(struct kmem_cache *cachep, gfp_t gfp); 247static int enable_cpucache(struct kmem_cache *cachep, gfp_t gfp);
247static void cache_reap(struct work_struct *unused); 248static void cache_reap(struct work_struct *unused);
248 249
@@ -1030,6 +1031,7 @@ static void __drain_alien_cache(struct kmem_cache *cachep,
1030 struct array_cache *ac, int node) 1031 struct array_cache *ac, int node)
1031{ 1032{
1032 struct kmem_cache_node *n = get_node(cachep, node); 1033 struct kmem_cache_node *n = get_node(cachep, node);
1034 LIST_HEAD(list);
1033 1035
1034 if (ac->avail) { 1036 if (ac->avail) {
1035 spin_lock(&n->list_lock); 1037 spin_lock(&n->list_lock);
@@ -1041,9 +1043,10 @@ static void __drain_alien_cache(struct kmem_cache *cachep,
1041 if (n->shared) 1043 if (n->shared)
1042 transfer_objects(n->shared, ac, ac->limit); 1044 transfer_objects(n->shared, ac, ac->limit);
1043 1045
1044 free_block(cachep, ac->entry, ac->avail, node); 1046 free_block(cachep, ac->entry, ac->avail, node, &list);
1045 ac->avail = 0; 1047 ac->avail = 0;
1046 spin_unlock(&n->list_lock); 1048 spin_unlock(&n->list_lock);
1049 slabs_destroy(cachep, &list);
1047 } 1050 }
1048} 1051}
1049 1052
@@ -1087,6 +1090,7 @@ static inline int cache_free_alien(struct kmem_cache *cachep, void *objp)
1087 struct kmem_cache_node *n; 1090 struct kmem_cache_node *n;
1088 struct array_cache *alien = NULL; 1091 struct array_cache *alien = NULL;
1089 int node; 1092 int node;
1093 LIST_HEAD(list);
1090 1094
1091 node = numa_mem_id(); 1095 node = numa_mem_id();
1092 1096
@@ -1111,8 +1115,9 @@ static inline int cache_free_alien(struct kmem_cache *cachep, void *objp)
1111 } else { 1115 } else {
1112 n = get_node(cachep, nodeid); 1116 n = get_node(cachep, nodeid);
1113 spin_lock(&n->list_lock); 1117 spin_lock(&n->list_lock);
1114 free_block(cachep, &objp, 1, nodeid); 1118 free_block(cachep, &objp, 1, nodeid, &list);
1115 spin_unlock(&n->list_lock); 1119 spin_unlock(&n->list_lock);
1120 slabs_destroy(cachep, &list);
1116 } 1121 }
1117 return 1; 1122 return 1;
1118} 1123}
@@ -1182,6 +1187,7 @@ static void cpuup_canceled(long cpu)
1182 struct array_cache *nc; 1187 struct array_cache *nc;
1183 struct array_cache *shared; 1188 struct array_cache *shared;
1184 struct array_cache **alien; 1189 struct array_cache **alien;
1190 LIST_HEAD(list);
1185 1191
1186 /* cpu is dead; no one can alloc from it. */ 1192 /* cpu is dead; no one can alloc from it. */
1187 nc = cachep->array[cpu]; 1193 nc = cachep->array[cpu];
@@ -1196,7 +1202,7 @@ static void cpuup_canceled(long cpu)
1196 /* Free limit for this kmem_cache_node */ 1202 /* Free limit for this kmem_cache_node */
1197 n->free_limit -= cachep->batchcount; 1203 n->free_limit -= cachep->batchcount;
1198 if (nc) 1204 if (nc)
1199 free_block(cachep, nc->entry, nc->avail, node); 1205 free_block(cachep, nc->entry, nc->avail, node, &list);
1200 1206
1201 if (!cpumask_empty(mask)) { 1207 if (!cpumask_empty(mask)) {
1202 spin_unlock_irq(&n->list_lock); 1208 spin_unlock_irq(&n->list_lock);
@@ -1206,7 +1212,7 @@ static void cpuup_canceled(long cpu)
1206 shared = n->shared; 1212 shared = n->shared;
1207 if (shared) { 1213 if (shared) {
1208 free_block(cachep, shared->entry, 1214 free_block(cachep, shared->entry,
1209 shared->avail, node); 1215 shared->avail, node, &list);
1210 n->shared = NULL; 1216 n->shared = NULL;
1211 } 1217 }
1212 1218
@@ -1221,6 +1227,7 @@ static void cpuup_canceled(long cpu)
1221 free_alien_cache(alien); 1227 free_alien_cache(alien);
1222 } 1228 }
1223free_array_cache: 1229free_array_cache:
1230 slabs_destroy(cachep, &list);
1224 kfree(nc); 1231 kfree(nc);
1225 } 1232 }
1226 /* 1233 /*
@@ -2056,6 +2063,16 @@ static void slab_destroy(struct kmem_cache *cachep, struct page *page)
2056 kmem_cache_free(cachep->freelist_cache, freelist); 2063 kmem_cache_free(cachep->freelist_cache, freelist);
2057} 2064}
2058 2065
2066static void slabs_destroy(struct kmem_cache *cachep, struct list_head *list)
2067{
2068 struct page *page, *n;
2069
2070 list_for_each_entry_safe(page, n, list, lru) {
2071 list_del(&page->lru);
2072 slab_destroy(cachep, page);
2073 }
2074}
2075
2059/** 2076/**
2060 * calculate_slab_order - calculate size (page order) of slabs 2077 * calculate_slab_order - calculate size (page order) of slabs
2061 * @cachep: pointer to the cache that is being created 2078 * @cachep: pointer to the cache that is being created
@@ -2459,13 +2476,15 @@ static void do_drain(void *arg)
2459 struct array_cache *ac; 2476 struct array_cache *ac;
2460 int node = numa_mem_id(); 2477 int node = numa_mem_id();
2461 struct kmem_cache_node *n; 2478 struct kmem_cache_node *n;
2479 LIST_HEAD(list);
2462 2480
2463 check_irq_off(); 2481 check_irq_off();
2464 ac = cpu_cache_get(cachep); 2482 ac = cpu_cache_get(cachep);
2465 n = get_node(cachep, node); 2483 n = get_node(cachep, node);
2466 spin_lock(&n->list_lock); 2484 spin_lock(&n->list_lock);
2467 free_block(cachep, ac->entry, ac->avail, node); 2485 free_block(cachep, ac->entry, ac->avail, node, &list);
2468 spin_unlock(&n->list_lock); 2486 spin_unlock(&n->list_lock);
2487 slabs_destroy(cachep, &list);
2469 ac->avail = 0; 2488 ac->avail = 0;
2470} 2489}
2471 2490
@@ -3393,9 +3412,10 @@ slab_alloc(struct kmem_cache *cachep, gfp_t flags, unsigned long caller)
3393 3412
3394/* 3413/*
3395 * Caller needs to acquire correct kmem_cache_node's list_lock 3414 * Caller needs to acquire correct kmem_cache_node's list_lock
3415 * @list: List of detached free slabs should be freed by caller
3396 */ 3416 */
3397static void free_block(struct kmem_cache *cachep, void **objpp, int nr_objects, 3417static void free_block(struct kmem_cache *cachep, void **objpp,
3398 int node) 3418 int nr_objects, int node, struct list_head *list)
3399{ 3419{
3400 int i; 3420 int i;
3401 struct kmem_cache_node *n = get_node(cachep, node); 3421 struct kmem_cache_node *n = get_node(cachep, node);
@@ -3418,13 +3438,7 @@ static void free_block(struct kmem_cache *cachep, void **objpp, int nr_objects,
3418 if (page->active == 0) { 3438 if (page->active == 0) {
3419 if (n->free_objects > n->free_limit) { 3439 if (n->free_objects > n->free_limit) {
3420 n->free_objects -= cachep->num; 3440 n->free_objects -= cachep->num;
3421 /* No need to drop any previously held 3441 list_add_tail(&page->lru, list);
3422 * lock here, even if we have a off-slab slab
3423 * descriptor it is guaranteed to come from
3424 * a different cache, refer to comments before
3425 * alloc_slabmgmt.
3426 */
3427 slab_destroy(cachep, page);
3428 } else { 3442 } else {
3429 list_add(&page->lru, &n->slabs_free); 3443 list_add(&page->lru, &n->slabs_free);
3430 } 3444 }
@@ -3443,6 +3457,7 @@ static void cache_flusharray(struct kmem_cache *cachep, struct array_cache *ac)
3443 int batchcount; 3457 int batchcount;
3444 struct kmem_cache_node *n; 3458 struct kmem_cache_node *n;
3445 int node = numa_mem_id(); 3459 int node = numa_mem_id();
3460 LIST_HEAD(list);
3446 3461
3447 batchcount = ac->batchcount; 3462 batchcount = ac->batchcount;
3448#if DEBUG 3463#if DEBUG
@@ -3464,7 +3479,7 @@ static void cache_flusharray(struct kmem_cache *cachep, struct array_cache *ac)
3464 } 3479 }
3465 } 3480 }
3466 3481
3467 free_block(cachep, ac->entry, batchcount, node); 3482 free_block(cachep, ac->entry, batchcount, node, &list);
3468free_done: 3483free_done:
3469#if STATS 3484#if STATS
3470 { 3485 {
@@ -3485,6 +3500,7 @@ free_done:
3485 } 3500 }
3486#endif 3501#endif
3487 spin_unlock(&n->list_lock); 3502 spin_unlock(&n->list_lock);
3503 slabs_destroy(cachep, &list);
3488 ac->avail -= batchcount; 3504 ac->avail -= batchcount;
3489 memmove(ac->entry, &(ac->entry[batchcount]), sizeof(void *)*ac->avail); 3505 memmove(ac->entry, &(ac->entry[batchcount]), sizeof(void *)*ac->avail);
3490} 3506}
@@ -3765,12 +3781,13 @@ static int alloc_kmem_cache_node(struct kmem_cache *cachep, gfp_t gfp)
3765 n = get_node(cachep, node); 3781 n = get_node(cachep, node);
3766 if (n) { 3782 if (n) {
3767 struct array_cache *shared = n->shared; 3783 struct array_cache *shared = n->shared;
3784 LIST_HEAD(list);
3768 3785
3769 spin_lock_irq(&n->list_lock); 3786 spin_lock_irq(&n->list_lock);
3770 3787
3771 if (shared) 3788 if (shared)
3772 free_block(cachep, shared->entry, 3789 free_block(cachep, shared->entry,
3773 shared->avail, node); 3790 shared->avail, node, &list);
3774 3791
3775 n->shared = new_shared; 3792 n->shared = new_shared;
3776 if (!n->alien) { 3793 if (!n->alien) {
@@ -3780,6 +3797,7 @@ static int alloc_kmem_cache_node(struct kmem_cache *cachep, gfp_t gfp)
3780 n->free_limit = (1 + nr_cpus_node(node)) * 3797 n->free_limit = (1 + nr_cpus_node(node)) *
3781 cachep->batchcount + cachep->num; 3798 cachep->batchcount + cachep->num;
3782 spin_unlock_irq(&n->list_lock); 3799 spin_unlock_irq(&n->list_lock);
3800 slabs_destroy(cachep, &list);
3783 kfree(shared); 3801 kfree(shared);
3784 free_alien_cache(new_alien); 3802 free_alien_cache(new_alien);
3785 continue; 3803 continue;
@@ -3869,6 +3887,7 @@ static int __do_tune_cpucache(struct kmem_cache *cachep, int limit,
3869 cachep->shared = shared; 3887 cachep->shared = shared;
3870 3888
3871 for_each_online_cpu(i) { 3889 for_each_online_cpu(i) {
3890 LIST_HEAD(list);
3872 struct array_cache *ccold = new->new[i]; 3891 struct array_cache *ccold = new->new[i];
3873 int node; 3892 int node;
3874 struct kmem_cache_node *n; 3893 struct kmem_cache_node *n;
@@ -3879,8 +3898,9 @@ static int __do_tune_cpucache(struct kmem_cache *cachep, int limit,
3879 node = cpu_to_mem(i); 3898 node = cpu_to_mem(i);
3880 n = get_node(cachep, node); 3899 n = get_node(cachep, node);
3881 spin_lock_irq(&n->list_lock); 3900 spin_lock_irq(&n->list_lock);
3882 free_block(cachep, ccold->entry, ccold->avail, node); 3901 free_block(cachep, ccold->entry, ccold->avail, node, &list);
3883 spin_unlock_irq(&n->list_lock); 3902 spin_unlock_irq(&n->list_lock);
3903 slabs_destroy(cachep, &list);
3884 kfree(ccold); 3904 kfree(ccold);
3885 } 3905 }
3886 kfree(new); 3906 kfree(new);
@@ -3988,6 +4008,7 @@ skip_setup:
3988static void drain_array(struct kmem_cache *cachep, struct kmem_cache_node *n, 4008static void drain_array(struct kmem_cache *cachep, struct kmem_cache_node *n,
3989 struct array_cache *ac, int force, int node) 4009 struct array_cache *ac, int force, int node)
3990{ 4010{
4011 LIST_HEAD(list);
3991 int tofree; 4012 int tofree;
3992 4013
3993 if (!ac || !ac->avail) 4014 if (!ac || !ac->avail)
@@ -4000,12 +4021,13 @@ static void drain_array(struct kmem_cache *cachep, struct kmem_cache_node *n,
4000 tofree = force ? ac->avail : (ac->limit + 4) / 5; 4021 tofree = force ? ac->avail : (ac->limit + 4) / 5;
4001 if (tofree > ac->avail) 4022 if (tofree > ac->avail)
4002 tofree = (ac->avail + 1) / 2; 4023 tofree = (ac->avail + 1) / 2;
4003 free_block(cachep, ac->entry, tofree, node); 4024 free_block(cachep, ac->entry, tofree, node, &list);
4004 ac->avail -= tofree; 4025 ac->avail -= tofree;
4005 memmove(ac->entry, &(ac->entry[tofree]), 4026 memmove(ac->entry, &(ac->entry[tofree]),
4006 sizeof(void *) * ac->avail); 4027 sizeof(void *) * ac->avail);
4007 } 4028 }
4008 spin_unlock_irq(&n->list_lock); 4029 spin_unlock_irq(&n->list_lock);
4030 slabs_destroy(cachep, &list);
4009 } 4031 }
4010} 4032}
4011 4033