diff options
author | Mel Gorman <mgorman@suse.de> | 2014-04-03 17:47:24 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-03 19:20:58 -0400 |
commit | d26914d11751b23ca2e8747725f2cae10c2f2c1b (patch) | |
tree | 020b606fb9223e29292f54922a11111239e3a3f4 /mm/slub.c | |
parent | 91ca9186484809c57303b33778d841cc28f696ed (diff) |
mm: optimize put_mems_allowed() usage
Since put_mems_allowed() is strictly optional, its a seqcount retry, we
don't need to evaluate the function if the allocation was in fact
successful, saving a smp_rmb some loads and comparisons on some relative
fast-paths.
Since the naming, get/put_mems_allowed() does suggest a mandatory
pairing, rename the interface, as suggested by Mel, to resemble the
seqcount interface.
This gives us: read_mems_allowed_begin() and read_mems_allowed_retry(),
where it is important to note that the return value of the latter call
is inverted from its previous incarnation.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Mel Gorman <mgorman@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/slub.c')
-rw-r--r-- | mm/slub.c | 16 |
1 files changed, 7 insertions, 9 deletions
@@ -1684,7 +1684,7 @@ static void *get_any_partial(struct kmem_cache *s, gfp_t flags, | |||
1684 | return NULL; | 1684 | return NULL; |
1685 | 1685 | ||
1686 | do { | 1686 | do { |
1687 | cpuset_mems_cookie = get_mems_allowed(); | 1687 | cpuset_mems_cookie = read_mems_allowed_begin(); |
1688 | zonelist = node_zonelist(slab_node(), flags); | 1688 | zonelist = node_zonelist(slab_node(), flags); |
1689 | for_each_zone_zonelist(zone, z, zonelist, high_zoneidx) { | 1689 | for_each_zone_zonelist(zone, z, zonelist, high_zoneidx) { |
1690 | struct kmem_cache_node *n; | 1690 | struct kmem_cache_node *n; |
@@ -1696,19 +1696,17 @@ static void *get_any_partial(struct kmem_cache *s, gfp_t flags, | |||
1696 | object = get_partial_node(s, n, c, flags); | 1696 | object = get_partial_node(s, n, c, flags); |
1697 | if (object) { | 1697 | if (object) { |
1698 | /* | 1698 | /* |
1699 | * Return the object even if | 1699 | * Don't check read_mems_allowed_retry() |
1700 | * put_mems_allowed indicated that | 1700 | * here - if mems_allowed was updated in |
1701 | * the cpuset mems_allowed was | 1701 | * parallel, that was a harmless race |
1702 | * updated in parallel. It's a | 1702 | * between allocation and the cpuset |
1703 | * harmless race between the alloc | 1703 | * update |
1704 | * and the cpuset update. | ||
1705 | */ | 1704 | */ |
1706 | put_mems_allowed(cpuset_mems_cookie); | ||
1707 | return object; | 1705 | return object; |
1708 | } | 1706 | } |
1709 | } | 1707 | } |
1710 | } | 1708 | } |
1711 | } while (!put_mems_allowed(cpuset_mems_cookie)); | 1709 | } while (read_mems_allowed_retry(cpuset_mems_cookie)); |
1712 | #endif | 1710 | #endif |
1713 | return NULL; | 1711 | return NULL; |
1714 | } | 1712 | } |