Add parameter to add_partial to avoid having two functions

Add a parameter to add_partial instead of having separate functions. The
parameter allows a more detailed control of where the slab pages is placed in
the partial queues.

If we put slabs back to the front then they are likely immediately used for
allocations. If they are put at the end then we can maximize the time that
the partial slabs spent without being subject to allocations.

When deactivating slab we can put the slabs that had remote objects freed (we
can see that because objects were put on the freelist that requires locks) to
them at the end of the list so that the cachelines of remote processors can
cool down. Slabs that had objects from the local cpu freed to them (objects
exist in the lockless freelist) are put in the front of the list to be reused
ASAP in order to exploit the cache hot state of the local cpu.

Patch seems to slightly improve tbench speed (1-2%).

Signed-off-by: Christoph Lameter <clameter@sgi.com>
Reviewed-by: Pekka Enberg <penberg@cs.helsinki.fi>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

+15 -16
+15 -16
mm/slub.c
··· 1198 /* 1199 * Management of partially allocated slabs 1200 */ 1201 - static void add_partial_tail(struct kmem_cache_node *n, struct page *page) 1202 { 1203 spin_lock(&n->list_lock); 1204 n->nr_partial++; 1205 - list_add_tail(&page->lru, &n->partial); 1206 - spin_unlock(&n->list_lock); 1207 - } 1208 - 1209 - static void add_partial(struct kmem_cache_node *n, struct page *page) 1210 - { 1211 - spin_lock(&n->list_lock); 1212 - n->nr_partial++; 1213 - list_add(&page->lru, &n->partial); 1214 spin_unlock(&n->list_lock); 1215 } 1216 ··· 1335 * 1336 * On exit the slab lock will have been dropped. 1337 */ 1338 - static void unfreeze_slab(struct kmem_cache *s, struct page *page) 1339 { 1340 struct kmem_cache_node *n = get_node(s, page_to_nid(page)); 1341 ··· 1343 if (page->inuse) { 1344 1345 if (page->freelist) 1346 - add_partial(n, page); 1347 else if (SlabDebug(page) && (s->flags & SLAB_STORE_USER)) 1348 add_full(n, page); 1349 slab_unlock(page); ··· 1358 * partial list stays small. kmem_cache_shrink can 1359 * reclaim empty slabs from the partial list. 1360 */ 1361 - add_partial_tail(n, page); 1362 slab_unlock(page); 1363 } else { 1364 slab_unlock(page); ··· 1373 static void deactivate_slab(struct kmem_cache *s, struct kmem_cache_cpu *c) 1374 { 1375 struct page *page = c->page; 1376 /* 1377 * Merge cpu freelist into freelist. Typically we get here 1378 * because both freelists are empty. So this is unlikely ··· 1381 */ 1382 while (unlikely(c->freelist)) { 1383 void **object; 1384 1385 /* Retrieve object from cpu_freelist */ 1386 object = c->freelist; ··· 1394 page->inuse--; 1395 } 1396 c->page = NULL; 1397 - unfreeze_slab(s, page); 1398 } 1399 1400 static inline void flush_slab(struct kmem_cache *s, struct kmem_cache_cpu *c) ··· 1616 * then add it. 1617 */ 1618 if (unlikely(!prior)) 1619 - add_partial_tail(get_node(s, page_to_nid(page)), page); 1620 1621 out_unlock: 1622 slab_unlock(page); ··· 2024 #endif 2025 init_kmem_cache_node(n); 2026 atomic_long_inc(&n->nr_slabs); 2027 - add_partial(n, page); 2028 return n; 2029 } 2030
··· 1198 /* 1199 * Management of partially allocated slabs 1200 */ 1201 + static void add_partial(struct kmem_cache_node *n, 1202 + struct page *page, int tail) 1203 { 1204 spin_lock(&n->list_lock); 1205 n->nr_partial++; 1206 + if (tail) 1207 + list_add_tail(&page->lru, &n->partial); 1208 + else 1209 + list_add(&page->lru, &n->partial); 1210 spin_unlock(&n->list_lock); 1211 } 1212 ··· 1339 * 1340 * On exit the slab lock will have been dropped. 1341 */ 1342 + static void unfreeze_slab(struct kmem_cache *s, struct page *page, int tail) 1343 { 1344 struct kmem_cache_node *n = get_node(s, page_to_nid(page)); 1345 ··· 1347 if (page->inuse) { 1348 1349 if (page->freelist) 1350 + add_partial(n, page, tail); 1351 else if (SlabDebug(page) && (s->flags & SLAB_STORE_USER)) 1352 add_full(n, page); 1353 slab_unlock(page); ··· 1362 * partial list stays small. kmem_cache_shrink can 1363 * reclaim empty slabs from the partial list. 1364 */ 1365 + add_partial(n, page, 1); 1366 slab_unlock(page); 1367 } else { 1368 slab_unlock(page); ··· 1377 static void deactivate_slab(struct kmem_cache *s, struct kmem_cache_cpu *c) 1378 { 1379 struct page *page = c->page; 1380 + int tail = 1; 1381 /* 1382 * Merge cpu freelist into freelist. Typically we get here 1383 * because both freelists are empty. So this is unlikely ··· 1384 */ 1385 while (unlikely(c->freelist)) { 1386 void **object; 1387 + 1388 + tail = 0; /* Hot objects. Put the slab first */ 1389 1390 /* Retrieve object from cpu_freelist */ 1391 object = c->freelist; ··· 1395 page->inuse--; 1396 } 1397 c->page = NULL; 1398 + unfreeze_slab(s, page, tail); 1399 } 1400 1401 static inline void flush_slab(struct kmem_cache *s, struct kmem_cache_cpu *c) ··· 1617 * then add it. 1618 */ 1619 if (unlikely(!prior)) 1620 + add_partial(get_node(s, page_to_nid(page)), page, 1); 1621 1622 out_unlock: 1623 slab_unlock(page); ··· 2025 #endif 2026 init_kmem_cache_node(n); 2027 atomic_long_inc(&n->nr_slabs); 2028 + add_partial(n, page, 0); 2029 return n; 2030 } 2031