diff options
author | Christoph Lameter <cl@linux.com> | 2012-05-09 11:09:53 -0400 |
---|---|---|
committer | Pekka Enberg <penberg@kernel.org> | 2012-06-01 02:25:40 -0400 |
commit | 7ced3719719669ad6bd279b45fa3c1a517b2e057 (patch) | |
tree | b50ad0437b1bff8e772a53f0ffdb7392f501ea39 /mm/slub.c | |
parent | 507effeaba29bf724dfe38317fbd11d0fe25fa40 (diff) |
slub: Acquire_slab() avoid loop
Avoid the loop in acquire slab and simply fail if there is a conflict.
This will cause the next page on the list to be considered.
Acked-by: David Rientjes <rientjes@google.com>
Signed-off-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
Diffstat (limited to 'mm/slub.c')
-rw-r--r-- | mm/slub.c | 28 |
1 files changed, 15 insertions, 13 deletions
@@ -1490,12 +1490,12 @@ static inline void remove_partial(struct kmem_cache_node *n, | |||
1490 | } | 1490 | } |
1491 | 1491 | ||
1492 | /* | 1492 | /* |
1493 | * Lock slab, remove from the partial list and put the object into the | 1493 | * Remove slab from the partial list, freeze it and |
1494 | * per cpu freelist. | 1494 | * return the pointer to the freelist. |
1495 | * | 1495 | * |
1496 | * Returns a list of objects or NULL if it fails. | 1496 | * Returns a list of objects or NULL if it fails. |
1497 | * | 1497 | * |
1498 | * Must hold list_lock. | 1498 | * Must hold list_lock since we modify the partial list. |
1499 | */ | 1499 | */ |
1500 | static inline void *acquire_slab(struct kmem_cache *s, | 1500 | static inline void *acquire_slab(struct kmem_cache *s, |
1501 | struct kmem_cache_node *n, struct page *page, | 1501 | struct kmem_cache_node *n, struct page *page, |
@@ -1510,22 +1510,24 @@ static inline void *acquire_slab(struct kmem_cache *s, | |||
1510 | * The old freelist is the list of objects for the | 1510 | * The old freelist is the list of objects for the |
1511 | * per cpu allocation list. | 1511 | * per cpu allocation list. |
1512 | */ | 1512 | */ |
1513 | do { | 1513 | freelist = page->freelist; |
1514 | freelist = page->freelist; | 1514 | counters = page->counters; |
1515 | counters = page->counters; | 1515 | new.counters = counters; |
1516 | new.counters = counters; | 1516 | if (mode) |
1517 | if (mode) | 1517 | new.inuse = page->objects; |
1518 | new.inuse = page->objects; | ||
1519 | 1518 | ||
1520 | VM_BUG_ON(new.frozen); | 1519 | VM_BUG_ON(new.frozen); |
1521 | new.frozen = 1; | 1520 | new.frozen = 1; |
1522 | 1521 | ||
1523 | } while (!__cmpxchg_double_slab(s, page, | 1522 | if (!__cmpxchg_double_slab(s, page, |
1524 | freelist, counters, | 1523 | freelist, counters, |
1525 | NULL, new.counters, | 1524 | NULL, new.counters, |
1526 | "lock and freeze")); | 1525 | "acquire_slab")) |
1526 | |||
1527 | return NULL; | ||
1527 | 1528 | ||
1528 | remove_partial(n, page); | 1529 | remove_partial(n, page); |
1530 | WARN_ON(!freelist); | ||
1529 | return freelist; | 1531 | return freelist; |
1530 | } | 1532 | } |
1531 | 1533 | ||